如何用BeautifulSoup提取含干扰标签的h2后续段落文本?
问题描述
要构建角色描述与能力数据集,需提取网页中指定h2标签后的段落文本,但网页存在结构干扰:
- h2标签内嵌套class为
mw-headline的span标签 - 部分h2标签后会先出现figure标签,之后才是目标p标签
网页结构示例:
<h2><span class="mw-headline" id="Apariencia">Apariencia</span></h2> <figure class="thumb tleft " style="width: 100px"> <p>...</p> <p>...</p> <p>...</p> <h2><span class="mw-headline" id="Personalidad">Personalidad</span></h2> <p>...</p> <p>...</p> <p>...</p>
原尝试代码(无法实现需求):
import urllib.request from bs4 import BeautifulSoup fp = urllib.request.urlopen("https://jojo.fandom.com/es/wiki/Star_Platinum") mybytes = fp.read() html_doc = mybytes.decode("utf8") fp.close() soup = BeautifulSoup(html_doc, 'html.parser') spans = soup.find_all('span', {"class": "mw-headline"}) for s in spans: print(s.nextSibling.getText)
解决方案
原代码的问题在于:直接取span的nextSibling,而span的父元素是h2,我们需要的是h2标签之后的内容;同时没有处理h2后可能存在的figure干扰元素,也没有收集到下一个h2前的所有p标签。
修正后的代码如下:
import urllib.request from bs4 import BeautifulSoup # 获取网页内容 fp = urllib.request.urlopen("https://jojo.fandom.com/es/wiki/Star_Platinum") html_doc = fp.read().decode("utf8") fp.close() soup = BeautifulSoup(html_doc, 'html.parser') # 找到所有带mw-headline类的span,对应每个目标h2标题 headline_spans = soup.find_all('span', class_="mw-headline") for span in headline_spans: # 获取当前span的父元素h2 current_h2 = span.parent print(f"--- {span.get_text()} ---") # 遍历h2之后的所有兄弟节点 next_sibling = current_h2.next_sibling while next_sibling is not None: # 跳过空白节点和figure标签 if next_sibling.name == 'figure' or (hasattr(next_sibling, 'strip') and next_sibling.strip() == ''): next_sibling = next_sibling.next_sibling continue # 遇到下一个h2就停止遍历 if next_sibling.name == 'h2': break # 如果是p标签,提取文本 if next_sibling.name == 'p': print(next_sibling.get_text(strip=True)) # 移动到下一个兄弟节点 next_sibling = next_sibling.next_sibling print("\n")
代码说明
- 先找到所有
mw-headline类的span,通过parent属性获取对应的h2标签,这才是需要定位的标题节点。 - 遍历h2之后的兄弟节点:
- 跳过空白节点和figure标签,排除干扰。
- 遇到下一个h2标签时停止,避免跨标题收集内容。
- 遇到p标签时提取文本,
get_text(strip=True)可以去除多余的空白字符。
内容的提问来源于stack exchange,提问作者Iván Grzegorczyk
相关产品推荐
相关产品推荐

