DevTool 團隊

網頁正文提取為 Markdown:HTML 轉換的場景與規則

為什麼要手動把網頁內容變成 Markdown?這篇講清 HTML 轉 Markdown 的三類真實場景(筆記歸檔、部落格遷移、餵給大語言模型的乾淨素材),以及轉換器的核心規則:標題與強調怎麼映射、嵌套列表的縮排與有序起始號、GFM 表格的對齊、程式碼塊的語言提取與圍欄升級、語法字元為什麼要按位置轉義。附線上工具與 Markdown 生態的搭配用法。

為什麼要把網頁內容變成 Markdown

三個場景撐起了 HTML 轉 Markdown 的真實需求:

  1. 筆記歸檔:讀到好文章想存進 Obsidian/Notion——這些工具的「貼上網頁」常丟格式或帶進廣告雜質,複製 HTML 原始碼再轉 Markdown 是最乾淨的路徑
  2. 部落格遷移:老站是 HTML 輸出(WordPress 主題、手寫頁面),遷到 Hugo/Hexo/Astro 這類 Markdown 驅動的靜態部落格,逐篇轉格式是必經之路
  3. 大語言模型的素材整理:把網頁餵給模型做摘要/翻譯/改寫時,去掉導覽列頁尾殘渣的純 Markdown 上下文最省 token、噪音最低

三個場景的共同點:要結構與正文,不要樣式與雜質——這正是轉換規則設計的出發點。

核心規則一:結構與強調的映射

直譯的部分沒有爭議:h1-h6 映射 #-######,strong 映射 **,em 映射 *,行內 code 用反引號。有意思的是邊界:

  • 包裝標籤透傳:div/section/span 這類純容器在 Markdown 裡沒有對應物,只保留內部內容
  • script/iframe/表單丟棄:互動元素在 Markdown 裡無處安放,安全上也不該保留
  • 行內樣式全丟:Markdown 哲學是內容與表現分離,顏色字號這類資訊注定丟失

核心規則二:列表的深度還原

列表是最容易轉壞的結構。要點有三個:

  • 嵌套縮排:子列表按兩空格縮排逐層展開,亂一層整棵樹就散架
  • 有序起始號:<ol start="5"> 要輸出 5. 開頭——編號是內容語義,丟了就錯
  • 任務列表:列表項首位是 checkbox 時轉 - [x]/- [ ](GFM 擴充),藏在段落裡的 checkbox 則按表單元素丟棄

核心規則三:表格與程式碼塊

表格走 GFM 擴充:表頭行 + 對齊分隔行 + 資料行,對齊從 HTML 的 align 屬性映射(:---/:---:/---:)。要誠實的是:現代網頁的對齊多寫在 CSS class 裡,能映射到的對齊是少數——「表格結構保留」是確定的,「視覺對齊保留」不承諾。

程式碼塊有兩條:從 language-xxx class 提取語言標註圍欄(```python);圍欄升級——內容本身含三反引號時(比如這篇網頁就是在講 Markdown 語法),外層圍欄自動升到四反引號,否則程式碼塊在半途被截斷。

核心規則四:轉義——保住「渲染結果與原文一致」

這是最容易被輕視、卻決定輸出品質的一環。文字裡恰好出現 *、_、[、行首 # 或 - 時,不轉義就會意外變成強調/連結/標題/列表。規則按位置判斷:

場景 處理
文字中的 * [ 前加反斜線
snake_case 詞中間的 _ 保留(前後是字母數字時不是強調語法)
行首的 # - 1. 轉義,防止變標題/列表
表格儲存格內的 | 轉義,防止拆列
pre/code 內容 一律不轉義(它就該是字面量)

工具與生態的搭配

HTML 轉 Markdown 轉換器把上述規則做全:貼上原始碼即時轉換,列表符號/強調風格/保留圖片/GFM 表格四個開關適配目標編輯器慣例。轉換結果想預覽渲染效果,用 Markdown 線上預覽反方向核對;README 類文件的預覽工作流見這篇指南。程式化批次場景再用 markdownify/turndown 這類庫——一次性任務,貼上即得的線上工具成本最低。

常見問題

HTML 轉 Markdown 的過程中會丟失什麼?

四類:行內樣式與 class/id(Markdown 沒有對應語法);合併儲存格與儲存格內嵌套結構(GFM 表格不支援);script/iframe/表單控制元件等互動元素(安全與語法雙重不支援);CSS 驅動的視覺資訊(對齊多寫在 class 裡,只有 HTML align 屬性的對齊能映射)。結構與文字內容是保住的——這正是「素材整理」場景需要的。

轉 Markdown 時底線和星號為什麼要轉義?

Markdown 把 * 與 _ 當強調語法、把 [ ] 當連結語法、行首的 # 與 - 當標題與列表——文字裡恰好出現這些字元時會意外改變渲染結果(snake_case 變斜體、行首數字加點變列表)。轉換器按位置轉義:詞中間的底線保留、行首語法字元加反斜線、表格儲存格裡的豎線轉義——保住「渲染結果與原文一致」這個第一原則。

程式碼塊裡的三個反引號怎麼處理?

圍欄升級:內容本身包含 ``` 時,外層圍欄自動升到四反引號或更長,直到不再與內容衝突——這也是 CommonMark 的標準做法。行內程式碼同理,內容含反引號時用雙反引號包裹。轉換 Markdown 教學類網頁(程式碼塊裡就是反引號語法)時這條規則是剛需。

有哪些程式設計庫可以做同樣的轉換?

Python 生態的 markdownify 與 html2text(命令列可獨立用)、BeautifulSoup4 自寫遍歷;JavaScript/Node 的 turndown(瀏覽器與 Node 雙端)與 unified 生態的 rehype-remark 管線;各靜態部落格框架(Hugo/Hexo)的匯入器內部也是這類庫。線上工具的優勢是零環境成本:貼上即得,適合一次性或低頻任務。