html2text最稳,适合批量处理;turndown适合前端定制但已停更;pandoc高保真但丢样式;在线工具仅限临时救急。批量转HTML到Markdown首选html2text,需加-b 0、-g、--unicode-snob等参数避坑。

直接用 html2text 命令行工具最稳,不依赖浏览器、批量处理可靠、中文支持好;turndown 适合前端实时转换或 Node.js 深度定制,但已停止维护;pandoc 高保真但忽略样式和 class;在线工具只适合临时救急,敏感内容别传。
用 html2text 批量转 HTML 到 Markdown 最省心
它默认就干对了大部分事:把 <h2> 变成 ##,<ul><li> 变成 -,<strong> 变成 **,还自动过滤 <script> 和 <style>。但默认行为有几个坑:
-
bodywidth默认是 79,会强行折行,导致段落里莫名其妙断开——加-b 0关掉它 - 表格默认输出 ASCII 表格(难读),加
-g启用 GitHub 兼容模式才能生成标准 Markdown 表格(前提是原 HTML 表格结构规整) - 中文引号、破折号会被转成英文符号,加
--unicode-snob保留原样 - 图片默认只留
![alt](),路径丢了——得配合--image-urls或提前用脚本重写src
批量处理一行搞定:for f in *.html; do html2text -g --unicode-snob -b 0 "$f" > "${f%.html}.md"; done
turndown 在浏览器里转 HTML 字符串要绕过几个雷
它轻、快、能配规则,但 2022 年后就没更新了,部分新标签(比如 <details>)不识别,自定义标签容易崩。常见翻车点:
立即学习“前端免费学习笔记(深入)”;
- 默认用
setext风格标题(===下划线),但 GitHub 不渲染多级setext——显式设{ headingStyle: 'atx' } -
<a href="foo.html">link</a>默认输出[link](foo.html),但若页面在子路径下,相对链接就失效——得加baseUrl选项补全 - 遇到
<div class="warning">...这类语义容器,它直接丢掉,不会映射成 callout——得手写addRule处理,例如把class="note"转成> [!note]\n> ... - 不处理内联样式,
style="color:red"里的 red 不会变成文字颜色,也不会报错,静默丢弃
基础用法:
const turndownService = new TurndownService({ headingStyle: 'atx' });<br>const md = turndownService.turndown(htmlString);
输入文章 URL,返回干净 Markdown。支持17个平台(头条、微信公众号、知乎、36kr、虎嗅、华尔街见闻、澎湃、InfoQ 等)专项优化,双引擎提取、图片本地化、三层抓取策略。常与 browser‑web‑search skill配合:先用 bws 搜索获取 url 列表,再逐篇调用本 skill 提取正文。
pandoc 转换后发现样式没了?这本来就是设计如此
pandoc 的定位是“语义转换器”,不是“样式搬运工”。它能精准还原嵌套列表、复杂表格(只要没 colspan)、数学公式(配合 MathML),但所有视觉信息都会被剥离:
-
class="highlight"、id="section-2"、style="margin-left:2em"全部消失,不警告也不留注释 -
<img src="a.jpg" alt="desc" width="200">只剩,尺寸、title、loading 属性全丢 - 如果 HTML 里有
<script>fetch(...) </script>渲染出的内容,pandoc看不到——它只吃静态 HTML 字符串 - 表格头行必须存在且完整,
<table><tr><td>A</td></tr></table>这种无表头的,会转成空表或报错,得先用脚本补<thead>
命令示例:pandoc input.html -f html -t markdown_strict -o output.md(markdown_strict 禁用 GFM 扩展,更接近标准)
为什么别信“一键在线转换”?真实风险在这儿
像 html-to-md.net 或 cloudconvert.com 这类服务,背后调的是简化版解析器,上传即公开,且不可控:
- 图片资源路径全被清空,
<img src="/assets/logo.png">变成![](),本地路径无法恢复 -
<blockquote class="twitter-tweet">这类嵌入内容,直接转成空段落,原始语义完全丢失 - 中文段落间可能多出空行,因为服务端用了不同换行策略,又不提供参数调整入口
- 上传含 API key 或内部链接的 HTML,等于主动泄露——没有隐私条款保障,日志也查不到
临时救急可以,但只要涉及批量、工程化、或含敏感信息,就得切回本地工具链。
真正难的从来不是“怎么转”,而是“转完之后要不要人工校验”。表格结构、图片路径、自定义容器语义、跨文档引用——这些都得靠人眼盯。工具只负责把 80% 的机械活干掉,剩下 20% 是没法自动化的。


















