一句话回答:
使用多个指定名字的参数可以同时过滤 tag 的多个属性,或者使用 attrs 参数传入一个含多属性的字典。
长回答分为多属性查找和多值属性两部分
多属性查找:
我们在使用 BeautifulSoup 时最常规的操作就是根据某个具体 id 或 class 属值筛选出符合条件的标签,我在官方文档的基础上稍加改动,以下面这段 HTML 文档为例:
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<p class="title"><b>The Dormouse's story</b></p >
<p class="story">Once upon a time there were three little sisters; and their names were
< a href=" " class="sister test" id="link1" target="_blank">Elsie</ a>,
< a href="http://example.com/lacie" class="sister" id="link2">Lacie</ a> and
< a href="http://example.com/tillie" class="sister" id="link3">Tillie</ a>;
and they lived at the bottom of a well.</p >
<p class="story">...</p >
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, "lxml")
比如,你可以直接根据 link1 link2 link3 这些 id 定位到具体的 a 标签,你也可以根据 sister 获取到三个 a 标签:
link1 = soup.find_all("a", id="link1")
# [<a class="sister test2" href=" " id="link1" target="_blank">Elsie</a>]
links = soup.find_all("a", class_="sister")
# [<a class="sister test2" href=" " id="link1" target="_blank">Elsie</a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
这属于常见做法,你甚至可以通过 target 属性来获取标签:
target = soup.find_all("a", target="_blank")
# [<a class="sister test2" href=" " id="link1" target="_blank">Elsie</a>]
我理解的题主的问题,大概是类似于,同时筛选 class 和 target 两个属性值,比如 class 为 sister,target 为 _blank 这样的标签。做法其实很直观:
target = soup.find_all("a", class_="sister", target="_blank" )
这种写法只要往后面继续加关键字就好了…但是关键字太多就不太直观了…所以我们也可以换一种写法,向 attrs 传入一个字典即可:
links = soup.find_all("a", attrs={"class": "sister", "target": "_blank"})
我个人其实是习惯后一种写法的。顺便说为什么前者中要用 class_ 而不能是 class,因为 class 是 Python 保留关键字,使用 class 做参数会导致语法错误。从 Beautiful Soup 的 4.1.1 版本开始,可以通过 class_ 参数搜索有指定 CSS 类名的 tag。在我看来,与其刻意避开这个坑,倒不如直接更规范地写成 attrs={"class": "sister"} 的形式(attrs可以省略,直接传字典作为参数就可以)
顺便提醒注意多值属性
Beautiful Soup 4.2.0 文档www.crummy.com
HTML 中的一些属性可以有多值,最常见的多值的属性是 class。那么我们使用 class 的值筛选 tag 时就需要注意,可以分别搜索tag中的每个类名,也可以完全匹配,但是完全匹配 class 的值时,如果类名的顺序与实际不符,将搜索不到结果。
依然是上例:
links1 = soup.find_all("a", attrs={"class": "test"})
# [<a class="sister test" href=" " id="link1" target="_blank">Elsie</a>]
links2 = soup.find_all("a", attrs={"class": "sister test"})
# [<a class="sister test" href=" " id="link1" target="_blank">Elsie</a>]
links = soup.find_all("a", attrs={"class": "test sister"})
# []