最受歡迎的 HTML 轉 Markdown 函式庫,竟然不會轉表格

最後更新於 August 17, 2026
最受歡迎的 HTML 轉 Markdown 函式庫,竟然不會轉表格
AI 摘要
在這份 metadata 截圖中,turndown 是四個受測函式庫裡 GitHub stars 最多的一個,擁有 11,386 顆星。針對四個共用的 HTML 測試樣本,它在核心預設設定下產生了 0 個 Markdown 表格,而且對相同輸入使用的 token 數量比 markdownify 多出 24.6%。四個工具都完整保住了每一個內容探針。差別完全在於結構如何被處理,以及這些結構在後續流程中的成本。若是要把內容餵給模型,或儲存這類頁面的結構化資料,先從 markdownify 開始。它在這個計數器下的表格列數與 markitdown 打平,token 數落在最低的一群,授權是 MIT,安裝大小只有 1.8 MiB。

在這份 metadata 截圖中,turndown 是四個受測函式庫裡 GitHub stars 最多的一個,擁有 11,386 顆星。針對四個共用的 HTML 測試樣本,它在核心預設設定下產生了 0 個 Markdown 表格,而且在相同輸入下,使用的 token 數量比 markdownify 多出 24.6%

四個工具都完整保住了所有內容探針。差別完全在於結構被如何處理,以及這些結構在後續流程中會帶來多少成本。

測試了什麼,以及使用了哪些樣本

這份研究基礎原本就有一組針對 markitdown 的測試包,包含五個 HTML 樣本與預先註冊的探針字串——也就是會逐字檢查是否存活的精確字串,另外還有用來辨識頁面雜訊的 boilerplate 字串。整體比較採用的是四個所有四款轉換器都共同使用的樣本:書店型錄、引言網站、冰球統計表,以及 Wikipedia 上關於網頁爬蟲的文章。第五個樣本 Nothing but tables 只作為偏重表格的診斷用,不納入 24.6% 的總體統計。

四個工具分別是:turndown 7.2.4(Node)、markdownify 1.2.3、html2text 2025.4.15,以及 markitdown,後者直接使用其已公開的數據列。頁面包含:書店型錄、引言網站、冰球統計表,以及 Wikipedia 的網頁爬蟲條目。

下方每個指標名稱都與 markitdown 自己的產物欄位一一對應,因此這些列可以直接並排比較,不需要把兩種不同定義硬湊成同一個詞。

表格

Measured results chart: Token output vs Markdown table rows

轉換器內容探針輸出字元數Token 數量 (o200k)每 token 字節數Markdown 表格列數連結數
turndown16/1695,18826,2363.630611
markdownify16/1676,86821,0623.6536599
html2text16/1676,45221,1763.6132545
markitdown16/1676,99521,3363.6136598

四個樣本——也就是 markitdown 也有跑的那四個。各樣本完整數據可見 fiveway-scores.json。Token 使用 o200k_base 計算;markitdown 的表格列數則是從其自己儲存的 Markdown 重新統計,使用與其他工具相同的計數器。

內容保留打成平手。 四個樣本中共 16 個 body 探針,全部都在每個轉換器的輸出中保留下來。如果你只在意「文字會不會過去」,這四個答案都是會。

結構保留並不是平手。 在這四個共用樣本中,markdownify 與 markitdown 都輸出 36 行 Markdown 表格列;html2text 輸出 32 行;turndown 則是 0 行。至於獨立的「全表格」診斷樣本,markdownify 輸出 62 行、html2text 輸出 59 行;這些列數不納入上面的總計。

turndown 的 token 成本高出 24.6%,而且原因不是表格。我原本以為是表格造成的,但逐樣本數據說明並非如此——如下所示。

turndown 對表格做了什麼

以下是冰球統計樣本,同樣的資料列,三種呈現方式。

turndown:

System diagram: Core Table Paths Diverge

Team Name

Year

Wins

Losses

Boston Bruins

1990

44

24

markdownify:

| Team Name | Year | Wins | Losses | ... |
| --- | --- | --- | --- | --- |
| Boston Bruins | 1990 | 44 | 24 | ... |

html2text:

Team Name  |  Year  |  Wins  |  Losses  | ...
---|---|---|---|---
Boston Bruins  |  1990  |  44  |  24  | ...

turndown 的轉換沒有把任何數值弄丟,所以它在探針上可以拿到 16/16。真正沒有留下來的是每個數值對應哪一欄。如果直接看 turndown 的輸出,44 只是一個孤零零的數字;你無法知道它是 Boston 的勝場數,除非自己去數位置,還得祈禱中間沒有空白儲存格。這個樣本裡偏偏就有空白儲存格,所以光靠數位置也行不通。

對模型來說,這代表的是:它看到的是一個可以回答問題的表格,還是只會猜測的一串數字。

這不算是 bug,比較像是已知的設計邊界——turndown 核心本來就不處理表格,而 turndown-plugin-gfm 就是用來補上這個功能的。不過預設安裝並不包含這個插件,而 11,386 顆星也表示很多人確實是直接用預設版。

token 差距真正從哪裡來

我上面那段話原本寫得很肯定,認為 24.6% 的 token 差距是因為表格被攤平成文字。後來我改成逐樣本檢查,結果不是。

樣本turndown tokens ÷ markdownify tokens
引言網站(沒有表格)0.99×
書店型錄1.06×
冰球統計(單一大型表格)1.37×
Wikipedia(以散文為主,含 9 行表格)1.29×
全表格樣本0.78×

在那個全都是表格的樣本裡,turndown 反而便宜 22%——因為 Markdown 的 pipe 骨架本身也會吃 token,而 turndown 完全不會輸出這些東西。單純把表格攤平,並不必然代表 token 成本更高。

Wikipedia 那個樣本佔整體的 74%,而且只有 9 行表格。它那 15,378 個字元的差距不可能是表格造成的。真正的原因是這些內容:

(function(){var className="client-js vector-feature-language-in-header-enabled…
.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}…
(RLQ=window.RLQ||[]).push(function(){mw.config.set({"wgHostname":"mw-web…

turndown 不會移除 <script><style> 內容,但 markdownify 與 html2text 會。 以只會出現在這些元素中的標記來統計:turndown 的輸出在各樣本中帶有 10 個 script 標記和 84 個 style 標記;另外兩個工具兩者都為 0。在 Wikipedia 頁面上,MediaWiki 內嵌的 JavaScript 設定與 CSS 共 8 行,就佔了 14,644 個字元——也就是整體差距的 95% (script-style-stripping.json)。

這才是我真正在意、也真的會採取行動的結論。攤平表格是你看得見的結構問題;但 Markdown 裡混進一大段 JavaScript 設定,則是毫無資訊、純粹浪費的成本,而在真實世界頁面上,它帶來的負擔遠遠超過這次比較中的其他因素。

html2text 會輸出你一開始可能認不出來的表格

html2text 的表格列數是 32,低於 markdownify 和 markitdown 的 36,而我一開始的計數器只算出 1

問題不在函式庫,而在我的計數規則。html2text 會輸出 Team Name | Year | Wins 但沒有前後的管線符號——這是常見的 Markdown 表格形式,只是用要求 ^\|.*\|$ 的 regex 是看不出來的。我當時就是這樣寫 regex、這樣跑,還差點直接報告 html2text 不支援表格。

其實它有。修正後的計數器改用一個啟發式:一串連續包含 pipe 的行,中間夾著一行分隔列。用這個規則,html2text 的表格列數就從 1 變成 32。這不是完整的 Markdown parser,因此這些列數應該被解讀為「在有記錄的計數器下量到的結果」,而不是絕對的渲染真理。

如果你會用自己的 regex 去後處理 Markdown,這件事很值得記住:這四個函式庫裡,有兩個會輸出外層 pipe,有一個不會。

很少人提到的授權問題

轉換器授權安裝內容冷啟動匯入Stars最後發布
turndownMIT3 個 npm 套件,8.8 MiB0.056 s11,3862026-04-03
markdownifyMIT5 個套件,1.8 MiB0.046 s2,2352026-06-30
html2textGPL-3.0-or-later1 個套件,0.2 MiB0.077 s2,1682025-04-15
markitdown依其套件 metadata 為準本次安裝未測量未測量

install-and-import.json。每個函式庫都安裝在自己獨立的空白環境中。授權資訊分別從三個地方確認:registry metadata、GitHub repo,以及已安裝套件自己的 METADATA 檔,其中寫著 License-Expression: GPL-3.0-or-later

在這份安裝比較裡最輕量的函式庫——1 個套件、0.2 MiB——是 GPL-3.0-or-later。這會不會影響專案,要看軟體如何組合與散布。把它當成授權負責人需要確認的選擇節點就好;本文不是法律意見。markitdown 在這裡顯示為未測量,是因為這份產物沒有捕捉到它的安裝與授權資訊。

這種取捨很容易被忽略,因為授權是 benchmark 裡看不見的屬性。

不過,這三者都比同類別中的文章擷取器輕得多——那些通常會落在 21 到 70 MiB。轉換器本來就比擷取器小很多,依賴預算要把兩者分開看。

在這張表成立之前,我必須先修正兩個混淆因子

上面的數字其實已經是第三版。前兩版有問題,而且那兩個問題都很容易重現。

五個樣本對四個樣本。 markitdown 只跑了這五個檔案中的四個,另外三個工具則全跑五個。把每個工具自己的測試集加總,會得到 markdownify 98 行表格列、markitdown 36 行,看起來像是能力差距。若只看相同的四個樣本,則是 36 對 36——完全平手。第五個樣本偏偏就是表格最多的那個,因此這個混淆會往最糟的方向偏移,讓新進工具看起來比既有工具多出將近三倍。

System diagram: Make the Comparison Comparable

兩個計數器,一個欄位。 markitdown 公開的 md_table_rows 是來自它自己的程式碼,而我當時還沒讀過。拿那個數字去跟我的計數器比,可能是在比較兩個計數方式,而不是兩個轉換器。它的 Markdown 輸出有存到磁碟,因此修正方式就是用同一個計數器跑完四個樣本——而當我這麼做後,markitdown 的重算結果與它公開的每個樣本數值完全一致(0、0、27、9)。定義是一致的;只是我一開始不查就不會知道。

這兩個錯誤都不會從輸出表面看出來,但都會產生一張看似很有把握、其實完全錯誤的表格。

誰適合用哪一個

你要把頁面內容餵給模型,或是儲存像這類頁面的結構化內容? 先從 markdownify 開始。它在這個計數器下的表格列數與 markitdown 打平,token 數也落在最低的一群,授權是 MIT,安裝體積只有 1.8 MiB。先用你自己的頁面形狀驗證,再決定要不要標準化。

你的依賴預算是以 KB 計,且不需要對外散布? 選 html2text。1 個套件、0.2 MiB,表格也還在。先確認 GPL 相關問題,另外也要注意它的最後發布時間是 2025 年 4 月。

你本來就在 Node 技術棧裡? 那就用 turndown,並搭配 turndown-plugin-gfm;但在交給它之前,先把 HTML 裡的 <script><style> 移除,因為 turndown 不會幫你做。這兩個缺口會讓 token 多出四分之一,也會讓你的表格結構直接消失,而且在看輸出之前你根本不會知道。

你原本就會轉其他文件格式? markitdown 也能處理 PDF、Office 等格式,而它的 HTML 輸出與專門的轉換器相比也很有競爭力。少一個依賴,就值得考慮。

代管 API 的位置在哪裡

上面這四個工具都只處理你已經拿到的 HTML。它們不會幫你抓頁面、不會渲染 JavaScript,也不會處理反機器人層;而對很多真實目標來說,真正更難的其實是後半段。

我們在 Thunderbit 的開發者工具鏈就是負責這一段。POST /distill 接收一個 URL,會回傳乾淨、適合 LLM 使用的 Markdown,抓取與渲染都已處理好;POST /extract 則會依照你提供的 JSON Schema,回傳 AI 對齊的結構化 JSON,輸出形狀又不同了——是列資料,而不是你之後還得自己解析的 Markdown 表格。這兩個功能都可透過 MCP server 與 CLI(npx @thunderbit/thunderbit-cli)使用。價格可見 Thunderbit 定價頁

比較務實的說法是:如果你手上已經有 HTML,而且只是想轉成 Markdown,那 markdownify 免費、表現也很好,而這張表也告訴你它的競品中還有哪些同樣適合。如果你要的是抓頁面,或是結構化列資料而不是散文,那就是另一種採購決策了。

若你想看更完整的領域整理,我們的 web scraping API 總覽 介紹了代管方案,而 開源爬蟲主文 則涵蓋自架式工具。用 Python 把 HTML 轉成 Markdown 是實作導讀,而 llms.txt 想標準化的是什麼 則說明了這個類別的下一步走向。

免費試用 Thunderbit 網頁資料擷取

結論

就這個四樣本工作負載來說,markdownify 是最強的預設選擇:在共用計數器下,它的表格列數與 markitdown 打平,token 數與其他高效率轉換器相比也只差 1.3% 以內,授權是 MIT,安裝大小只有 1.8 MiB。

這個「受歡迎程度」和「實際表現」之間的落差,才是這篇文章真正的重點。turndown 是個很棒的函式庫,很多人都已經安裝,但沒有搭配能處理表格的插件;這個缺口會反映成多出四分之一的 token,以及一個不再存在的表格結構。在你真的去計算之前,這兩件事都不會在任何地方顯示出來。

只要記住一件事:在把輸出交給模型之前,先確認你的轉換器到底怎麼處理表格。這四個工具裡,有三個會做出合理結果。最受歡迎的那個不會,除非你有特別告訴它。

免費試用 Thunderbit 網頁資料擷取 Get Started Free

常見問題

turndown 真的不支援表格嗎? 它的核心不支援。表格是由 turndown-plugin-gfm 這個獨立套件提供的,而單純執行 npm install turndown 並不會包含它。沒有這個插件時,每個儲存格都只會以自己的段落形式保留下來——值還在,但列與欄的關係不見了。四個樣本加總後,這會變成 0 個 Markdown 表格列,且在相同內容下比 markdownify 多出 24.6% 的 token。

為什麼一開始看起來 html2text 沒有表格? 因為我的計數器要求有前後 pipe,但 html2text 不會輸出那種格式。Team Name | Year | Wins 是合法的 Markdown,而且能正常渲染;只是它和 | Team Name | Year | 這種風格不同。修正後的計數器會像 parser 一樣,去找一串包含 pipe 的行以及其中的分隔列,於是 html2text 就從 1 行變成 32 行。如果你自己用 regex 後處理 Markdown,這個差異會直接影響結果。

html2text 的 GPL 授權真的是問題嗎? 要看你如何組合與散布軟體而定。GPL-3.0-or-later 可能會帶來 MIT 不會有的義務,所以在把它用到會對外發布的產品前,務必先和負責授權的人確認。這是一個合規檢查點,不是法律意見;這個授權資訊已從 registry metadata、repository,以及已安裝套件的 METADATA 中確認。

這些 token 數對其他頁面也有參考價值嗎? 24.6% 的差距大多來自 turndown 把 <script><style> 內容保留下來,所以它會隨頁面含有多少這類內容而變動——在現代 CMS 頁面上通常很多,在靜態頁面上則接近零。表格則會把差距拉向另一邊:在那個全表格樣本裡,turndown 反而便宜 22%,因為它不輸出 pipe 骨架。四個工具的 bytes per token 都落在 3.61 到 3.65 之間,所以輸出密度大致一致,差別主要在數量。如果這個數字會影響預算,就用你自己的語料來量。

這裡沒有測到什麼? 真實世界的多樣性——四個樣本畢竟就是四個樣本。巢狀清單、定義清單、註腳與數學公式。格式不完整的 HTML,這一直是轉換器最容易分歧的地方。把 Markdown 再轉回 HTML 的往返測試。docling,它在磁碟上也有相同樣本,但公開的執行結果沒有回報這些欄位,因此這裡是缺席,不是估算。還有設定:html2text 是用 body_width=0 跑的,因為它預設的 78 會把每一行都硬換行,這樣會改變表格裡每一個字元與 token 的計數。

Ke
Ke
Thunderbit 技術長|資深資料科學家與機器學習專家 Ke Shen 在機器學習與資料科學領域擁有近十年經驗,畢業於哥倫比亞大學,曾任 Walmart Labs 資深資料科學家。他精通 Python、R、Java 與統計學,且具備深受同儕認可的深厚專業,分享如何將複雜的 AI 演算法從理論落實到可投入生產的架構的實戰見解。
目錄
Thunderbit · AI 網頁資料代理

1 次點擊 內擷取任何頁面的資料

獲 250,000+ 用戶信賴
提供免費方案
從網頁到試算表
描述你需要什麼——Thunderbit 的 AI Agent 會幫你抓取並匯出到 Excel、Google Sheets、Airtable 或 Notion。可免費開始。
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week