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

如何用Beautiful Soup从含子标签的元素中提取目标文本?

问题

如何用Beautiful Soup从包含多个子标签的元素里提取目标文本?我尝试抓取各国人口数据,但存储人口的标签包含多个子标签,用soup.table.tr.string返回的是None,能不能提取出像1.411.750.000 (2022)这样的目标文本?

待解析的HTML片段:

<td>
 1.411.750.000 (2022)
 <small>
  (<a href="/wiki/xxx" title="xxx">1.</a>)
 </small>
 <sup class="reference" id="cite_ref-2">
  <a href="#cite_note-2">[2]</a>
 </sup>
</td>

我的Python代码:

import requests
from bs4 import BeautifulSoup

r = requests.get('https://example.com/country-fishery-list')
s = BeautifulSoup(r.content, 'html.parser')

for i in s.find_all('td'):
    if i.a:
        tr = requests.get(f"https://example.com{i.a.get('href')}")   
        ts = BeautifulSoup(tr.content, 'html.parser')

        print(f"https://example.com{i.a.get('href')}:")
        for j in ts.table.find_all('tr'):
            if j.td.b:
                if "Einwohnerzahl" in j.td.b:
                    print("population: ", j.find_all('td')[1].string)
                    break
解决方法

当元素包含多个子标签时,.string会返回None,因为该元素有多个子节点,无法直接返回单一字符串。可以用以下几种方法提取目标文本:

1. 用.stripped_strings提取第一个有效文本

.stripped_strings会迭代返回元素下所有非空白的文本片段,取第一个就是目标内容:

target_td = j.find_all('td')[1]
population = next(target_td.stripped_strings)

2. 直接获取第一个文本子节点

通过.contents筛选出标签下的纯文本节点,取第一个非空白的:

target_td = j.find_all('td')[1]
population = [text.strip() for text in target_td.contents if isinstance(text, str) and text.strip()][0]

3. 用.get_text()配合正则提取

先获取所有文本,再用正则匹配出目标格式的内容:

import re
target_td = j.find_all('td')[1]
full_text = target_td.get_text(strip=True)
population = re.match(r'[\d\.]+\s+\(\d{4}\)', full_text).group().strip()

修改后的完整代码

import requests
from bs4 import BeautifulSoup

r = requests.get('https://example.com/country-fishery-list')
s = BeautifulSoup(r.content, 'html.parser')

for i in s.find_all('td'):
    if i.a:
        country_url = f"https://example.com{i.a.get('href')}"
        tr = requests.get(country_url)   
        ts = BeautifulSoup(tr.content, 'html.parser')

        print(f"{country_url}:")
        for j in ts.table.find_all('tr'):
            if j.td and j.td.b and "Einwohnerzahl" in j.td.b.get_text():
                target_td = j.find_all('td')[1]
                # 使用stripped_strings方法提取
                population = next(target_td.stripped_strings)
                print("population: ", population)
                break

内容的提问来源于stack exchange,提问作者Push

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:13:17