据我所了解,Python中两个主要的HTML解析库是lxml和BeautifulSoup。我选择使用BeautifulSoup来完成正在进行的项目,但这只是因为我发现它的语法比较易学易懂,并没有特别的原因。尽管如此,我发现很多人似乎更喜欢lxml,并且我也听说lxml更快。
那么,一个库相对于另一个库有哪些优点呢?在什么情况下应该使用lxml呢?在什么情况下使用BeautifulSoup会更好?还有其他值得考虑的库吗?
据我所了解,Python中两个主要的HTML解析库是lxml和BeautifulSoup。我选择使用BeautifulSoup来完成正在进行的项目,但这只是因为我发现它的语法比较易学易懂,并没有特别的原因。尽管如此,我发现很多人似乎更喜欢lxml,并且我也听说lxml更快。
那么,一个库相对于另一个库有哪些优点呢?在什么情况下应该使用lxml呢?在什么情况下使用BeautifulSoup会更好?还有其他值得考虑的库吗?
Pyquery
提供了类似于jQuery选择器的接口,可在 Python 中使用(内部使用 lxml 库)。
http://pypi.python.org/pypi/pyquery
它真的很棒,我再也不用其他东西了。
首先,BeautifulSoup已经停止活跃维护, 作者甚至推荐使用lxml等替代方案。
引用链接页面中的话:
Beautiful Soup 的版本 3.1.0 对真实世界的 HTML 处理效果要差得多, 比起版本 3.0.8 来。最常见的问题是 处理标签不正确、"malformed start tag"和 "bad end tag" 错误。 这个页面解释了发生了什么,问题将如何解决, 以及你现在可以做什么。
此页面最初编写于2009年3月。 从那时起,3.2系列已发布,代替了3.1系列, 并开始开发4.x系列。为了历史记录, 此页面将保持不变。
简而言之
请改用3.2.0版本。
lxml
只是一个替代品,用来取代问题版本 3.1.0,而这些问题在 3.2.0 中已得到解决,并且现在甚至有了发布时间只有两个月的版本 4——因此该模块很难被称为“不再积极维护”。请修改回答 - Eli Benderskylxml
定位为轻松快捷、生产级别的HTML和XML解析器,顺带还包括一个soupparser
模块,以支持BeautifulSoup的功能。 BeautifulSoup
是一个由一个人完成的项目,旨在帮助您节省时间,从格式不正确的HTML或XML中快速提取数据。
lxml documentation表示两种解析器都有优点和缺点。因此,lxml
提供了一个soupparser
,以便您可以来回切换。引用如下,
最后他们说,BeautifulSoup使用不同的解析方法。它不是一种真正的HTML解析器,而是使用正则表达式来深入解析标签汤。因此,在某些情况下它更容易遵循而在其他情况下则可能效果不佳。 lxml/libxml2通常能够更好地解析和修复破损的HTML代码,但BeautifulSoup对于编码检测具有更高的支持率。这很大程度上取决于输入的内容哪种解析器更有效。
lxml
更直接,只是像预期的那样解析和构建树。我认为它也适用于BeautifulSoup
本身,而不仅仅是lxml
的soupparser
。BeautifulSoup
的编码检测,同时仍然使用lxml
快速解析:>>> 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
的创始人的话说,
That's it! Have fun! I wrote Beautiful Soup to save everybody time. Once you get used to it, you should be able to wrangle data out of poorly-designed websites in just a few minutes. Send me email if you have any comments, run into problems, or want me to know about your project that uses Beautiful Soup.
--Leonard
希望现在清楚了。这个工具是一个出色的个人项目,旨在节省你从设计不良的网站中提取数据的时间。目标是立即为您节省时间,完成工作,而不一定是长期节省时间,并且绝对不会优化软件的性能。
此外,来自lxml网站,
lxml已经从Python Package Index下载超过两百万次,也直接在许多软件包分发中提供,例如Linux或MacOS-X。
还有,来自为什么选择lxml?,
C库libxml2和libxslt具有巨大的优势:...符合标准...功能齐全...快速。 快!快!... lxml是libxml2和libxslt的新Python绑定...
不要使用BeautifulSoup,改用lxml.soupparser,这样你就能充分利用lxml的强大之处,并使用BeautifulSoup的优秀功能来处理破损和低质量的HTML。
我曾经非常成功地使用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()
<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.