Если у вас когда-либо есть вложенные таблицы (как на веб-сайтах старой школы), описанный выше подход может дать сбой.
В качестве решения вы можете сначала извлечь не вложенные таблицы:
html = '''<table>
<tr>
<td>Top level table cell</td>
<td>
<table>
<tr><td>Nested table cell</td></tr>
<tr><td>...another nested cell</td></tr>
</table>
</td>
</tr>
</table>'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
non_nested_tables = [t for t in soup.find_all('table') if not t.find_all('table')]
В качестве альтернативы, если вы хотите извлечь содержимое всех таблиц, включая те, которые вложены в другие таблицы, вы можете извлечь только заголовки tr
и th
верхнего уровня *. Для этого вам необходимо отключить рекурсию при вызове метода find_all
:
soup = BeautifulSoup(html, 'lxml')
tables = soup.find_all('table')
cnt = 0
for my_table in tables:
cnt += 1
print ('=============== TABLE {} ==============='.format(cnt))
rows = my_table.find_all('tr', recursive=False) # <-- HERE
for row in rows:
cells = row.find_all(['th', 'td'], recursive=False) # <-- HERE
for cell in cells:
# DO SOMETHING
if cell.string: print (cell.string)
Выход:
=============== TABLE 1 ===============
Top level table cell
=============== TABLE 2 ===============
Nested table cell
...another nested cell