find_all在混合内容中找不到文本

时间:2014-12-20 00:55:04

标签: python regex beautifulsoup

我在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"

升级后,标签主体现在包含一个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所做的搜索,就在那里 修改第一个代码的方法是什么?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

第一个示例仅在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'