ParseJet

如何用 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 摄取时,按标题分块而不是按固定字符数分块 — 感知标题的分块能保持章节完整,检索效果显著更好。这种结构保真度,正是值得认真做好转换这一步的原因。

不写代码,先试试转换效果

上传一份 PDF,看看这个 API 输出的 Markdown — 标题、表格与扫描页 OCR 全都包含。

免费把 PDF 转成 Markdown

常见问题

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 积分。

免费开始提取文本

无需注册。几秒钟内解析您的第一个文件。

查看价格