我在 HTML 中有两组不同的 div 标签:
<div class="ABC BCD CDE123">
<div class="ABC BCD CDE234">
<div class="ABC BCD CDE345">
和
<div class="ABC XYZ BCD">
我想选择所有带有 ABC 和 BCD 的标签,但不包含 BeautifullSoup4 的 XYZ 类。
我已经知道这种方法:
soup.find_all('div', class_=['ABC','BCD'])
搜索为
OR
(因此必须存在 ABC 或 BCD)。我也知道这里的方法:
def myfunction(theclass):
return theclass is not None and len(theclass)=5
soup.find_all('div', class_=myfunction)
这将返回类名长度为 5 的所有 div
然后我试图用这个解决我的问题:
soup.find_all('div', class_ = lambda x: x and 'ABC' and 'BCD' in x.split() and x and 'XYZ' not in x.split())
但这是行不通的。
所以我尝试用这种方法调试它:
def myfunction(theclass):
print theclass
return True
soup.find_all('div', class_=myfunction)
问题似乎是,来自这样的标签:
<div class="ABC BCD CDE123">
只有 'ABC' 交给
myfunction
,所以 theclass = 'ABC'
而不是我所期望的 theclass ='ABC BCD CDE123'
。这也是我猜测 lambda 函数失败的原因。
我如何根据我的要求过滤标签的任何线索:
我想选择所有带有 ABC 和 BCD 的标签,但不包含 BeautifullSoup4 的 XYZ 类。
最佳答案
这可以使用 SET 来完成。
获取类 ABC 和 BCD 的所有结果的列表。将结果包含在 python SET 中。对 XYZ 应用相同的方法。您现在将拥有两个 SET,一个用于 ABC 和 BCD,另一个用于 XYZ。减去两个集合
要在搜索列表中使用 ABC 和 BCD,请使用 select 函数而不是 find_all
from bs4 import BeautifulSoup
data = '''
<div class="ABC BCD CDE123"></div>
<div class="ABC BCD CDE234"></div>
<div class="ABC BCD CDE345"></div>
<div class="ABC XYZ BCD"></div>
<div class="ABC XYZ AAC"></div>
<div class="ABC AAC"></div>
'''
soup = BeautifulSoup(data)
ABC_BCD = set(soup.select('div.ABC.BCD'))
XYZ = set(soup.select('div.XYZ'))
result = ABC_BCD - XYZ
for element in result:
print element
输出
<div class="ABC BCD CDE234"></div>
<div class="ABC BCD CDE123"></div>
<div class="ABC BCD CDE345"></div>
使用 find_all 使用相同的代码
ABC_BCD = set(soup.find_all('div', class_=['ABC','BCD']))
XYZ = set(soup.find_all('div', class_=['XYZ']))
result = ABC-BCD
for element in result:
print element
输出是
<div class="ABC BCD CDE234"></div>
<div class="ABC AAC"></div> #This is what we dont need
<div class="ABC BCD CDE123"></div>
<div class="ABC BCD CDE345"></div>
关于python - BeautifulSoup:查找类名:AND + NOT,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51189822/