Разбор HTML с использованием Python - PullRequest
3 голосов
/ 22 марта 2012

Мне нужно проанализировать веб-страницу и извлечь из нее некоторые значения. Поэтому я создал парсер Python следующим образом:

from HTMLParser import HTMLParser
class MyHTMLParser(HTMLParser):
    def handle_data(self, data):
        print "Data     :", data

f=open("result.html","r")
s=f.read()
parser = MyHTMLParser()
parser.feed(s)

Программа читает файл html и печатает данные из него.

Я передал следующий result.html, здесь парсер работает нормально

<tr class='trmenu1'>
<td>Marks Obtained: </td><td colspan=1>75.67 Out of 100</td>
</tr>
<tr class='trmenu1'>
<td>GATE Score: </td><td colspan=1>911</td>
</tr>
<tr class='trmenu1'>
<td>All India Rank: </td><td colspan=1>34</td>
</tr>

После прохождения вышеупомянутого html выдается:

Данные:

Данные: Оценки получены:
Данные: 75,67 из 100 Данные:

Данные:

Данные:

Данные: GATE Счет:
Данные: 911
Данные:

Данные:

Данные:

Данные: Вся Индия Ранг:
Данные: 34

Но синтаксический анализатор должен читать файл большего размера, а код, упомянутый выше, является небольшой частью этого большого файла. Файл слишком большой, чтобы вставить его сюда. Поэтому я загрузил его по следующей ссылке: http://www.mediafire.com/?dsgr1gdjvs59c7c Когда передается больший файл, парсер не читает все записи, оставляя некоторые пустые записи в выводе. Часть вывода показана ниже:

Данные: Силлаби

Данные:

Данные: GATE Score

Данные:

Данные: результаты GATE

Данные:

Обратите внимание на пустую запись в строке под счетом ворот, которая была 911 в предыдущем выводе.

Парсер работает нормально с маленьким файлом, но не с большим файлом Почему это происходит? Я использую Python 2.7

Ответы [ 2 ]

7 голосов
/ 22 марта 2012

Мое предпочтительное решение для анализа HTML или XML - lxml и xpath.

Быстрый и грязный пример того, как вы можете использовать xpath:

from lxml import etree
data = open('result.html','r').read()
doc = etree.HTML(data)

for tr in doc.xpath('//table/tr[@class="trmenu1"]'):
  print tr.xpath('./td/text()')

Выход:

['Registration Number: ', ' CS 2047103']
['Name of the Candidate: ', 'PATIL SANTOSH KUMARRAO        ']
['Examination Paper: ', 'CS - Computer Science and Information Technology']
['Marks Obtained: ', '75.67 Out of 100']
['GATE Score: ', '911']
['All India Rank: ', '34']
['No of Candidates Appeared in CS: ', '156780']
['Qualifying Marks for CS: ', '\r\n\t\t\t\t\t']
['General', 'OBC ', '(Non-Creamy)', 'SC / ST / PD ']
['31.54', '28.39', '21.03 ']

Этот код создает ElementTree из данных HTML.Используя xpath, он выбирает все элементы <tr>, где есть атрибут class="trmenu1".Затем для каждого <tr> он выбирает и печатает текст любого <td> потомка.

2 голосов
/ 22 марта 2012

Если вы внимательно посмотрите на HTML-страницу на MediaFire, вы заметите, что у вас есть два текстовых блока, которые содержат «Оценка GATE»

 line 162: <tr><td class='qlink4' background='webimages/blkbuttona3.jpg' onMouseOut="background='webimages/blkbuttona3.jpg'" onMouseOver="background='webimages/blkbuttonb3.jpg'">&nbsp;<a class="dark2" href="gscore.php" title="GATE Score">GATE Score</a></td></tr>

 line 192: <tr class='trmenu1'><td>GATE Score: </td><td colspan=1>911</td></tr>

Проблема, с которой вы столкнулись, возможно, связана с ошибкой в ​​полной html-странице, которую вы пытаетесь проанализировать, поэтому вы можете видеть только одно вхождение "GATE Score".

Как вам было предложено в комментариях, используйте BeautifulSoup, который более терпим к искаженному HTML.

...