Python中如何用BeautifulSoup提取div标签直接文本(排除嵌套标签内容)
问题核心原因
你当前遇到的提取问题本质来自两点:
- 你之前写的
print(firm)输出的是整个div.b-branches__item节点的HTML源码,本身就会把内部嵌套的<i>、<b>标签和对应内容完整展示出来; - 等你实际提取纯文本时,BeautifulSoup默认的文本提取逻辑会递归读取目标节点下所有子孙标签的内容——也就是不管是div直接挂载的纯文本,还是藏在内部嵌套标签里的文本,都会被一并抓取,自然会把
<i><b>里的"Firm"也带出来,不符合你只取div直接挂载文本的需求。
可行的精准提取方案
方案1:遍历直接子节点筛选纯文本(推荐,不修改原soup结构)
这个方法稳定性最高,全程不会改动你加载好的soup对象结构,也天然不会读到嵌套标签内部的内容:
from bs4 import NavigableString for i in section: firm = i.find('div', class_='b-branches__item') # children属性仅返回div第一层直接子节点,不递归进入内部嵌套标签 # 筛选出类型为纯文本的节点,过滤掉多余空白后拼接 target_text = ''.join( child.strip() for child in firm.children if isinstance(child, NavigableString) and child.strip() ) print(target_text)
运行后输出就只会是你要的RJT Roadlines,完全不会包含嵌套标签里的"Firm"内容。
该方法不受内部嵌套标签的结构、数量影响,只要目标文本是直接挂载在目标div下的,就能准确提取,不会因为后续页面结构小改动就失效。
方案2:先移除不需要的嵌套标签再提取文本(适合不需要复用原soup结构的场景)
如果后续不会再用到soup中被嵌套标签包裹的内容,可以先把这些不需要的标签从DOM树中移除,再抓剩余的纯文本:
for i in section: firm = i.find('div', class_='b-branches__item') # 移除div内部所有的i、b嵌套标签 for nested_tag in firm.find_all(['i', 'b']): nested_tag.decompose() target_text = firm.get_text(strip=True) print(target_text)
注意:这个decompose()操作会直接永久修改原soup的节点结构,如果后续还要读取这些被删掉的嵌套标签内容,就不能使用这个方法。
常见误区提醒
不要依赖正则表达式从原始HTML字符串中硬抠目标内容——只要HTML的标签顺序、属性发生小幅变动,正则的匹配逻辑就会失效,远不如BeautifulSoup原生的节点遍历逻辑稳定可靠。
内容的提问来源于stack exchange,提问作者Jatin Sehra
相关产品推荐
相关产品推荐

