You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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">&gt;
                                                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">&gt;
                                                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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 18:15:45