如何用BeautifulSoup提取含指定特征嵌套或连续div的元素?
使用BeautifulSoup提取特定div元素的解决方案
翻译后的提问:
我有一段HTML处理代码:
from bs4 import BeautifulSoup html_text = """\ <div id="aa" class="aa"> This I don't want </div> <div id="a a" class="b b"> <div id="cc" class="dd"> This I want </div></div> <div id="aa" class="cc">This I don't want</div>""" soup = BeautifulSoup(html_text, "html.parser")
我希望用BeautifulSoup提取元素:
<div id="a a" class="b b"> <div id="cc" class="dd">
请问有没有语法可以实现以下两种需求?
- 提取包含两个div的元素,其中第一个div的特征为
id="aa" class="bb",第二个div的特征为id="cc" class="dd"。 - 提取包含上述两个连续div的元素(通常用
a > b表示b紧跟在a之后)。
针对你的初始提取目标
要拿到<div id="a a" class="b b">这个元素,有两种简单方法:
# 方法1:直接通过自身属性定位 target_div = soup.find("div", id="a a", class_="b b") # 方法2:通过子元素反向查找父元素 target_div = soup.find("div", id="cc", class_="dd").parent
需求1:提取包含两个指定div的元素
核心是找到同时包含两个特征div的父元素,可通过两种方式实现:
方式一:反向遍历父元素验证
先定位第二个特征div,再遍历它的所有父元素,找到包含第一个特征div的容器:
# 定位第二个目标div child_dd = soup.find("div", id="cc", class_="dd") # 遍历父元素找符合条件的容器 target_parent = None for parent in child_dd.parents: if parent.find("div", id="aa", class_="bb"): target_parent = parent break
方式二:自定义筛选条件查找
用lambda表达式作为筛选条件,直接找到同时包含两个特征div的容器:
target_parent = soup.find( lambda tag: tag.name == "div" and tag.find("div", id="aa", class_="bb") and tag.find("div", id="cc", class_="dd") )
需求2:提取包含两个连续div的元素
你提到的a > b在CSS选择器里是直接子元素关系,但你描述的“b紧跟在a之后”更接近相邻兄弟关系(对应CSS选择器a + b),两种场景分别处理:
场景1:两个div是相邻兄弟(a紧跟b)
先找到符合条件的相邻兄弟对,再取它们的父元素:
# 用CSS相邻兄弟选择器定位第二个div second_div = soup.select_one("div#aa.bb + div#cc.dd") # 获取父元素 target_parent = second_div.parent
场景2:两个div是直接父子(b是a的直接子元素)
直接定位父元素,验证它的直接子元素包含目标div:
target_parent = soup.find( lambda tag: tag.name == "div" and tag.find("div", id="aa", class_="bb") and tag.find("div", id="cc", class_="dd", recursive=False) )
内容的提问来源于stack exchange,提问作者Akira
相关产品推荐
相关产品推荐

