get_text()默认保留原始换行与空格,不自动清理;需用strip=True和separator=' '组合实现干净文本提取,对pre/code等特殊标签需单独处理。

get_text() 默认保留原始换行,不是“提取干净文本”
调用 get_text() 不加参数时,它不会帮你清理空格或换行——而是照搬 HTML 中的文本节点结构。比如两个 <p></p> 标签之间有换行符,get_text() 就会输出 \n\n;<div> 里手动敲了四个空格,也会原样保留。
<p>这不是 bug,是设计使然:它只做“提取”,不做“格式化”。想得到统一空白的文本,必须显式控制参数。</p>
<ul>
<li>
<code>strip=False(默认)→ 每段文本首尾的空白、换行全保留
separator=''(默认)→ 相邻文本节点直接拼接,可能造成“第一段第二段”这种粘连<span><em>文字</em></span> 可能带出多个 \n 或 \t用 separator + strip 组合解决 90% 的空白混乱
最常用且稳定的组合是:get_text(separator=' ', strip=True)。它做了两件事:把不同标签之间的文本用空格隔开,同时清除每段内部首尾的换行/制表符。
这个组合适合大多数网页正文提取场景,比如新闻、博客、产品描述。它不会强行抹掉语义换行(如段落之间),但会把因 HTML 缩进、换行导致的多余空白压平。
立即学习“前端免费学习笔记(深入)”;
- 若原文本是
<p>\n 第一段\n</p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/xiazai/skill9972" title="Wechat Article Html"><img src="https://img.php.cn/upload/skill/001/246/273/6adaf20e695c2374.jpg" alt="Wechat Article Html" ></a> <div class="aritcle_card_info flexColumn"> <a href="/xiazai/skill9972" title="Wechat Article Html">Wechat Article Html</a> <p>将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。</p> </div> <a href="/xiazai/skill9972" title="Wechat Article Html" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div> <p> 第二段 \n</p>,输出为"第一段 第二段" - 若需要保留段落分隔,改用
separator='\n',再配合strip=True防止每行前后多出空格 - 避免用
separator=''处理中文——容易把“你好世界”变成“你好世界”,中间缺空格反而难读
遇到 pre、code、textarea 里的原始缩进怎么办?
这些标签在 HTML 解析阶段就受浏览器保护,其内部空白不会被折叠。但 get_text() 仍会把它们当普通文本节点提取,导致大量空格、制表符混入最终结果。
如果你的目标是“统一空白格式”,这类内容通常需要单独处理——要么跳过,要么用正则后置清洗。
- 先用
soup.find_all(['pre', 'code', 'textarea'])找出这些块,临时替换为占位符(如'[CODE_BLOCK]') - 再对剩余部分调用
get_text(separator=' ', strip=True) - 最后用
re.sub(r'\s+', ' ', text)全局压缩连续空白(慎用,会破坏 pre 块语义) - 注意:
white-space: pre这类 CSS 声明对get_text()无效——它不读样式,只读 DOM 结构
为什么不用正则删标签再处理空白?
用 re.sub(r']+>', '', html) 看似简单,但实际踩坑率极高:实体字符(如 &)、注释、script/style 内容、不闭合标签都会导致错乱。而 get_text() 是基于解析器的 DOM 遍历,天然兼容 malformed HTML。
真正要警惕的是“混合方案”:比如先用正则粗筛,再用 get_text() 提取——这会让原本已修复的结构再次暴露在正则风险中。
- 如果必须用正则,仅限于已知格式极简的字符串(如邮件模板片段),且务必加上
re.DOTALL - 所有含 JavaScript 渲染、动态插入内容的页面,正则基本失效,只能靠真实 DOM 解析(如 Selenium)
-
get_text()的types参数可过滤掉注释节点(Comment),比正则更精准
真正难处理的,是那些既要用 pre 保留格式、又要在同一页面里提取“干净正文”的混合场景——这时候得按语义分区处理,不能指望一个参数通吃。


















