2009-01-19 60 views
3

我在用BeautifulSoup解析一些狡猾的HTML时遇到了麻烦。事实证明,在较新版本中使用的HTMLParser比以前使用的SGMLParser具有更小的容错性。BeautifulSoup 3.1解析器太容易打破


BeautifulSoup有某种调试模式吗?我试图找出如何阻止它borking一些讨厌的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会告诉我它在做什么,所以在这种情况下,我可以弄清楚它作为标签名称是什么?

回答

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

这是Python的2.5.2与BeautifulSoup 3.0.7a - 也许这是中老年/新版本有什么不同?这正是BeautifulSoup处理得如此精美的那种汤,所以我怀疑它在某个时候已经发生了变化......在结构中还有别的东西,你没有在问题中提到过吗?

+0

我有Python 2.5.1和BeautifulSoup 3.1.0.1。原始的破碎结构是不同的,但问题也出现在问题的简化结构中。我刚刚在您的示例中运行了代码,并且遇到了与以前相同的问题,在之后没有任何问题。现在我真的很困惑! – Mat 2009-01-19 23:49:26

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还没有固定在这种情况下,问题虽然。

3

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

Ian Blicking agrees

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