【问题标题】:Non-recursive find with lxml builder使用 lxml 构建器进行非递归查找
【发布时间】:2016-07-13 13:00:35
【问题描述】:

我发现在 Python 2.7 中,如果我使用 lxml 构建器,我无法执行非递归 bs4.BeautifulSoup.find_all

以 HTML sn-p 为例:

<p> <b> Cats </b> are interesting creatures </p>

<p> <b> Dogs </b> are cool too </p>

<div>
<p> <b> Penguins </b> are pretty neat, but they're inside a div </p>
</div>

<p> <b> Llamas </b> don't live in New York </p>

假设我想找到所有p 直接子元素。我用find_all("p", recursive=False) 做一个非递归的find_all

为了测试这一点,我将上面的 HTML sn-p 设置在一个名为 html 的变量中。然后,我创建了两个BeautifulSoup 实例,ab

a = bs4.BeautifulSoup(html, "html.parser")
b = bs4.BeautifulSoup(html, "lxml")

它们在正常使用find_all 时都能正常运行:

>>> a.find_all("p")
[<p> <b> Cats </b> are interesting creatures </p>, <p> <b> Dogs </b> are cool too </p>, <p> <b> Penguins </b> are pretty neat, but they're inside a div </p>, <p> <b> Llamas </b> don't live in New York </p>]
>>> b.find_all("p")
[<p> <b> Cats </b> are interesting creatures </p>, <p> <b> Dogs </b> are cool too </p>, <p> <b> Penguins </b> are pretty neat, but they're inside a div </p>, <p> <b> Llamas </b> don't live in New York </p>]

但如果我关闭递归查找,则只有 a 有效。 b 返回一个空列表:

>>> a.find_all("p", recursive=False)
[<p> <b> Cats </b> are interesting creatures </p>, <p> <b> Dogs </b> are cool too </p>, <p> <b> Llamas </b> don't live in New York </p>]
>>> b.find_all("p", recursive=False)
[]

这是为什么?这是一个错误,还是我做错了什么? lxml 构建器是否支持非递归 find_all

【问题讨论】:

    标签: python python-2.7 parsing beautifulsoup lxml


    【解决方案1】:

    这是因为lxml 解析器会将您的 HTML 代码放入 html/body 中(如果它不存在):

    >>> b = bs4.BeautifulSoup(html, "lxml")
    >>> print(b)
    <html><body><p> <b> Cats </b> are interesting creatures </p>
    <p> <b> Dogs </b> are cool too </p>
    <div>
    <p> <b> Penguins </b> are pretty neat, but they're inside a div </p>
    </div>
    <p> <b> Llamas </b> don't live in New York </p>
    </body></html>
    

    因此,非递归模式下的find_all() 将尝试在html 元素中查找元素,该元素只有一个body 子元素:

    >>> print(b.find_all("p", recursive=False))
    []
    >>> print(b.body.find_all("p", recursive=False))
    [<p> <b> Cats </b> are interesting creatures </p>, <p> <b> Dogs </b> are cool too </p>, <p> <b> Llamas </b> don't live in New York </p>]
    

    【讨论】:

    • 这对我来说似乎有些不一致,为什么不同的解析器会以这种方式表现不同?
    • @LukeTaylor 这可能会令人困惑,我同意。在Differences between parsers 文档段落中有一些相关信息。这一切都归结为不同的解析器使非格式良好的 HTML 成为有效的 - 他们只是做的不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 2010-09-10
    • 2014-03-20
    • 2019-01-05
    • 2012-02-18
    相关资源
    最近更新 更多