如何用Python BeautifulSoup4提取特定标签外的文本内容?
提取特定标签外的无包裹文本(BeautifulSoup4)
问题场景
使用Python 3.8 + BeautifulSoup4,Windows 10环境、PyCharm开发,已能提取<span class="def">和<a class="tdme">内的文本,但需要提取<span>标签后的无包裹文本(如(Région de Mundolsheim, Bas-Rhin))。直接获取外层<li>的文本会包含所有子元素内容,切片方法也不适用。
目标HTML结构:
<ul> <li> <span class="def">Achenheim</span> (Région de Mundolsheim, Bas-Rhin) <ul> <li> <ul> <li> <a class="tdme" href="orgues/achenhei.htm">> St-Georges : Max ROETHINGER, 1962.</a> </li> </ul> </li> </ul> </li> <li> <span class="def">Adamswiller</span> (Région de Drulingen, Bas-Rhin)<ul> <li> <ul> <li> <a class="tdme" href="orgues/adamswpr.htm">> Eglise protestante : George WEGMANN, 1846.</a> </li> </ul> </li> </ul> </li> </ul>
用户原有代码:
from bs4 import BeautifulSoup import requests as requests r = requests.get('url_link') soup = BeautifulSoup(r.content, 'html.parser') regions = soup.select('ul li') for r in regions: print(str(r))
解决方案
方法1:利用next_sibling直接获取span后的文本
通过定位<span class="def">,直接获取其紧邻的兄弟文本节点,再清理空白字符:
from bs4 import BeautifulSoup import requests r = requests.get('url_link') soup = BeautifulSoup(r.content, 'html.parser') # 精准定位包含span.def的外层li(排除嵌套子li) outer_lis = soup.select('ul > li:has(span.def)') for li in outer_lis: # 提取城镇名称 town = li.find('span', class_='def').get_text(strip=True) # 获取span后的无包裹文本,清理多余空格和换行 region = li.find('span', class_='def').next_sibling.strip() # 提取教堂信息,清理多余的>符号和空白 church_info = li.find('a', class_='tdme').get_text(strip=True).lstrip('>') print(f"城镇: {town}") print(f"所属地区: {region}") print(f"教堂详情: {church_info}\n")
方法2:遍历li的子节点筛选文本
如果span后存在多个分散的文本节点,可遍历外层li的所有子节点,筛选出非空白的文本节点:
for li in outer_lis: region_text = "" # 遍历li的所有子节点 for content in li.contents: # 判断是否为纯文本节点,且内容非空白 if isinstance(content, str) and content.strip(): region_text = content.strip() break print(f"所属地区: {region_text}")
关键说明
- 使用
ul > li:has(span.def)选择器可精准定位外层li,避免选中嵌套的子li; next_sibling直接指向span标签后的第一个兄弟节点(即目标文本),适合结构固定的场景;- 遍历
contents的方法兼容性更强,可应对文本节点分散的情况。
内容的提问来源于stack exchange,提问作者Laura
相关产品推荐
相关产品推荐

