html2text是最稳的HTML转文本工具,保留段落结构、处理链接列表,支持-smart script removal和-utf8参数;BeautifulSoup+get_text()更灵活可控;浏览器innerText仅适合临时救急;避免用正则或xml.etree解析不规范HTML。

用 html2text 命令行工具最稳
直接丢掉浏览器右键“另存为文本”这种不可靠操作——它会漏样式、乱码、丢换行。html2text 是专为这事写的,保留段落结构、去掉标签但不破坏语义,连链接和列表都能转成可读文本。
安装后执行:
html2text input.html > output.txt
默认行为已足够干净。如果页面有大量广告或侧边栏,加 -ss(smart script removal)自动过滤 JS 渲染的干扰块;遇到中文乱码,先确认源文件编码是 UTF-8,再加 -utf8 参数强制解码。
-
html2text不解析 CSS,所以不会因为 display:none 就跳过内容 - 对含
<script></script>或的页面,默认会跳过这些块,不用额外清理 - 如果 HTML 来自网页抓取(比如
curl结果),注意响应头里的Content-Type是否带charset=gbk——这时候得先用iconv转码,再喂给html2text
Python 里用 BeautifulSoup + get_text() 更可控
适合需要预处理、删特定区块、或批量处理不同模板的情况。比正则安全,比 html2text 灵活,但得多写几行。
核心就这句:
soup.get_text(separator=' ', strip=True)
其中 separator=' ' 防止段落粘连,strip=True 去首尾空格。如果原文有大量 或
,可以先用 soup.find_all(['script', 'style', 'nav', 'footer']) 批量 .decompose() 掉无关节点。
- 别直接
str(soup)再正则删标签——HTML 嵌套不规则时必翻车 -
get_text()对默认压成一行,要保留表格逻辑得单独遍历
tr/td- 如果页面用了 Web Component 或 Shadow DOM,
BeautifulSoup解析不了,得先用 Puppeteer 渲染出静态 HTML 再处理浏览器控制台临时导出:只适合单次、小页面
不是正经方案,但救急够用。打开开发者工具(F12),在 Console 里粘贴:
document.body.innerText
回车后复制输出——它快,但会把所有样式、JS 动态插入的内容全吞进来,且无法区分标题/段落层级。
- 遇到
innerText返回空?可能是内容由innerHTML插入但未触发渲染,换成textContent - 复制结果里一堆 "\n\n\n"?那是浏览器把 换行当段落了,得手动替换
\n\n+为单个\n- 千万别用
document.documentElement.outerHTML然后正则删标签——嵌套注释、属性值里的会让正则崩别碰
xml.etree.ElementTree解析 HTML它只认标准 XML,而真实 HTML 充斥着自闭合标签(
)、缺失闭合()、大小写混用。一解析就报xxx
yyy
ParseError: mismatched tag或静默丢数据。哪怕你用
html.parser作为ET.XMLParser的底层,也绕不开树构建阶段的容错缺陷。真要用 ET,先用BeautifulSoup把 HTML 规范化成 XHTML,再喂进去——多此一举,不如一步到位用BeautifulSoup。-
lxml.html可以,但它本质是封装了 libxml2 的 HTML 解析器,不是原生 ET - 看到 Stack Overflow 上有人用
ET.fromstring(html)成功,大概率是样本 HTML 刚好规整,换个页面就挂 - 错误信息里出现
unclosed token或expected ',基本就是 ET 在硬刚不规范 HTML
实际转换时,最常被忽略的是编码探测逻辑——
html2text和BeautifulSoup都会优先读,但很多老页面只有 HTTP 头声明,或者 meta 写在 body 里。这时候要么手动指定编码,要么先用chardet探测一遍再传参。 - 千万别用
- 如果页面用了 Web Component 或 Shadow DOM,
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











