在pythonparsingHTML – lxml或BeautifulSoup? 哪种更适合哪种用途?

从我可以做出来的,Python中的两个主要的HTMLparsing库是lxml和BeautifulSoup。 我select了BeautifulSoup作为我正在开发的一个项目,但是除了find语法更容易学习和理解外,我没有特别的理由select它。 但是我看到很多人都赞成lxml,我听说lxml更快。

所以我想知道一个在另一个的优点是什么? 我什么时候想要使用lxml,何时使用BeautifulSoup会更好? 还有其他的图书馆值得考虑吗?

对于初学者,BeautifulSoup不再积极维护, 作者甚至推荐使用 lxml等替代品 。

从链接页面引用:

Beautiful Soup 3.1.0版在真实世界的HTML上比3.0.8版显着更差。 最常见的问题是错误地处理标签,“格式错误的开始标签”错误和“错误的结束标签”错误。 本页面解释发生了什么事情,如何解决问题,以及您现在可以做什么。

这个页面最初是在2009年3月写的。从那时起,3.2系列已经发布,取代了3.1系列,4.x系列的开发已经开始。 这个页面将保持历史的目的。

TL;博士

改用3.2.0。

Pyquery为Python提供了jQueryselect器接口(使用lxml)。

http://pypi.python.org/pypi/pyquery

这真的很棒,我什么也不用了。

总之, lxml被定位为一个闪电般快速的生产质量的html和xmlparsing器,顺便说一下,它还包含一个soupparser模块,用于恢复BeautifulSoup的function。 BeautifulSoup是一个单人项目,旨在节省您的时间,以快速从不良forms的HTML或XML中提取数据。

lxml文档说这两个parsing器都有优点和缺点。 出于这个原因, lxml提供了一个soupparser所以你可以来回切换。 引用,

BeautifulSoup使用不同的parsing方法。 这不是一个真正的HTMLparsing器,但使用正则expression式通过标签汤进行深入探索。 因此,在某些情况下更为宽容,其他方面更不好。 lxml / libxml2更好地parsing和修复破损的HTML并不less见,但BeautifulSoup支持编码检测。 这非常依赖于parsing器工作得更好的input。

最后他们说,

使用这个parsing器的缺点是它比lxml的HTMLparsing器得多。 所以如果性能很重要的话,你可能会考虑使用soupparser作为某些情况下的后备。

如果我正确地理解了它们,这意味着汤parsing器更加健壮 – 它可以使用正则expression式处理畸形标记的“汤” – 而lxml更直接,只是parsing事物并构build树你会期望的。 我认为这也适用于BeautifulSoup本身,而不仅仅是lxmlsoupparser

他们还展示了如何从BeautifulSoup的编码检测中受益,同时仍然使用lxml快速parsing:

 >>> from BeautifulSoup import UnicodeDammit >>> def decode_html(html_string): ... converted = UnicodeDammit(html_string, isHTML=True) ... if not converted.unicode: ... raise UnicodeDecodeError( ... "Failed to detect encoding, tried [%s]", ... ', '.join(converted.triedEncodings)) ... # print converted.originalEncoding ... return converted.unicode >>> root = lxml.html.fromstring(decode_html(tag_soup)) 

(相同来源: http : //lxml.de/elementsoup.html )。

BeautifulSoup的创造者的话来说,

而已! 玩的开心! 我写了美丽的汤,以节省每个人的时间。 一旦你习惯了,你应该能够在短短几分钟内从devise不佳的网站上调出数据。 如果您有任何意见,请发邮件给我,遇到问题,或要求我了解您使用美丽汤的项目。

  --Leonard 

从美丽的汤文件引用。

我希望现在清楚。 汤是一个精彩的单人项目,旨在节省您的时间从devise不佳的网站提取数据。 目的是为了节省您的时间,完成工作,而不一定是为了节省您的时间,而且绝对不是为了优化软件的性能。

另外,从lxml网站上 ,

lxml已经从Python Package Index下载了超过两百万次,并且也可以直接用于许多软件包发行版,例如Linux或MacOS-X。

而且,从为什么lxml? ,

C库libxml2和libxslt有巨大的好处:…符合标准…全function…快速。 快速! 快速! … lxml是一个新的Python绑定libxml2和libxslt …

不要使用BeautifulSoup,使用lxml.soupparser然后你坐在lxml的力量之上,并且可以使用BeautifulSoup的好处来处理真正的破坏和蹩脚的HTML。

我用lxmlparsingHTML非常成功。 它似乎也处理“soupy”的HTML也很好。 我强烈推荐它。

这里有一个快速testing,我试图处理一些丑陋的HTML:

 import unittest from StringIO import StringIO from lxml import etree class TestLxmlStuff(unittest.TestCase): bad_html = """ <html> <head><title>Test!</title></head> <body> <h1>Here's a heading <p>Here's some text <p>And some more text <b>Bold!</b></i> <table> <tr>row <tr><td>test1 <td>test2 </tr> <tr> <td colspan=2>spanning two </table> </body> </html>""" def test_soup(self): """Test lxml's parsing of really bad HTML""" parser = etree.HTMLParser() tree = etree.parse(StringIO(self.bad_html), parser) self.assertEqual(len(tree.xpath('//tr')), 3) self.assertEqual(len(tree.xpath('//td')), 3) self.assertEqual(len(tree.xpath('//i')), 0) #print(etree.tostring(tree.getroot(), pretty_print=False, method="html")) if __name__ == '__main__': unittest.main() 

当然,我会使用EHP。 它比lxml更快,更好用,更简单。

查看。 https://github.com/iogf/ehp

 <body ><em > foo <font color="red" ></font></em></body> from ehp import * data = '''<html> <body> <em> Hello world. </em> </body> </html>''' html = Html() dom = html.feed(data) for ind in dom.find('em'): print ind.text() 

输出:

 Hello world. 

可以在这里find一个有点过时的速度比较,这明显推荐lxml,因为速度差异看起来很激烈。