Парсер BeautifulSoup 3.1 ломается слишком легко - PullRequest
3 голосов
/ 20 января 2009

У меня возникли проблемы с анализом некоторого хитрого HTML с BeautifulSoup. Оказывается, что HTMLParser, используемый в более новых версиях, менее терпим, чем SGMLParser, используемый ранее.


Есть ли у BeautifulSoup какой-нибудь режим отладки? Я пытаюсь выяснить, как остановить это на некотором противном HTML, который я загружаю с веб-сайта Крэбби:

<HTML>
    <HEAD>
        <TITLE>Title</TITLE>
        <HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
    </HEAD>
    <BODY>
        ...
        ...
    </BODY>
</HTML>

BeautifulSoup сдается после тега <HTTP-EQUIV...>

In [1]: print BeautifulSoup(c).prettify()
<html>
 <head>
  <title>
   Title
  </title>
 </head>
</html>

Проблема явно в теге HTTP-EQUIV, который на самом деле является очень искаженным тегом <META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">. Очевидно, мне нужно указать это как самозакрывающийся, но что бы я ни указывал, я не могу это исправить:

In [2]: print BeautifulSoup(c,selfClosingTags=['http-equiv',
                            'http-equiv="pragma"']).prettify()
<html>
 <head>
  <title>
   Title
  </title>
 </head>
</html>

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

Ответы [ 3 ]

6 голосов
/ 12 марта 2009

Возникли проблемы с Beautiful Soup 3.1.0? рекомендует использовать парсер html5lib в качестве одного из обходных путей.

#!/usr/bin/env python
from html5lib import HTMLParser, treebuilders

parser = HTMLParser(tree=treebuilders.getTreeBuilder("beautifulsoup"))

c = """<HTML>
    <HEAD>
        <TITLE>Title</TITLE>
        <HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
    </HEAD>
    <BODY>
        ...
        ...
    </BODY>
</HTML>"""

soup = parser.parse(c)
print soup.prettify()

Выход:

<html>
 <head>
  <title>
   Title
  </title>
 </head>
 <body>
  <http-equiv="pragma" content="NO-CACHE">
   ...
        ...
  </http-equiv="pragma">
 </body>
</html>

Вывод показывает, что html5lib в этом случае не устранил проблему.

3 голосов
/ 03 августа 2009

Попробуйте lxml (и его html-модуль). Несмотря на название, он также предназначен для анализа и очистки HTML. Это намного, намного быстрее, чем BeautifulSoup, и он даже обрабатывает «сломанный» HTML лучше, чем BeautifulSoup. Он также имеет API совместимости для BeautifulSoup, если вы не хотите изучать lxml API.

Ян Бликинг соглашается .

Больше нет смысла использовать BeautifulSoup, если только вы не используете Google App Engine или что-то, где нет ничего, кроме Python.

2 голосов
/ 20 января 2009

Ваша проблема должна быть чем-то другим; у меня работает нормально:

In [1]: import BeautifulSoup

In [2]: c = """<HTML>
   ...:     <HEAD>
   ...:         <TITLE>Title</TITLE>
   ...:         <HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
   ...:     </HEAD>
   ...:     <BODY>
   ...:         ...
   ...:         ...
   ...:     </BODY>
   ...: </HTML>
   ...: """

In [3]: print BeautifulSoup.BeautifulSoup(c).prettify()
<html>
 <head>
  <title>
   Title
  </title>
  <http-equiv>
  </http-equiv>
 </head>
 <body>
  ...
        ...
 </body>
</html>


In [4]: 

Это Python 2.5.2 с BeautifulSoup 3.0.7a - может быть, он отличается от старых / новых версий? Это именно тот вид супа, с которым BeautifulSoup справляется так красиво, что я сомневаюсь, что он был изменен в какой-то момент ... Есть ли что-то еще в структуре, которую вы не упомянули в проблеме?

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