【问题标题】:find_all does not find text in mixed contentfind_all 在混合内容中找不到文本
【发布时间】:2015-02-18 23:21:32
【问题描述】:

我在 Python 中有一点屏幕抓取代码,使用 BeautifulSoup,这让我很头疼。对 html 的一个小改动使我的代码中断,但我不明白为什么它无法工作。这基本上是一个演示 html 在解析时的外观:

soup=BeautifulSoup("""
<td>
    <a href="https://alink.com">
        Foo Some text Bar
    </a>
</td>
""")
links = soup.find_all('a',text=re.compile('Some text'))
links[0]['href'] # => "https://alink.com"

升级后,a 标签正文现在包含一个 img 标签,这使得代码中断。

<td>
    <a href="https://alink.com">
        <img src="dummy.gif" >
        Foo Some text Bar
    </a>
</td>

'links' 现在是一个空列表,所以正则表达式没有找到任何东西。 我通过仅匹配文本来绕过它,然后找到 它的父级,但这似乎更加脆弱:

links = soup.find_all(text=re.compile('Some text'))
links[0].parent['href'] # => "https://alink.com"

在文本中添加一个 img 标签作为兄弟是什么意思 内容打破了 BeautifulSoup 所做的搜索,并且在那里 修改第一个代码的方法?

【问题讨论】:

  • 为什么不next(link["href"] for link in soup.find_all('a') if "Some text" in link.text)
  • 看起来不错。 next() 调用是做什么的?
  • 只返回第一个匹配项,这将是您想要的链接

标签: python regex beautifulsoup


【解决方案1】:

不同的是,第二个例子有一个不完整的img标签:

应该是

<img src="dummy.gif" />
Foo Some text Bar

<img src="dummy.gif" > </img>
Foo Some text Bar

相反,它被解析为

<img src="dummy.gif" >
Foo Some text Bar
</img>

所以找到的元素不再是a,而是img,其父元素是a

【讨论】:

  • 这种行为实际上是特定于库的。我有一些解析代码可以在我的 Mac 上使用 Python 发行版,但它不适用于我的 Linux 发行版。不完整的 img 标签在一个运行时被视为父级,但在另一个运行时不被视为兄弟级。一定会喜欢的。
【解决方案2】:

第一个示例仅在 a.string 不是 None 时才有效,即,如果文本是唯一的孩子。

作为一种解决方法,您可以使用函数谓词:

a = soup.find(lambda tag: tag.name == 'a' and tag.has_attr('href') and 'Some text' in tag.text)
print(a['href'])
# -> 'https://alink.com'

【讨论】:

    猜你喜欢
    • 2013-01-18
    • 2014-08-20
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 2021-08-01
    相关资源
    最近更新 更多