如何使用Python提取网页文本且避免句子被换行符拆分
解决方案
方案1:纯HTML解析方案(基于BeautifulSoup,性能更高)
你之前使用BeautifulSoup.get_text()出现句子拆分的核心原因是该方法默认保留HTML源码中的原始换行、空白字符,且没有区分块级元素与行内元素的排版差异。本方案模拟浏览器的文本渲染逻辑,仅在块级元素(如<p>、<h1>、<li>等)之间添加换行,同一块内的所有连续空白统一合并为单个空格,从根源避免句子被中间拆分,同时支持保留<pre>、<code>等标签的原始格式。
示例代码如下:
from bs4 import BeautifulSoup import re # 定义需要保留原始空白格式的标签 PRESERVE_FORMAT_TAGS = {"pre", "code"} # 定义块级标签,仅不同块之间添加换行 BLOCK_TAGS = {"p", "div", "h1", "h2", "h3", "h4", "h5", "h6", "li", "blockquote", "section", "article", "header", "footer", "nav", "aside"} def extract_clean_html_text(html_content): soup = BeautifulSoup(html_content, "html.parser") # 移除所有非内容类标签,避免提取无关内容 for invalid_tag in soup(["script", "style", "meta", "link", "noscript", "iframe"]): invalid_tag.decompose() result = [] for tag in soup.find_all(BLOCK_TAGS): # 跳过嵌套的子块级元素,避免重复提取内容 if tag.find_parent(BLOCK_TAGS): continue # 保留代码块等标签的原始格式 if tag.name in PRESERVE_FORMAT_TAGS: block_text = tag.get_text() else: # 合并同一块内的所有连续空白为单个空格 raw_block_text = tag.get_text(separator=" ", strip=True) block_text = re.sub(r"\s+", " ", raw_block_text).strip() if block_text: result.append(block_text) # 不同块级元素的内容用换行分隔 return "\n".join(result)
方案2:无头浏览器渲染方案(和手动复制效果完全一致)
如果需要和浏览器手动全选复制完全相同的文本效果,或者需要处理动态渲染的页面,可以使用无头浏览器直接获取渲染后的文本,不需要手动处理DOM结构。
示例使用Playwright实现:
from playwright.sync_api import sync_playwright def extract_rendered_page_text(url): with sync_playwright() as p: # 启动无头Chromium浏览器 browser = p.chromium.launch(headless=True) page = browser.new_page() page.goto(url) # 直接获取页面渲染后的innerText,和手动复制效果一致 page_text = page.evaluate("() => document.body.innerText") browser.close() return page_text
使用该方案需要先安装Playwright依赖:执行pip install playwright后,再执行playwright install chromium安装浏览器内核。
内容的提问来源于stack exchange,提问作者Julius Hamilton
相关产品推荐
相关产品推荐

