如何用 Python 把 PDF 转成 Markdown
把 PDF 转成 Markdown 已经是 RAG 管道和 LLM 工作流的标准预处理步骤 — Markdown 保留了模型用来理解结构的标题和表格,token 开销却小得多。Python 里有好几个不错的选择,各有真实的取舍。下面是最值得关注的四个方案,均附可运行代码。
为什么选 Markdown?为什么这事比看起来难
LLM 对 Markdown 的处理能力极强:标题标记出章节边界,管道表格保持数据对齐,列表仍然是列表。把 PDF 原始提取的纯文本喂给模型会丢掉这一切 — 而直接喂 PDF 二进制对多数管道来说根本不可行。这就是几乎所有认真做 RAG 的技术栈都会在分块和向量化之前先把文档转成 Markdown 的原因。
难点在于 PDF 并不包含结构 — 它只包含定位在 x/y 坐标上的字符。转换器必须反向推断:哪些行是标题(靠字号)、哪些词组成表格(靠对齐)、阅读顺序是什么(靠版面分析)。不同库在这些方面的水平差距巨大,所以选型才重要。
还有第二个麻烦:扫描版 PDF 里根本没有文字,只有页面图片。下面的方案中只有部分能通过 OCR 处理这种文件。
方案一:PyMuPDF4LLM — 快而轻
PyMuPDF4LLM 是在 PyMuPDF(fitz)之上、专为 LLM 管道打造的轻薄封装:pip install pymupdf4llm,然后 md = pymupdf4llm.to_markdown("doc.pdf") — 一行代码,速度极快,多数文档不到一秒即可处理完。
它按字号识别标题,把表格渲染成管道表格,还能带元数据按页分块输出,可直接接入 LlamaIndex 或 LangChain。对于版面常规的数字原生 PDF — 报告、文档、无奇特排版的论文 — 它是极佳的默认选择。
局限:没有 OCR,扫描页会返回空内容。复杂多栏排版和结构复杂的表格可能输出错乱,因为其底层启发式规则以速度优先,不做深度版面分析。许可提醒:PyMuPDF 采用 AGPL 协议 — 内部工具没问题,但要放进商业产品发布前请先与法务确认。
方案二:Marker — 质量最高,需要 GPU
Marker 用一条深度学习模型流水线完成版面检测、阅读顺序和表格结构识别,产出的 Markdown 在所有开源方案中最忠实于原文 — 多栏学术论文、复杂表格甚至公式都能处理。
代价是基础设施:数 GB 的模型权重、需要 GPU 才有合理速度(CPU 可用但很慢 — 单个文档常需数十秒),以及一棵沉重的依赖树,要部署到生产或 Serverless 环境得下不少功夫。
当难啃文档的输出质量是第一优先级、且你有硬件时选 Marker — 在 GPU 机器上批量转换学术语料正是它的最佳场景。若是轻量服务或 Serverless 函数,运维负担通常会把它排除在外。
方案三:MarkItDown — 微软的全格式转换器
MarkItDown 是微软开源的“万物转 Markdown”库:pip install markitdown,然后 MarkItDown().convert("doc.pdf").text_content。它的强项是广度 — 同一个 API 可转换 PDF、DOCX、PPTX、XLSX、HTML 等,这也是它因 LLM 数据准备而爆红的原因。
具体到 PDF,它的提取比专用方案更简单:依赖基础文本提取,标题识别和表格保真度落后于 PyMuPDF4LLM 和 Marker,扫描版 PDF 还需要额外配置 OCR。
当你需要一个依赖覆盖多种文件类型、中等质量即可 — 比如一个必须接住“用户传什么都行”的内部摄取脚本 — 就选 MarkItDown,而不是把它当作 PDF 输出质量的最优解。
方案四:托管 API — 零依赖
第四个方案是干脆不在本地跑转换:把 PDF POST 给解析 API,直接拿回 Markdown。用 ParseJet:resp = httpx.post("https://api.parsejet.com/v1/parse/auto/file", headers={"Authorization": "Bearer KEY"}, files={"file": open("doc.pdf", "rb")}) — JSON 响应的 "text" 字段就是 Markdown。
这条路内置了扫描页 OCR,不用安装模型权重或原生库,在 Serverless 函数、容器和 notebook 里表现完全一致,还彻底绕开了 AGPL 问题。代价是一次网络往返,以及超出免费额度后的按文档计费(每月免费 300 积分;一份 PDF 消耗 3 积分)。
想让管道今天就跑起来、PDF 里混有扫描件、或部署环境不适合重依赖 — Lambda、Cloud Run、Vercel — 就选 API。
到底该用哪个?
数字原生 PDF、版面简单到中等、看重速度:PyMuPDF4LLM。它是纯 Python 里投入产出比最好的选择。
难度大的文档(多栏论文、复杂表格)且有 GPU:Marker。开源方案中没有能超过它输出质量的。
要用一个库处理多种文件类型、中等质量即可:MarkItDown。
混有扫描版 PDF、要部署到 Serverless、或完全不想管理依赖:托管 API。一次 HTTP 调用,内置 OCR,任何文档都是同一输出结构。
完整示例:把整个 PDF 文件夹转成 Markdown 文件
无论选哪条路,管道形态都一样 — 遍历、转换、写出。下面用 API 实现(把内层调用换成 pymupdf4llm.to_markdown() 即可改为本地运行):
import httpx; from pathlib import Path — 然后对 Path("pdfs/").glob("*.pdf") 中的每个 pdf:resp = httpx.post("https://api.parsejet.com/v1/parse/auto/file", headers={"Authorization": "Bearer KEY"}, files={"file": pdf.read_bytes()}); Path("md/", pdf.stem + ".md").write_text(resp.json()["text"], encoding="utf-8")。
做 RAG 摄取时,按标题分块而不是按固定字符数分块 — 感知标题的分块能保持章节完整,检索效果显著更好。这种结构保真度,正是值得认真做好转换这一步的原因。
常见问题
Python 里把 PDF 转 Markdown 最好的库是哪个?
数字原生 PDF 首选 PyMuPDF4LLM,速度与质量比最佳。版面复杂且有 GPU 时,Marker 输出质量最高。有扫描件或想零依赖部署时,用 ParseJet 这类托管 API,一次 HTTP 调用同时搞定 OCR 和结构。
如何用 Python 把扫描版 PDF 转成 Markdown?
扫描页没有文字层,必须 OCR。本地方案意味着自己接一套 OCR 引擎;更省事的做法是用内置 OCR 的 API — ParseJet 会自动检测图片页并在同一次请求里完成 OCR。
MarkItDown 做 PDF 转 Markdown 效果好吗?
MarkItDown 的强项是用一个库转换多种格式(PDF、DOCX、PPTX、XLSX)。单论 PDF,它的结构识别比 PyMuPDF4LLM 和 Marker 简单 — 中等质量需求够用,但不是忠实还原标题和表格的最佳选择。
做 RAG 为什么要转 Markdown 而不是纯文本?
Markdown 保留了纯文本会抹平的标题、列表和表格。感知标题的分块检索效果更好,LLM 也能借助结构理解上下文 — 而 token 开销与纯文本基本相同。
不安装任何库能在 Python 里做 PDF 转 Markdown 吗?
能 — 用 httpx 或 requests 通过 HTTP 调用解析 API。把文件 POST 到 ParseJet 的 /v1/parse/auto/file,响应的 "text" 字段就是 Markdown。免费 API Key 每月含 300 积分。
相关工具
PDF to Markdown Converter
Convert PDF to Markdown online for free. Preserves headings, lists, tables, and code blocks. No signup required — try it instantly or automate via API.
PDF to JSON Converter
Convert PDF to JSON online for free. Get text, title, and metadata as structured JSON — ready for your app, database, or AI pipeline. API included.
Word to Markdown Converter
Convert Word documents (DOCX) to Markdown online for free. Headings, lists, and tables preserved. No signup — or automate DOCX to MD conversion via API.