Как вы получаете все строки из определенной таблицы, используя BeautifulSoup? - PullRequest
18 голосов
/ 06 января 2010

Я изучаю Python и BeautifulSoup, чтобы очистить данные из Интернета и прочитать таблицу HTML. Я могу прочитать это в Open Office, и там написано, что это Таблица № 11.

Кажется, что BeautifulSoup является предпочтительным выбором, но кто-нибудь может сказать мне, как получить конкретную таблицу и все строки? Я посмотрел документацию к модулю, но не могу разобраться с этим. Многие из примеров, которые я нашел в Интернете, похоже, делают больше, чем мне нужно.

Ответы [ 2 ]

35 голосов
/ 06 января 2010

Это должно быть довольно просто, если у вас есть кусок HTML для анализа с BeautifulSoup. Общая идея состоит в том, чтобы перейти к вашей таблице с помощью метода findChildren, после чего вы можете получить текстовое значение внутри ячейки с помощью свойства string.

>>> from BeautifulSoup import BeautifulSoup
>>> 
>>> html = """
... <html>
... <body>
...     <table>
...         <th><td>column 1</td><td>column 2</td></th>
...         <tr><td>value 1</td><td>value 2</td></tr>
...     </table>
... </body>
... </html>
... """
>>>
>>> soup = BeautifulSoup(html)
>>> tables = soup.findChildren('table')
>>>
>>> # This will get the first (and only) table. Your page may have more.
>>> my_table = tables[0]
>>>
>>> # You can find children with multiple tags by passing a list of strings
>>> rows = my_table.findChildren(['th', 'tr'])
>>>
>>> for row in rows:
...     cells = row.findChildren('td')
...     for cell in cells:
...         value = cell.string
...         print "The value in this cell is %s" % value
... 
The value in this cell is column 1
The value in this cell is column 2
The value in this cell is value 1
The value in this cell is value 2
>>> 
2 голосов
/ 05 января 2019

Если у вас когда-либо есть вложенные таблицы (как на веб-сайтах старой школы), описанный выше подход может дать сбой.

В качестве решения вы можете сначала извлечь не вложенные таблицы:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...