BeautifulSoup 3.1解析器很容易打破

时间:2009-01-19 23:07:03

标签: python html parsing beautifulsoup

我在使用BeautifulSoup解析一些狡猾的HTML时遇到了麻烦。事实证明,较新版本中使用的HTMLParser不如先前使用的SGMLParser容忍。


BeautifulSoup有某种调试模式吗?我正在试图弄清楚如何阻止它从一个讨厌的HTML borking我从一个crabby网站加载:

<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 个答案:

答案 0 :(得分:6)

Having problems with 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在这种情况下没有解决问题。

答案 1 :(得分:3)

尝试lxml(及其html模块)。尽管它的名字,它也用于解析和抓取HTML。它比BeautifulSoup快得多,甚至比BeautifulSoup更好地处理“破坏”的HTML。如果您不想学习lxml API,它还有BeautifulSoup的兼容性API。

Ian Blicking agrees

没有理由再使用BeautifulSoup了,除非您使用的是Google App Engine或其他不允许使用Python的东西。

答案 2 :(得分:2)

你的问题必须是别的;它适用于我:

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]: 

这是带有BeautifulSoup 3.0.7a的Python 2.5.2 - 也许它在旧版本/新版本中有所不同?这正是BeautifulSoup如此美妙地处理的那种汤,所以我怀疑它在某些时候已经被改变了......在这个问题中你还没有提到过其他结构吗?