为什么需要这个
做技术的人几乎都遇到过这种场景:
客户发来一份扫描版的产品手册(PDF,全是图片)、或者一本技术书籍的扫描件。你想提取里面的文字,复制到笔记里。
传统做法:对着 PDF 截图 → 手动打字 → 累死。
我给团队搭了一套自动化管线,从扫描 PDF 到结构化 Markdown,全自动。
方案对比
市面上的方案我基本都试过:
| 方案 | 准确率 | 中文支持 | 表格 | 排版保留 | 成本 |
|---|---|---|---|---|---|
| Adobe Acrobat OCR | 高 | 好 | 一般 | 好 | 收费 |
| 微信截图 OCR | 中 | 好 | 无 | 无 | 免费 |
| Tesseract | 中低 | 差 | 无 | 无 | 免费 |
| Marker + Surya | 极高 | 优秀 | 好 | 好 | 免费 |
| 百度云 OCR API | 高 | 好 | 一般 | 一般 | 按量付费 |
最终选了 Marker + Surya 组合。理由是:完全本地运行、不要钱、中文支持好、表格和公式识别能力强。
这套管线是什么
核心两个模型:
- Surya — 做 OCR 文字识别(支持 90+ 语言,中文效果特别好)
- Marker — 基于 Surya 做版面分析 + 结构化输出(保留标题层级、表格、代码块、公式)
处理流程:
扫描 PDF → Surya OCR(识别文字位置)→ Marker 版面分析 → 结构化 Markdown
安装
# 安装 Surya
pip install surya-ocr
# 安装 Marker
pip install marker-pdf
# 下载模型(首次运行自动下载,约 500MB)
上手:单文件转换
最基本的用法,一行命令:
marker /path/to/book.pdf --output_dir ./output/
输出是一份完整的 Markdown 文件,标题层级、段落、列表全部保留。
批量处理:50 页扫描版手册
我写了个批量脚本:
import subprocess
from pathlib import Path
def batch_convert(pdf_dir: str, output_dir: str):
"""批量转换目录下所有 PDF"""
pdfs = list(Path(pdf_dir).glob("*.pdf"))
output = Path(output_dir)
output.mkdir(parents=True, exist_ok=True)
for pdf in pdfs:
print(f"正在处理: {pdf.name}")
subprocess.run([
"marker", str(pdf),
"--output_dir", str(output / pdf.stem)
], check=True)
print(f"完成: {pdf.name} → {output / pdf.stem}")
print(f"全部完成!共处理 {len(pdfs)} 个文件")
# 用我的扫描版产品手册测试
batch_convert("./scanned_manuals/", "./output_markdown/")
效果实测
拿一份 50 页的中文产品手册测试(扫描版,白底黑字带表格):
- 文字识别:99%+ 准确率(只有非常模糊的部分出错)
- 表格:90% 正确转为 Markdown 表格
- 排版:标题层级 H1-H3 基本正确还原
- 速度:50 页约 3 分钟
- 输出体积:50 页 PDF 扫描件(~120MB)→ Markdown 文件(~15KB)
中文的一些坑
踩过的坑写出来省大家时间:
1. 竖排文字
Surya 目前对中文竖排排版支持有限。如果你的扫描件是古书/旧式排版(从上往下、从右往左),需要先做旋转预处理。
2. 数学公式
Marker 对 LaTeX 风格的公式识别还可以,中文技术文档里行内公式基本能还原。独立公式块偶尔会串行,需要人工校正。
3. 图片说明
扫描件里的图片(比如产品实物图)不会保留,只会标注 [image] 占位。如果需要提取图片,要配合 OCR 的坐标数据做裁剪。
进阶:配合文档翻译
如果你的扫描件是英文的,想转成中文 Markdown,可以在管线后面加一个翻译步骤:
import openai
def translate_markdown(md_content: str) -> str:
"""将英文 Markdown 翻译为中文,保留格式"""
response = openai.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": "将以下 Markdown 翻译为中文。保留所有 Markdown 格式标记(#、*、-、[]()等)。不改变代码块内容。"
},
{"role": "user", "content": md_content}
]
)
return response.choices[0].message.content
# 读取转换后的 Markdown,翻译
with open("output_zh.md", "r") as f:
md_content = f.read()
translated = translate_markdown(md_content)
with open("output_translated.md", "w") as f:
f.write(translated)
这套组合适合:
- 产品说明书 PDF → 在线文档
- 扫描版技术书籍 → 笔记
- 客户发来的合同/文档 → 可编辑格式
- 批量历史文档 → 数据库导入
小广告
如果你有 PDF 文档处理、文档格式转换、文档翻译等需求,欢迎留言或私信交流。这类管线我已经搭过很多条,多数场景可以复用,1-2 天交付。
顺便说一句:这个方案的模型和代码全部开源免费,唯一需要的就是一台能跑 Python 的机器——你手边的电脑就够用了。