Извлечение текста из таблицы с помощью python и lxml - PullRequest
3 голосов
/ 15 декабря 2011

Недавно я увидел, что другой пользователь задал вопрос об извлечении информации из веб-таблицы Извлечение информации с веб-страницы с python . Ответ от ekhumoro прекрасно работает на странице, которую попросил другой пользователь. Увидеть ниже.

from urllib2 import urlopen
from lxml import etree

url = 'http://www.uscho.com/standings/division-i-men/2011-2012/'

tree = etree.HTML(urlopen(url).read())

for section in tree.xpath('//section[starts-with(@id, "section_")]'):
    print section.xpath('h3[1]/text()')[0]
    for row in section.xpath('table/tbody/tr'):
        cols = row.xpath('td//text()')
        print '  ', cols[0].ljust(25), ' '.join(cols[1:])
    print

Моя проблема заключается в использовании этого кода в качестве руководства для анализа этой страницы http://www.uscho.com/rankings/d-i-mens-poll/ , Используя следующие изменения, я могу получить только h1 и h3 для печати. ​​

Input

url = 'http://www.uscho.com/rankings/d-i-mens-poll/'
tree = etree.HTML(urlopen(url).read())

for section in tree.xpath('//section[starts-with(@id, "rankings")]'):
    print section.xpath('h1[1]/text()')[0]
    print section.xpath('h3[1]/text()')[0]
    for row in section.xpath('table/tbody/tr'):
        cols = row.xpath('td/b/text()')
        print '  ', cols[0].ljust(25), ' '.join(cols[1:])
    print

выход

USCHO.com Division I Men's Poll
December 12, 2011

Структура таблицы выглядит одинаково, поэтому я не понимаю, почему я не могу использовать подобный код. Я просто инженер-механик в пути над головой. Любая помощь приветствуется.

Ответы [ 3 ]

4 голосов
/ 15 декабря 2011

lxml отлично, но если вы не знакомы с xpath, я рекомендую вам BeautifulSoup:

from urllib2 import urlopen
from BeautifulSoup import BeautifulSoup

url = 'http://www.uscho.com/rankings/d-i-mens-poll/'
soup = BeautifulSoup(urlopen(url).read())

section = soup.find('section', id='rankings')
h1 = section.find('h1')
print h1.text
h3 = section.find('h3')
print h3.text
print

rows = section.find('table').findAll('tr')[1:-1]
for row in rows:
    columns = [data.text for data in row.findAll('td')[1:]]
    print '{0:20} {1:4} {2:>6} {3:>4}'.format(*columns)

Выходные данные для этого скрипта:

USCHO.com Division I Men's Poll
December 12, 2011

Minnesota-Duluth     (49) 12-3-3  999
Minnesota                 14-5-1  901
Boston College            12-6-0  875
Ohio State           ( 1) 13-4-1  848
Merrimack                 10-2-2  844
Notre Dame                11-6-3  667
Colorado College           9-5-0  650
Western Michigan           9-4-5  647
Boston University         10-5-1  581
Ferris State              11-6-1  521
Union                      8-3-5  510
Colgate                   11-4-2  495
Cornell                    7-3-1  347
Denver                     7-6-3  329
Michigan State            10-6-2  306
Lake Superior             11-7-2  258
Massachusetts-Lowell      10-5-0  251
North Dakota               9-8-1   88
Yale                       6-5-1   69
Michigan                   9-8-3   62
2 голосов
/ 16 декабря 2011

Структура таблицы немного отличается, и есть столбцы с пустыми записями.

Возможное lxml решение:

from urllib2 import urlopen
from lxml import etree

url = 'http://www.uscho.com/rankings/d-i-mens-poll/'
tree = etree.HTML(urlopen(url).read())

for section in tree.xpath('//section[@id="rankings"]'):
    print section.xpath('h1[1]/text()')[0],
    print section.xpath('h3[1]/text()')[0]
    print
    for row in section.xpath('table/tr[@class="even" or @class="odd"]'):
        print '%-3s %-20s %10s %10s %10s %10s' % tuple(
            ''.join(col.xpath('.//text()')) for col in row.xpath('td'))
    print

Вывод:

USCHO.com Division I Men's Poll December 12, 2011

1   Minnesota-Duluth           (49)     12-3-3        999          1
2   Minnesota                           14-5-1        901          2
3   Boston College                      12-6-0        875          3
4   Ohio State                 ( 1)     13-4-1        848          4
5   Merrimack                           10-2-2        844          5
6   Notre Dame                          11-6-3        667          7
7   Colorado College                     9-5-0        650          6
8   Western Michigan                     9-4-5        647          8
9   Boston University                   10-5-1        581         11
10  Ferris State                        11-6-1        521          9
11  Union                                8-3-5        510         10
12  Colgate                             11-4-2        495         12
13  Cornell                              7-3-1        347         16
14  Denver                               7-6-3        329         13
15  Michigan State                      10-6-2        306         14
16  Lake Superior                       11-7-2        258         15
17  Massachusetts-Lowell                10-5-0        251         18
18  North Dakota                         9-8-1         88         19
19  Yale                                 6-5-1         69         17
20  Michigan                             9-8-3         62         NR
0 голосов
/ 15 декабря 2011

Заменить 'table/tbody/tr' на 'table/tr'.

...