如何用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
相关产品推荐
相关产品推荐

