【发布时间】:2020-02-18 17:25:01
【问题描述】:
有两个元素:<div class = "abc def"> 和 <div class = "abc">
我想选择后者。
我的代码是
soup.find('div', {'class':'abc'})
但是它选择了前者。
正确的做法是什么?
【问题讨论】:
标签: python beautifulsoup
有两个元素:<div class = "abc def"> 和 <div class = "abc">
我想选择后者。
我的代码是
soup.find('div', {'class':'abc'})
但是它选择了前者。
正确的做法是什么?
【问题讨论】:
标签: python beautifulsoup
前一个元素有两个类:和(参见例如How to assign multiple classes to an HTML container?),因此BeautifulSoup 在使用find() 时正确指向它。
为了指向第二个你应该使用findAll - 它返回一个列表 - 并提取第二个元素:
soup.findAll('div', {'class':'abc'})[1]
【讨论】:
listname[-1]
来自Official doc:
您也可以搜索类属性的确切字符串值:
css_soup.find_all("p", class_="body strikeout") # [<p class="body strikeout"></p>]
soup.find_all("div", class_="abc")
【讨论】:
试试 :nth-of-type(2) 或 :nth-child(2) 与 css 选择器。
print(soup.select_one('.abc:nth-of-type(2)'))
示例:
html='''<div class = "abc def"></div>
<div class = "abc"></div>'''
soup=BeautifulSoup(html,'html.parser')
print(soup.select_one('.abc:nth-of-type(2)'))
已编辑:
print(soup.select_one('.abc:not(.def)'))
【讨论】:
要获得精确的类匹配,您可以使用以下函数 lambda 表达式作为过滤器。
soup.find_all(lambda x: x.name == 'div' and ''.join(x.get('class', list())) == 'abc')
如果需要,您也可以将其包装在一个函数中。 ''.join(x.get('class', list())) == 'abc' 加入类(如果可用)并检查它是否等于 'abc'。
例子
from bs4 import BeautifulSoup
html = """
<div class = "abc def"></div>
<div class = "abc"></div>
<div></div>
"""
soup = BeautifulSoup(html, 'html.parser')
print(
soup.find_all(
lambda x: x.name == 'div' and ''.join(x.get('class', list())) == 'abc'
)
)
输出
[<div class="abc"></div>]
参考:
【讨论】: