#html #python-3.x #beautifulsoup
#HTML #python-3.x #beautifulsoup
Вопрос:
Учитывая html, подобный этому:
page_html = '''
<html>
<head>
<title>Title</title>
</head>
<body>
<div id="div1">
<h1>h1 text</h1>
<div id="div div1">text div div1
</div>
<p>text in p</p>
<table id="tab1" border="1">
<tr id="tab1 tr1" class="class1">
<td><a href="/info/tab1/tr1/td1">tab1 tr1 td 1</a></td>
<td><a href="/info/tab1/tr1/td2">tab1 tr1 td 2</a></td>
<td><a href="/info/tab1/tr1/td3">tab1 tr1 td 3</a></td>
</tr>
<tr id="tab1 tr2" class="class1">
<td><a href="/info/tab1/tr2/td1">tab1 tr2 td 1</a></td>
<td><a href="/info/tab1/tr2/td2">tab1 tr2 td 2</a></td>
</tr>
<tr id="tab1 tr3" class="class2">
<td><a href="/info/tab1/tr3/td1">tab1 tr3 td 1</a></td>
<td><a href="/info/tab1/tr3/td2">tab1 tr3 td 2</a></td>
</tr>
</table>
<table id="tab2" border="1">
<tr id="tab2 tr1" class="class2">
<td><a href="/info/tab2/tr1/td1">tab2 tr1 td 1</a></td>
<td><a href="/info/tab2/tr1/td2">tab2 tr1 td 2</a></td>
<td><a href="/info/tab2/tr1/td3">tab2 tr1 td 3</a></td>
</tr>
<tr id="tab2 tr2" class="class2">
<td><a href="/info/tab2/tr2/td1">tab2 tr2 td 1</a></td>
<td><a href="/info/tab2/tr2/td2">tab2 tr2 td 2</a></td>
</tr>
<tr id="tab2 tr3" class="class3">
<td><a href="/info/tab2/tr3/td1">tab2 tr3 td 1</a></td>
<td><a href="/info/tab2/tr3/td2">tab2 tr3 td 2</a></td>
</tr>
</table>
</div>
</body>
</html>
'''
Я хотел бы получить текст из td в таблице с, id=tab2
где tr имеют атрибут class=class2
, соответствующий:
<tr id="tab2 tr1" class="class2">
<td><a href="/info/tab2/tr1/td1">tab2 tr1 td 1</a></td>
<td><a href="/info/tab2/tr1/td2">tab2 tr1 td 2</a></td>
<td><a href="/info/tab2/tr1/td3">tab2 tr1 td 3</a></td>
</tr>
<tr id="tab2 tr2" class="class2">
<td><a href="/info/tab2/tr2/td1">tab2 tr2 td 1</a></td>
<td><a href="/info/tab2/tr2/td2">tab2 tr2 td 2</a></td>
</tr>
Мое частичное решение таково:
from bs4 import BeautifulSoup
bsobj = BeautifulSoup(page_html)
res = bsobj.find('table', id='tab2').findAll('tr', {'class':'class2'})
но я не могу извлечь текст.
Попытка понимания списка:
[td.text for td in res]
получает общий (правильный) результат, но в виде списка двух tr и с аномальным n
значением, то есть:
[‘ntab2 tr1 td 1ntab2 tr1 td 2ntab2 tr1 td 3 n’, ‘ntab2 tr2 td 1ntab2 tr2 td 2n’]
Есть ли более чистый способ получить текст для каждого td, удовлетворяющий моим условиям для table и tr?
Ответ №1:
Объекты результирующего набора могут обрабатываться как список и использоваться непосредственно для понимания списка. Вы можете использовать понимание вложенного списка, чтобы сначала получить все tr
, а затем все td
из каждого из tr
без сохранения промежуточных результатов.
from bs4 import BeautifulSoup
bsobj = BeautifulSoup(page_html,'html.parser')
res = [td.text for tr in bsobj.find('table', id='tab2').findAll('tr', {'class':'class2'}) for td in tr.findAll('td')]
print(res)
Вывод
['tab2 tr1 td 1', 'tab2 tr1 td 2', 'tab2 tr1 td 3', 'tab2 tr2 td 1', 'tab2 tr2 td 2']
Ответ №2:
Лучший и более чистый способ доступа к таблице — использовать ванильный JavaScript.
Прежде всего, вам лучше добавить id
в свой <table id="myTable">
элемент, чтобы избежать конфликтов.
Вот способ прочитать все <td>
из элемента таблицы с помощью <tr>
—
let table = document.getElementById('myTable');
let trs = Array.from(table.getElementsByTagName('tr'));
trs.forEach(tr => {
let tds = Array.from(table.getElementsByTagName('td'));
tds.forEach(td => {
console.log(td.innerHTML);
})
})
Жить в действии — https://jsitor.com/A3cx88q5h
Комментарии:
1. Возможно, я не совсем понял язык. Мне интересны решения на python 3. В любом случае, спасибо.