我正在抓取HTML网页。我在Mac(Sierra)上使用BeautifulSoup lib(4.6.0)和Python(3.7)。
除其他外,我看到了一堆具有类属性的'div'标签。一些'div'标签带有多个类属性值。现在我想根据标签名称和类属性值进行过滤,例如我想找到具有class ='a'但没有class ='b'的'div'标签(是的,有些div标签带有class ='a b')。
要获取这些标签,我尝试使用BS4文档(https://www.crummy.com/software/BeautifulSoup/bs4/doc/#a-function)中提到的过滤功能。我的印象是find_all()将bs4标签元素传递给该函数,并且在该函数内您可以执行对BS4标签元素的任何操作。这似乎是不正确的。我得到一个字符串,显然所有我的BS4标签元素操作都引发了异常。
两个问题:
答案 0 :(得分:0)
给我的印象是find_all()将bs4标签元素传递给该函数,并且在该函数内您可以执行对BS4标签元素的任何操作。
您的印象是正确的。从bs4文档(重点是我的):
...定义一个将元素作为其唯一参数的函数。
因此,文档中的每个元素都将传递给filter函数,如果该函数为该元素返回True
,则该元素将包含在.find_all()
返回的元素列表中。实际上,这只能用作最后的选择,因为它可能会占用大量性能。我不完全确定为什么要获取字符串,一种可能是您正在将函数传递给class_=
参数,该参数确实传递了字符串,但不能不看代码就不能说。>
我认为您应该做的是使用.find_all()
获取所有具有类“ a”的<div>
,然后使用它们过滤掉那些仅包含没有类“ b”的那些自己的方法,像这样:
divs = soup.find_all('div', class_='a')
filtered_divs = [ div for div in divs if 'b' not in div.attrs['class'].split(' ') ]
但是,如果您确实想使用过滤器功能,看起来就像
class_a_not_b(e):
if 'class' not in e.attrs: return False
return 'a' in e.attrs['class'].split(' ') and 'b' not in e.attrs['class'].split(' ')
divs = soup.find_all(class_a_not_b)