复杂的Beautiful Soup查询

3 投票
3 回答
6288 浏览
提问于 2025-04-15 11:05

这是我用Beautiful Soup探索的一个HTML文件片段。

<td width="50%">
    <strong class="sans"><a href="http:/website">Site</a></strong> <br /> 

我想要获取任何包含<strong class="sans">的行中的<a href>,而这些行必须是在<td width="50%">里面的。

使用Beautiful Soup,能否对这个HTML文件进行这样的多重条件查询呢?

3 个回答

0
from bs4 import BeautifulSoup
html_doc = """<td width="50%">
<strong class="sans"><a href="http:/website">Site</a></strong> <br /> 
"""
soup = BeautifulSoup(html_doc, 'html.parser')
soup.select('td[width="50%"] .sans [href]')
# Out[24]: [<a href="http:/website">Site</a>]

文档

0

在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,特别是当我们不太了解这些工具的工作原理时。比如,有些错误信息可能会让人觉得很复杂,但其实它们只是告诉我们哪里出错了,或者需要我们注意什么。

当我们在网上寻找解决方案时,像StackOverflow这样的平台就非常有用。这里有很多经验丰富的程序员分享他们的知识和经验,帮助我们解决问题。我们可以看到他们的提问和回答,学习到很多实用的技巧和方法。

总之,遇到问题时,不要害怕去寻求帮助。通过学习和实践,我们会逐渐掌握更多的编程知识,变得越来越熟练。

>>> BeautifulSoup.BeautifulSoup("""<html><td width="50%">
...     <strong class="sans"><a href="http:/website">Site</a></strong> <br />
... </html>""" )
<html><td width="50%">
<strong class="sans"><a href="http:/website">Site</a></strong> <br />
</td></html>
>>> [ a for a in strong.findAll("a") 
            for strong in tr.findAll("strong", attrs = {"class": "sans"}) 
                for tr in soup.findAll("td", width = "50%")]
[<a href="http:/website">Site</a>]
12

BeautifulSoup的搜索机制可以接受一个可调用对象,也就是可以像函数一样被调用的东西。文档里似乎推荐在你的情况下使用这个:“如果你需要对标签的属性施加复杂或相互关联的限制,可以传入一个可调用对象作为名称,……”。(好吧,他们具体是在讲属性,但这个建议反映了BeautifulSoup API的一个基本精神。)

如果你想要一行代码的解决方案:

soup.findAll(lambda tag: tag.name == 'a' and \
tag.findParent('strong', 'sans') and \
tag.findParent('strong', 'sans').findParent('td', attrs={'width':'50%'}))

我在这个例子中用了一个lambda表达式,但实际上如果你有多个条件需要同时满足,可能更好定义一个可调用的函数,因为这个lambda表达式需要调用两次findParent('strong', 'sans'),这样才能避免在<a>标签没有strong父标签时抛出异常。使用一个合适的函数,你可以让测试变得更高效。

撰写回答