Как разобрать искаженный HTML в python, используя стандартные библиотеки - PullRequest
35 голосов
/ 20 апреля 2010

В python так много библиотек html и xml встроено, что трудно поверить, что нет поддержки для реального анализа HTML.

Я нашел множество отличных сторонних библиотек для этой задачи, но этот вопрос касается стандартной библиотеки python.

Требования:

  • Использовать только стандартные компоненты библиотеки Python (любая версия 2.x)
  • Поддержка DOM
  • Обработка сущностей HTML ( )
  • Обработка частичных документов (например: Hello, <i>World</i>!)

Бонусные баллы:

  • XPATH поддержка
  • Обрабатывать незакрытые / неправильно сформированные метки. (<big>does anyone here know <html ???

Вот мое 90% решение, как и просили. Это работает для ограниченного набора HTML, который я пробовал, но, как все могут видеть, это не совсем надежно. Поскольку я делал это, рассматривая документы в течение 15 минут и одной строки кода, я подумал, что смогу проконсультироваться с сообществом stackoverflow для аналогичного, но лучшего решения ...

from xml.etree.ElementTree import fromstring
DOM = fromstring("<html>%s</html>" % html.replace('&nbsp;', '&#160;'))

Ответы [ 6 ]

43 голосов
/ 21 апреля 2010

Надежный анализ HTML - относительно современная разработка (хотя это может показаться странным). В результате в стандартной библиотеке точно ничего нет. HTMLParser может показаться способом обработки HTML, но это не так - он терпит неудачу на многих очень распространенных HTML, и хотя вы можете обойти эти сбои, всегда будет другой случай, о котором вы даже не подумали (если вам действительно удастся справиться с каждой ошибкой, вы в основном воссоздадите BeautifulSoup).

На самом деле есть только 3 разумных способа разбора HTML (как его можно найти в Интернете): lxml.html , BeautifulSoup и html5lib . lxml является самым быстрым на данный момент, но его может быть немного сложно установить (и невозможно в такой среде, как App Engine). html5lib основан на том, как HTML 5 определяет синтаксический анализ; хотя на практике они похожи на две другие, возможно, они более «правильны» в том, как анализировать битый HTML (они все одинаково хорошо анализируют HTML). Все они делают респектабельную работу при разборе сломанного HTML. BeautifulSoup может быть удобен, хотя я считаю его API излишне изворотливым.

5 голосов
/ 20 апреля 2010

Возьмите исходный код BeautifulSoup и скопируйте его в свой скрипт ;-) Я только шучу ... все, что вы могли бы написать, что бы выполнить эту работу, будет более или менее дублировать функциональность, которая уже существует в библиотеках вот так.

Если это действительно не сработает, я должен спросить, почему так важно, чтобы вы использовали только стандартные компоненты библиотеки?

4 голосов
/ 20 апреля 2010

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

Красивый суп состоит из одного файла Python, содержащего около 2000 строк кода. Если это слишком большая зависимость, тогда напишите свою собственную, она не будет работать так же хорошо и, вероятно, не будет целиком намного меньше.

1 голос
/ 20 апреля 2010

Я не могу придумать ни одного популярного языка с хорошей, надежной, эвристической библиотекой для разбора HTML в своем stdlib. У Python, конечно, его нет, и я думаю, вы это знаете.

Почему требуется модуль stdlib? Большую часть времени, когда я слышу, что люди предъявляют такое требование, они глупы. Для выполнения большинства основных задач вам потребуется сторонний модуль или потратить весь лот работы на его внедрение. Введение зависимости - это хорошо , так как эту работу вам не нужно было делать.

Итак, что вы хотите, это lxml.html. Поставьте lxml вместе с вашим кодом, если это является проблемой, после чего он становится функционально эквивалентным написанию его самостоятельно, за исключением сложности, ошибок и удобства обслуживания.

1 голос
/ 20 апреля 2010

не соответствует вашим требованиям только стандарта, но beautifulsoup приятно

0 голосов
/ 16 февраля 2013

Как уже говорилось, в настоящее время не существует удовлетворительного решения только со стандартной библиотекой. Я столкнулся с той же проблемой, что и вы, когда пытался запустить одну из своих программ в устаревшей среде хостинга без возможности установки собственных расширений и только python2.6. Решение:

Grab этот файл и последняя стабильная BeautifulSoup версия серии 3er (3.2.1 на данный момент). Из tar-файла там просто выберите BeautifulSoup.py, это единственный, который вам действительно нужен для доставки с вашим кодом. Таким образом, у вас есть эти два файла на вашем пути, и все, что вам нужно сделать, чтобы получить случайный объект etree из какой-либо строки HTML, как вы бы получили его из lxml, это:

from StringIO import StringIO
import ElementSoup

tree = ElementSoup.parse(StringIO(input_str))

Для самого lxml и html5lib требуется компиляция некоторого C-кода, чтобы он работал. Значительно больше усилий, чтобы заставить их работать, и если ваша среда ограничена или ваша целевая аудитория не желает этого делать, избегайте их.

...