如何用BeautifulSoup提取网页#text内容及完整连贯文本?
网页文本爬取问题(BeautifulSoup)
- 无法提取示例HTML中
<a>标签内的「Previous」这类直接文本内容 - 实际爬取时仅能获取
<strong>标签内的粗体文本,希望提取包含<strong>前后内容的完整连贯句子
相关HTML结构
<a href="https://eltlearningjourneys.com/2015/05/12/5-different-english-classes/" rel="prev"> <span class="meta-nav">←</span> Previous </a>
爬取代码
from bs4 import BeautifulSoup import nltk html = """ <a href="https://eltlearningjourneys.com/2015/05/12/5-different- english-classes/" rel="prev"> <span class="meta-nav">←</span> Previous </a> """ soup = BeautifulSoup(html, "html.parser") # 定义可见元素的CSS选择器列表 visible_selectors = ['p', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'td', 'th', 'label', 'button', 'a', 'small', 'strong', 'em', 'blockquote', 'div[role="article"]', '#text'] # 查找所有匹配选择器且包含可见文本的元素 elements = [] for selector in visible_selectors: elements += soup.select(selector + ':not([class*="hidden"]):not([style*="display:none"])') for element in elements: # 获取元素内的可见文本 visible_text = ' '.join(element.text.split()) # 拆分句子 sentences = nltk.sent_tokenize(visible_text) for sentence in sentences: if sentence == "" or sentence is None: continue else: print(sentence)
解决方案
问题1:提取<a>标签内的直接文本
代码中使用#text作为CSS选择器是错误的,BeautifulSoup的CSS选择器不支持匹配文本节点。同时,你同时选中了<a>和它的子标签<span>,导致重复输出内容。
两种解决方式:
- 调整选择器列表:移除
#text和span,避免同时抓取父元素和子元素。修改后的选择器列表如下:
visible_selectors = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'td', 'th', 'label', 'button', 'a', 'small', 'strong', 'em', 'blockquote', 'div[role="article"]']
此时抓取<a>元素后,element.text会得到包含←和Previous的完整文本,再通过' '.join(element.text.split())处理空格即可。
- 单独提取
<a>内的直接文本:如果只想拿到<a>里排除子标签的纯文本,可遍历<a>的子节点,筛选出文本节点:
a_tag = soup.find('a', rel='prev') direct_text = ' '.join([node.strip() for node in a_tag.children if isinstance(node, str) and node.strip()]) print(direct_text) # 输出: Previous
问题2:提取包含<strong>的完整句子
当前代码单独抓取<strong>元素,导致只输出粗体内容。正确做法是抓取包含<strong>的上层容器(比如<p>、<div>等),而不是单独抓<strong>。
修改方式:
- 从选择器列表中移除
strong,改为抓取包含strong的父元素(如p)。例如HTML结构为<p>这是<strong>重要的</strong>完整句子。</p>时,抓取<p>元素后,p.text会输出完整的「这是重要的完整句子。」,而非单独的「重要的」。
内容的提问来源于stack exchange,提问作者keybe
相关产品推荐
相关产品推荐

