我正在使用bs4从js-stream-item类中提取li标签,但不包含下面的scroll-bump-user-card。 (只有a,b)
<li class="js-stream-item stream-item ">a<li>
<li class="js-stream-item stream-item stream-item ">b<li>
<li class="js-stream-item stream-item scroll-bump-user-card ">c<li>
我想到的方法有两种。
使用soup.find_all('li', class_=re.compile('js-stream-item'))
获取所有代码,然后使用scroll-bump-user-card删除代码。
首先使用[tag.extract() for tag in soup.find_all('li', class_=re.compile('scroll-bump-user-card'))]
删除,然后查找所有内容。
问题是,如果通过在re.compile()
中使用AND NOT语法编辑正则表达式来获得a,b是一种不错的方法。
更新我将alecxe答案的第一个选项重新写入一条长行,如下所示:
soup.find_all(lambda tag: re.compile('js-stream-item').search(str(tag))
and not re.compile('scroll-bump-user-card').search(str(tag))
and tag.name == 'li')
答案 0 :(得分:1)
首先,class
是一个特殊的multi-valued attribute,需要special handling。
一种选择是使用searching function并检查是否存在js-stream-item
班级并且缺少scroll-bump-user-card
班级:
def search_function(tag):
if tag.name == "li":
class_ = tag.get("class", [])
return "js-stream-item" in class_ and "scroll-bump-user-card" not in class_
for li in soup.find_all(search_function):
print(li.get_text(strip=True))
另一种选择是查找所有li
个js-stream-item
类,然后跳过li
个scroll-bump-user-card
类的元素:
for li in soup.select("li.js-stream-item"):
if "scroll-bump-user-card" in li["class"]:
continue
print(li.get_text(strip=True))
另一个,检查class
是否以stream-item
CSS selector结尾(不要使用此内容):
for li in soup.select("li[class$=' stream-item ']"):
print(li.get_text(strip=True))
请注意,此用例的更好的CSS选择器是:
li.js-stream-item:not(.scroll-bump-user-card)
但由于BeautifulSoup
中的CSS选择器支持有限,它无法正常工作。