58

据我所知,Python 中的两个主要 HTML 解析库是 lxml 和 BeautifulSoup。我为我正在进行的项目选择了 BeautifulSoup,但我选择它并没有什么特别的原因,只是觉得语法更容易学习和理解。但我看到很多人似乎更喜欢 lxml,而且我听说 lxml 更快。

所以我想知道一个比另一个有什么优势?我什么时候想使用 lxml,什么时候使用 BeautifulSoup 更好?还有其他值得考虑的库吗?

4

7 回答 7

26

Pyquery为 Python 提供 jQuery 选择器接口(在底层使用 lxml)。

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

真的太棒了,我不再使用其他任何东西了。

于 2009-12-17T18:48:09.913 回答
22

对于初学者,BeautifulSoup 不再积极维护,作者甚至推荐了 lxml 等替代方案。

从链接页面引用:

Beautiful Soup 3.1.0 版在实际 HTML 上的表现比 3.0.8 版差得多。最常见的问题是错误地处理标签、“格式错误的开始标签”错误和“错误的结束标签”错误。本页介绍了发生的情况、问题将如何解决以及您现在可以做什么。

本页最初写于 2009 年 3 月。从那时起,发布了 3.2 系列,取代了 3.1 系列,并且开始了 4.x 系列的开发。此页面将保留用于历史目的。

tl;博士

请改用 3.2.0。

于 2009-12-17T14:13:22.907 回答
17

总之,lxml它被定位为闪电般快速的生产质量的 html 和 xml 解析器,顺便说一下,它还包括一个soupparser依赖于 BeautifulSoup 功能的模块。BeautifulSoup是一个单人项目,旨在节省您从格式不佳的 html 或 xml 中快速提取数据的时间。

lxml 文档说这两个解析器都有优点和缺点。为此,lxml提供了一个soupparser这样你就可以来回切换。引用,

BeautifulSoup 使用不同的解析方法。它不是真正的 HTML 解析器,而是使用正则表达式来浏览标签汤。因此,在某些情况下它更宽容,而在其他情况下则不太好。lxml/libxml2 可以更好地解析和修复损坏的 HTML 并不少见,但 BeautifulSoup 对编码检测具有卓越的支持。这在很大程度上取决于哪个解析器工作得更好的输入。

最后他们说,

使用这个解析器的缺点是它比 lxml 的 HTML 解析器慢很多。因此,如果性能很重要,您可能需要考虑仅将 soupparser 用作某些情况下的后备。

如果我理解正确,这意味着汤解析器更健壮——它可以通过使用正则表达式来处理格式错误的标签的“汤”——而lxml更简单,只是解析事物并像你一样构建一棵树会期望。我认为它也适用于BeautifulSoup自身,而不仅仅是soupparserfor lxml

他们还展示了如何从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创造者的话来说,

就是这样!玩得开心!我写了美丽的汤来节省大家的时间。一旦习惯了它,您应该能够在几分钟内从设计不佳的网站中提取数据。如果您有任何意见、遇到问题或希望我了解您使用 Beautiful Soup 的项目,请给我发送电子邮件。

 --Leonard

引自Beautiful Soup 文档

我希望这现在很清楚。The soup 是一个出色的单人项目,旨在节省您从设计不佳的网站中提取数据的时间。目标是立即节省您的时间,完成工作,不一定是长期节省您的时间,也绝对不是优化您的软件的性能。

此外,从lxml 网站

lxml 已从 Python 包索引下载超过 200 万次,并且在许多包发行版中也可以直接使用,例如 Linux 或 MacOS-X。

而且,从为什么要使用 lxml?,

C 库 libxml2 和 libxslt 具有巨大的优势:...符合标准...功能齐全...速度快。快速地!快速地!... lxml 是 libxml2 和 libxslt 的新 Python 绑定...

于 2013-10-23T18:25:30.217 回答
11

不要使用 BeautifulSoup,使用 lxml.soupparser然后你就坐在 lxml 的强大功能之上,并且可以使用 BeautifulSoup 的优点来处理非常破碎和蹩脚的 HTML。

于 2009-12-17T14:24:12.630 回答
5

我使用 lxml 解析 HTML 取得了巨大成功。它似乎也可以很好地处理“soupy” 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()
于 2009-12-17T14:19:18.697 回答
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. 
于 2016-03-20T10:03:18.290 回答
0

可以在这里找到一个有点过时的速度比较,它明确推荐 lxml,因为速度差异似乎很大。

于 2012-12-08T13:42:45.317 回答