提取段落文本需先确保html结构合法,避免浏览器自动修复导致p标签错位;用soup.prettify()检查结构,优先选'html.parser'解析器;提取时用.get_text(strip=true)而非.text,并清洗零宽空格等异常字符。

标签本身不是“提取目标”,而是段落语义的容器;真正要提取的是其中的文本内容,且必须先确保 HTML 结构合法、p 标签未被浏览器自动修复或截断。
用 BeautifulSoup 找全 p 标签前先检查结构是否被破坏
浏览器遇到非法嵌套(比如 <p></p>
<div>xxx</div>
<p></p>
<div>xxx</div>
<p></p>,导致你用 soup.find_all('p') 拿到一堆空标签或错位内容。
- 先用
soup.prettify()输出解析后的 HTML,人工扫一眼p是否成对、是否意外中断 - 若原文含
<script></script>或<style></style>内联代码,且未闭合,lxml可能提前终止解析——换用'html.parser'试试 - 确认
p真实存在:打印len(soup.find_all('p')),再对比原始 HTML 中肉眼可见的段落数量
soup.find_all('p') 提取文本时别直接调 .text
.text 会把所有子节点(包括 <strong></strong>、<em></em>、<a></a>)的文本拼成一长串,丢失结构信息,也混入不可见字符(如 、 )。
- 要用
.get_text(strip=True),它默认合并空白符并去除首尾空格 - 如果想保留换行逻辑(比如段内
<br>应转为 ),加参数separator=' ' - 遇到
<p>第一句<strong>加粗</strong>第二句</p>,.get_text()返回 “第一句加粗第二句”,而你可能需要区分强调部分——那就得遍历.children手动处理
中文段落提取后常出现的乱码/空行问题怎么查
不是编码错了,大概率是源 HTML 用了非标准空格或富文本残留符号,比如微信公众号导出的 HTML 常含 <span style="white-space:pre-wrap"></span> 或零宽空格 u200b。
- 提取后做一次清洗:
text.replace('u200b', '').replace(' ', ' ').strip() - 用
repr()打印文本,看是否有异常 Unicode 字符(如'\u3000'全角空格) - 如果每段末尾总多一个空行,检查是否原文用了
<p>xxx</p> <p></p>这种空段落——加过滤:[p for p in soup.find_all('p') if p.get_text(strip=True)]
最易被忽略的一点:很多所谓“段落”其实根本没包 p 标签,比如微信公众号草稿箱直接粘贴的纯文本,会生成一堆 <div> 或 <code><section></section>。这时候靠 find_all('p') 就漏掉了——得先判断父容器结构,再按需 fallback 到 find_all(['p', 'div'], class_=re.compile(r'rich-text|content')) 这类策略。











