据我所知,Python中的两个主要HTML解析库是lxml和BeautifulSoup。我选择了BeautifulSoup作为我正在研究的项目,但除了找到更容易学习和理解的语法之外,我选择了它。但是我看到很多人似乎都喜欢lxml,我听说lxml更快。
所以我想知道一个优于另一个的优点是什么?我什么时候想使用lxml?什么时候最好使用BeautifulSoup?还有其他值得考虑的图书馆吗?
答案 0 :(得分:26)
答案 1 :(得分:22)
首先,不再积极维护BeautifulSoup,并且the author even recommends alternatives例如lxml。
从链接页面引用:
美丽的汤3.1.0版本 在真实世界的HTML上显着恶化 比版本3.0.8。最多 常见的问题是处理 标签错误,“格式错误的开始 标记“错误”和“错误结束标记”错误。 这个页面解释了发生了什么,如何 问题将得到解决,并且 你现在能做什么。
此页面最初是用 2009年3月。从那时起,3.2系列 已经发布,取代3.1 系列,以及4.x的开发 系列已经开始。这一页 将保持历史 目的。
<强> TL;博士强>
改用3.2.0。
答案 2 :(得分:14)
总之,lxml
被定位为闪电般快速的生产质量html和xml解析器,顺便说一下,它还包含一个soupparser
模块,可以依赖于BeautifulSoup的功能。 BeautifulSoup
是一个单人项目,旨在为您节省时间,以便从格式不正确的html或xml中快速提取数据。
lxml documentation说两种解析器都有优点和缺点。因此,lxml
提供了soupparser
,因此您可以来回切换。报价,
BeautifulSoup使用不同的解析方法。它不是真正的HTML 解析器,但使用正则表达式来跳过标签汤。它是 因此在某些情况下更宽容,在其他情况下则不那么好。它是 并不罕见lxml / libxml2更好地解析和修复损坏的HTML, 但BeautifulSoup对编码检测有很好的支持。的它 很大程度上取决于解析器更好地工作的输入。
最后他们说,
使用此解析器的缺点是慢得多 lxml的HTML解析器。 因此,如果性能很重要,您可能会想要 考虑将soupparser仅用作某些案例的后备。
如果我理解正确,这意味着汤解析器更强大 - 它可以通过使用正则表达式来处理格式错误标签的“汤” - 而lxml
更直接而且恰到好处解析事物并按照您的预期构建树。我认为它也适用于BeautifulSoup
本身,而不仅仅适用于soupparser
的{{1}}。
他们还展示了如何从lxml
的编码检测中受益,同时仍然使用BeautifulSoup
快速解析:
lxml
(相同来源:http://lxml.de/elementsoup.html)。
用>>> 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))
的创作者的话来说,
就是这样!玩得开心!我写了美丽的汤来节省每个人的时间。 一旦你习惯了它,你应该能够解决数据问题 在短短几分钟内设计糟糕的网站。如果你给我发电子邮件 有任何意见,遇到问题,或希望我了解你的 使用Beautiful Soup的项目。
BeautifulSoup
引自Beautiful Soup documentation。
我希望现在已经清楚了。汤是一个精彩的单人项目,旨在为您节省时间从设计不佳的网站中提取数据。目标是为您节省时间,完成工作,不一定能节省您的长期时间,绝对不是为了优化软件的性能。
此外,来自lxml website,
已经从Python Package Index下载了两个以上的lxml 百万次,也可直接在许多包装中使用 分发,例如对于Linux或MacOS-X。
而且,来自Why lxml?,
C库libxml2和libxslt有很多好处:... 符合标准......功能齐全......快速。快速!快速! ... lxml 是libxml2和libxslt ...
的新Python绑定
答案 3 :(得分:11)
不要使用BeautifulSoup,请使用 lxml.soupparser然后你就是坐在lxml的强大功能之上,并且可以使用BeautifulSoup的优点来处理真正破碎和糟糕的HTML。
答案 4 :(得分:5)
我使用lxml非常成功地解析HTML。它似乎也很好地处理“汤”HTML。我强烈推荐它。
这是一个快速测试,我试图处理一些丑陋的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()
答案 5 :(得分:1)
我肯定会使用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.
答案 6 :(得分:0)
可以找到一个有点过时的速度比较here,它明确推荐lxml,因为速度差异似乎很大。