Как я могу найти таблицу после текстовой строки, используя BeautifulSoup в Python? - PullRequest
4 голосов
/ 19 апреля 2011

Я пытаюсь извлечь данные из нескольких веб-страниц, которые не одинаковы в том, как они отображают свои таблицы.Мне нужно написать код, который будет искать текстовую строку, а затем перейти к таблице сразу после этой конкретной текстовой строки.Затем я хочу извлечь содержимое этой таблицы.Вот что у меня получилось:

from BeautifulSoup import BeautifulSoup, SoupStrainer
import re

html = ['<html><body><p align="center"><b><font size="2">Table 1</font></b><table><tr><td>1. row 1, cell 1</td><td>1. row 1, cell 2</td></tr><tr><td>1. row 2, cell 1</td><td>1. row 2, cell 2</td></tr></table><p align="center"><b><font size="2">Table 2</font></b><table><tr><td>2. row 1, cell 1</td><td>2. row 1, cell 2</td></tr><tr><td>2. row 2, cell 1</td><td>2. row 2, cell 2</td></tr></table></html>']
soup = BeautifulSoup(''.join(html))
searchtext = re.compile('Table 1',re.IGNORECASE) # Also need to figure out how to ignore space
foundtext = soup.findAll('p',text=searchtext)
soupafter = foundtext.findAllNext()
table = soupafter.find('table') # find the next table after the search string is found
rows = table.findAll('tr')
for tr in rows:
    cols = tr.findAll('td')
    for td in cols:
        try:
            text = ''.join(td.find(text=True))
        except Exception:
            text = ""
        print text+"|",
print

Однако я получаю следующую ошибку:

    soupafter = foundtext.findAllNext()
AttributeError: 'ResultSet' object has no attribute 'findAllNext'

Есть ли простой способ сделать это с помощью BeautifulSoup?

1 Ответ

8 голосов
/ 19 апреля 2011

Ошибка связана с тем, что findAllNext является методом Tag объектов, но foundtext является ResultSet объектом, который представляет собой список соответствующих тегов или строк.Вы можете перебирать каждый из тегов в foundtext, но в зависимости от ваших потребностей может быть достаточно использовать find, который возвращает только первый соответствующий тег.

Вотмодифицированная версия вашего кода.После изменения foundtext на использование soup.find я нашел и исправил ту же проблему с table.Я изменил ваше регулярное выражение на игнорировать пробел между словами :

from BeautifulSoup import BeautifulSoup, SoupStrainer
import re

html = ['<html><body><p align="center"><b><font size="2">Table 1</font></b><table><tr><td>1. row 1, cell 1</td><td>1. row 1, cell 2</td></tr><tr><td>1. row 2, cell 1</td><td>1. row 2, cell 2</td></tr></table><p align="center"><b><font size="2">Table 2</font></b><table><tr><td>2. row 1, cell 1</td><td>2. row 1, cell 2</td></tr><tr><td>2. row 2, cell 1</td><td>2. row 2, cell 2</td></tr></table></html>']
soup = BeautifulSoup(''.join(html))
searchtext = re.compile(r'Table\s+1',re.IGNORECASE)
foundtext = soup.find('p',text=searchtext) # Find the first <p> tag with the search text
table = foundtext.findNext('table') # Find the first <table> tag that follows it
rows = table.findAll('tr')
for tr in rows:
    cols = tr.findAll('td')
    for td in cols:
        try:
            text = ''.join(td.find(text=True))
        except Exception:
            text = ""
        print text+"|",
    print 

Это выводит:

1. row 1, cell 1| 1. row 1, cell 2|
1. row 2, cell 1| 1. row 2, cell 2|
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...