我可以将两个BeautifulSoup中的'findAll'搜索块合并为一个吗?

2 投票
4 回答
6423 浏览
提问于 2025-04-15 16:33

我可以把这两个代码块合并成一个吗:

补充说明:除了像Yacoby在回答中那样合并循环,还有其他方法吗。

for tag in soup.findAll(['script', 'form']):
    tag.extract()

for tag in soup.findAll(id="footer"):
    tag.extract()

我还可以把多个代码块合并成一个吗:

for tag in soup.findAll(id="footer"):
    tag.extract()

for tag in soup.findAll(id="content"):
    tag.extract()

for tag in soup.findAll(id="links"):
    tag.extract()

或者有没有什么lambda表达式可以用来检查数组,或者其他更简单的方法。

另外,我该如何找到带有class属性的标签,因为class是一个保留字:

补充说明:这一部分可以通过soup.findAll(attrs={'class': 'noprint'})来解决:

for tag in soup.findAll(class="noprint"):
    tag.extract()

4 个回答

0

你问题的第二部分答案其实就在文档里:

通过CSS类进行搜索

attrs这个参数本来可能会让人觉得很复杂,但有一个原因让它变得很有用,那就是CSS。通过某个特定的CSS类来查找标签是非常有用的,但CSS属性的名字“class”在Python中是一个保留字。

你可以用soup.find("标签名", { "class" : "css类名" })来通过CSS类进行搜索,不过这样写代码有点多,毕竟这是个常见的操作。其实,你可以直接用字符串来代替字典作为attrs参数,这样就能更简单地限制CSS类了。

from BeautifulSoup import BeautifulSoup
soup = BeautifulSoup("""Bob's <b>Bold</b> Barbeque Sauce now available in 
                   <b class="hickory">Hickory</b> and <b class="lime">Lime</a>""")

soup.find("b", { "class" : "lime" })
# <b class="lime">Lime</b>

soup.find("b", "hickory")
# <b class="hickory">Hickory</b>
5

我不知道BeautifulSoup是否有更优雅的方法,但你可以把这两个循环合并成这样:

for tag in soup.findAll(['script', 'form']) + soup.findAll(id="footer"):
    tag.extract()

你可以这样找到类(文档):

for tag in soup.findAll(attrs={'class': 'noprint'}):
    tag.extract()
8

你可以像这样把函数传给 .findall()

soup.findAll(lambda tag: tag.name in ['script', 'form'] or tag['id'] == "footer")

不过,先建立一个标签的列表,然后再逐个处理可能会更好:

tags = soup.findAll(['script', 'form'])
tags.extend(soup.findAll(id="footer"))

for tag in tags:
    tag.extract()

如果你想筛选多个 id,可以使用:

for tag in soup.findAll(lambda tag: tag.has_key('id') and
                                    tag['id'] in ['footer', 'content', 'links']):
    tag.extract()

更具体的方法是把一个 lambda 函数赋值给 id 参数:

for tag in soup.findAll(id=lambda value: value in ['footer', 'content', 'links']):
    tag.extract()

撰写回答