我正在抓取一个HTML网页。我在Mac机上使用Python库(4.6.0)和BeautifulSoup (3.7)。
在其他东西中,我看到了一堆'div‘标签,它们有class属性。一些'div‘标签带有多个class属性值。现在我想根据标记名和class属性值进行过滤,例如,我想找到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标记元素操作都会抛出一个异常。
两个问题:
发布于 2018-07-09 04:42:50
我的印象是,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(' ') ]
但是,如果您确实想要使用filter函数,它将如下所示
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)
https://stackoverflow.com/questions/51234758
复制相似问题