Python## 1. 安装与环境配置
pip install mineru-open-sdk
一行命令,安装完成。mineru-open-sdk 是 MinerU 官方提供的 Python SDK,通过它你可以直接调用 MinerU 的文档解析服务,不需要手动拼接 REST API、处理签名逻辑或维护轮询状态机。
Python 版本要求 >=3.10。SDK 的运行时依赖极轻——除了 httpx>=0.27,没有额外的重量级包(如 torch、tensorflow)。这意味着你可以在任何 Python 3.10+ 环境中快速集成,包括 Docker 容器、CI/CD Pipeline、无服务器函数(如 AWS Lambda 或阿里云函数计算)。
安装后验证:
from mineru import MinerU
print(MinerU.__name__) # mineru
SDK 自动识别当前环境是否有 MINERU_TOKEN 环境变量。如果你配置了 Token,MinerU() 会进入完整功能模式;如果没有,则自动降级为 Flash-only 模式——这在第 2 节会详细展开。
2. 快速上手:两种解析模式
mineru-open-sdk 提供两种解析入口,对应完全不同的使用场景:Flash Extract(Agent 轻量解析)和 Precision Extract(精准解析)。选对模式,比写对代码更重要。
Flash Extract:免 Token,10 秒出结果
Flash Extract 面向快速预览场景:不需要注册、不需要申请 Token、不需要配置任何认证信息。它适合 AI Agent 工作流中临时解析一个链接的场景。
from mineru import MinerU
client = MinerU() # 不传 Token,自动进入 flash-only mode
result = client.flash_extract("https://cdn-mineru.openxlab.org.cn/demo/example.pdf")
print(result.markdown)
约束条件需要清楚:
| 维度 | 限制 |
|---|---|
| 文件大小 | ≤ 10 MB |
| 页数 | ≤ 20 页 |
| 支持格式 | PDF、图片、Docx、PPTx、Excel |
| 输出格式 | 仅 Markdown |
| 认证 | 无(IP 限频) |
Flash Extract 返回的 result.markdown 包含 Markdown 文本。默认开启公式识别和表格识别,OCR 默认关闭。对扫描件场景,你需要手动开启 is_ocr=True。
Precision Extract:完整管线,全格式输出
当你需要完整结构——不仅仅是文本,还有图片资源、表格数据、公式 LaTeX,甚至同时导出 DOCX 和 HTML——就用 Precision Extract。
from mineru import MinerU
# 从 https://mineru.net/apiManage/token 获取免费 Token
client = MinerU("your-api-token")
result = client.extract("https://cdn-mineru.openxlab.org.cn/demo/example.pdf")
print(result.markdown) # Markdown 全文
print(result.images) # 提取出的图片列表
print(result.html) # HTML 格式
print(result.docx) # DOCX 二进制内容
print(result.latex) # LaTeX 格式
result 是一个 ExtractResult 对象,包含多个输出字段。你可以在一次调用中同时获取所有格式,不需要多次请求。其中 result.markdown 是最常用的字段,包含了完整的文档内容、版面结构和公式/表格的 Markdown 表示。
两种模式的输出字段对比
| 字段 | Flash Extract | Precision Extract |
|---|---|---|
result.markdown | ✅ | ✅ |
result.images | ❌ | ✅ |
result.html | ❌ | ✅ |
result.docx | ❌ | ✅ |
result.latex | ❌ | ✅ |
result.content_list | ❌ | ✅ |
选择策略很简单:文件小于 10 MB、不超过 20 页、只需 Markdown 输出 → Flash Extract。其他场景一律 Precision Extract,特别是需要图片资源、DOCX/LaTeX 导出、或文件超过 20 页时。
3. 三种生产级调用模式
从本地原型到生产系统,调用模式需要逐步升级。mineru-open-sdk 覆盖了三层递进场景。
模式一:本地文件直接解析
开发阶段最常用的方式。支持本地文件路径、URL 两种输入形式。
from mineru import MinerU
with MinerU("your-api-token") as client:
# 本地文件
result = client.extract("./report.pdf")
print(result.markdown)
# 远程 URL
result2 = client.extract("https://example.com/invoice.pdf")
print(result2.markdown)
使用上下文管理器(with 语句)时,SDK 会在退出时自动关闭 HTTP 连接池。你也可以手动管理生命周期:
client = MinerU("your-api-token")
result = client.extract("./report.pdf")
client.close()
extract() 支持多个参数控制解析行为:
result = client.extract(
"./论文.pdf",
model="vlm", # "vlm" | "pipeline" | "html"
ocr=True, # 启用 OCR
formula=True, # 公式识别(默认开启)
table=True, # 表格识别(默认开启)
language="ch", # 文档语言
pages="1-20", # 页码范围
extra_formats=["docx"], # 额外导出格式
timeout=600, # 轮询超时(秒)
)
model 参数值得单独说清楚:vlm 使用视觉语言模型解析,精度最高,适合复杂版面;pipeline 使用传统管线,速度更快;html 专门用于网页内容抓取,等价于调用 crawl() 方法。对学术论文、扫描件、图文混排文档,推荐使用 model="vlm"。
模式二:Open API 远程调用
当你的应用需要跨网络调用 MinerU 服务,或者你正在构建一个多租户系统,Open API 模式更合适。SDK 封装了完整的鉴权和轮询逻辑,你不需要手动处理 Authorization 头或任务状态机。
from mineru import MinerU
client = MinerU("your-api-token", base_url="https://mineru.net/api/v4")
result = client.extract("https://cdn-mineru.openxlab.org.cn/demo/example.pdf")
base_url 默认指向 MinerU 公共 API。如果你使用私有化部署或区域化服务节点,替换这个地址即可。SDK 内部使用 httpx 客户端管理连接,支持连接池复用(见第 6 节性能调优)。
Precision Extract 的文件限制:
| 限制项 | 值 |
|---|---|
| 文件大小 | ≤ 200 MB |
| 页数 | ≤ 200 页 |
| 每日免费额度 | 1000 页最高优先解析 |
| 单次批量 | ≤ 50 个文件(URL 模式) |
| 网络限制 | GitHub、AWS 等国外 URL 可能超时 |
模式三:私有化部署接入
如果你的数据不能上云,MinerU 提供开源版私有化部署。SDK 通过 base_url 参数无缝对接私有实例。
from mineru import MinerU
# 假设私有部署地址为 https://mineru.internal.company.com
client = MinerU("internal-token", base_url="https://mineru.internal.company.com/api/v4")
result = client.extract("./机密报告.pdf")
私有化部署模式下,所有解析在本地完成,数据不出内网。SDK 接口与云 API 完全一致,代码切换成本为零——换个 base_url 和 token 就行。
4. 批量处理与异步工作流
单文件解析只是起点。生产环境中,你需要处理的是成百上千个文档——合同审核、论文批量解析、票据数据提取、历史档案数字化。mineru-open-sdk 为此提供了两套互补的原语。
阻塞式批处理:extract_batch()
如果你希望"提交一批文件,依次拿到结果"——像是遍历一个文件列表,每个文件解析完成后立刻处理——用 extract_batch():
from mineru import MinerU
files = [
"contract_001.pdf",
"contract_002.pdf",
"report_2024.pdf",
"invoice_march.pdf",
"https://example.com/spec.pdf",
]
with MinerU("your-api-token") as client:
for result in client.extract_batch(files):
print(f"{result.filename}: state={result.state}")
if result.state == "done":
# 每完成一个文件,立即处理
with open(f"./output/{result.filename}.md", "w") as f:
f.write(result.markdown)
extract_batch() 返回一个迭代器,按文件的提交顺序逐个 yield ExtractResult。一个文件完成后,你可以立刻处理它的结果,不需要等待整批完成。这种行为对内存很友好——你不需要在内存里同时持有几百个文件的结果。
默认超时时间为 1800 秒(30 分钟)。你可以通过 timeout 参数调整:
results = client.extract_batch(files, timeout=3600)
异步 submit/query 原语
如果你的工作流更复杂——需要把文件提交到队列后去做其他事情,之后再回来查结果——使用 submit() + get_batch() 组合。
from mineru import MinerU
client = MinerU("your-api-token")
# 提交单个文件,返回 batch_id(注意:submit 返回的也是 batch_id)
batch_id = client.submit("大报告.pdf")
# ... 做其他事情 ...
# 轮询 batch,直到结果完成
while True:
results = client.get_batch(batch_id)
result = results[0]
if result.state in ("done", "failed"):
break
print(f"进度: {result.state}")
if result.state == "done":
print(result.markdown)
这一组接口最容易被误用。SDK 的设计中,submit() 和 submit_batch() 都返回 batch_id。这意味着你始终通过 batch 语义来查询——即使你只提交了一个文件。对应的查询方法是 get_batch(batch_id),返回一个结果列表。
批量提交 + 文件级别参数覆盖
当批次中的每个文件需要不同的解析参数时,使用 file_params:
from mineru import MinerU, FileParam
batch_id = client.submit_batch(
["a.pdf", "b.pdf"],
file_params={
"a.pdf": FileParam(pages="1-5", ocr=True),
"b.pdf": FileParam(pages="10-20"),
},
)
错误隔离与重试策略
批量处理时,单个文件的失败不会影响批次中的其他文件。你可以在迭代结果时逐个检查 result.state 和可选的 result.err_msg:
for result in client.extract_batch(files):
if result.state == "failed":
# 记录失败,不阻塞整个批次
failed_files.append(result.filename)
continue
process_result(result)
一个实用的重试策略:对失败的文件收集后单独重试,最多重试 3 次,每次间隔指数退避(1s → 2s → 4s)。
内存与并发控制
extract_batch() 内部会限制并发请求数以防止客户端内存溢出。如果你需要更高的吞吐,可以调整 httpx 客户端的连接池配置:
import httpx
from mineru import MinerU
transport = httpx.AsyncHTTPTransport(connections=10)
client = MinerU("token", base_url="...")
# 内部 client 可以通过 client._client 访问 httpx.AsyncClient
根据经验估算,一个中等配置的服务器(4 核 8G)使用默认并发设置处理 1000 份 PDF(平均 10 页/份),总耗时约 15-25 分钟,取决于文件复杂度和网络延迟。
5. 结果保存与格式选型
解析完成后,如何保存结果直接影响下游工作流效率。ExtractResult 提供了 5 个内置保存方法,覆盖 RAG 流水线、文档编辑、网页展示三种典型场景。
save_markdown() — RAG 流水线的标准输入
result.save_markdown("./output/", with_images=True)
保存一个 {filename}.md 文件和一个 {filename}_images/ 目录(如果解析结果中包含图片)。Markdown 是目前 RAG 流水线中最通用的文档格式——它保留了标题层级、列表、表格和公式,同时可以被几乎所有文本切分工具(如 LangChain 的 MarkdownHeaderTextSplitter)直接消费。
save_docx() — 文档编辑与办公协作
result.save_docx("./output/report.docx")
当最终用户需要对解析结果做二次编辑——比如调整排版、补充批注、合并多份文档——DOCX 是更自然的选择。MinerU 会将版面结构映射为 Word 的原生段落、表格和图片样式,保留多栏布局和脚注相对位置。
save_html() — 网页展示与在线预览
result.save_html("./output/report.html")
HTML 格式适合在线文档系统、知识库页面和 Web 应用。生成的 HTML 保持了原始的标题结构和图片内嵌引用,可以直接嵌入 iframe 或通过静态站点发布。
save_latex() — 学术出版与论文排版
result.save_latex("./output/paper.tex")
LaTeX 输出主要面向学术场景。如果源文档是高密度数学论文,LaTeX 格式保留了完整的公式表达和交叉引用结构,可以直接用于 Overleaf 或 TeX 编辑器的二次排版。
save_all() — 一键打包,保留完整资产
result.save_all("./output/full_result/")
save_all() 是最高层级的保存方法,它会解压完整结果包,输出目录结构如下:
output/full_result/
├── full.md # Markdown 全文
├── content_list.json # 结构化内容列表
├── images/ # 所有提取出的图片
│ ├── img_001.png
│ ├── img_002.jpg
│ └── ...
├── document.docx # (如果 extra_formats 包含 docx)
├── document.html # (如果 extra_formats 包含 html)
└── document.tex # (如果 extra_formats 包含 latex)
下游衔接建议
| 下游场景 | 推荐格式 | 原因 |
|---|---|---|
| RAG / 向量检索 | Markdown | 标题层级清晰,切分语义准确 |
| 文档编辑器(Word/Google Docs) | DOCX | 原生格式,所见即所得 |
| Web 内容展示 | HTML | 浏览器原生渲染,支持 CSS 样式 |
| 学术论文排版 | LaTeX | 公式和引用完整保留 |
| 全量归档 | save_all() | 一次性保存所有格式和资产 |
6. 性能调优与常见问题
超时设置
不同文件大小需要不同的超时配置。经验值:
# 小文件(<50 页)
client.extract("小文件.pdf", timeout=120)
# 大文件(50-200 页)
client.extract("大文件.pdf", timeout=600)
# 批量(100+ 文件)
client.extract_batch(files, timeout=3600)
单任务默认超时 300 秒,批量默认 1800 秒。如果文件普遍超过 100 页,建议将超时增加到 600 秒以上。
大文件分片
当文件超过 200 页或 200 MB 时,API 不支持直接解析。解决方案是在提交前拆分文件:
# 手动指定页码范围
result_part1 = client.extract("大报告.pdf", pages="1-100")
result_part2 = client.extract("大报告.pdf", pages="101-200")
对于超过 200 页的 PDF,建议先用 PyMuPDF 或 pdfplumber 拆分为多个子文件,再通过 extract_batch() 批量提交。
连接池复用
每次创建 MinerU() 实例都会初始化一个新的 HTTP 连接池。在高吞吐场景下,复用同一个实例:
# 推荐:复用 client 实例
client = MinerU("token")
for file in thousands_of_files:
result = client.extract(file)
process(result)
client.close()
常见问题与解决方法
Q: flash_extract() 返回空内容或报错
检查文件是否超过 10 MB 或 20 页。Flash API 对超限文件直接拒绝(HTTP 429 或错误码 -30003)。如果文件参数合规,检查 URL 是否为可公开访问的 CDN 地址——GitHub raw 链接、需要登录的网盘链接可能无法访问。
Q: extract() 报 Token 错误(错误码 A0202/A0211)
检查 Token 是否过期。Token 可以在 MinerU Token 管理页 续期。另一个常见问题是 Token 字符串中包含空格或换行符——建议从页面直接复制。
Q: 批量处理时部分文件一直 pending
Pending 状态通常是排队拥挤导致。MinerU 每天前 1000 页使用最高优先级队列,超过的部分自动降级。如果你的批量任务中有大量超 1000 页的文档,建议分批提交,避免所有文件挤在低优先级队列。
Q: 国外 URL(GitHub、AWS)请求超时
API 文档明确指出,因网络限制,GitHub、AWS 等国外 URL 会请求超时(错误码 -60008)。解决方案:先将文件下载到本地或上传到国内 CDN,再提交本地路径。
Q: 如何确认解析进度?
result = client.extract("大文件.pdf")
# extract() 会阻塞直到完成
# 但你可以通过 submit() + get_batch() 获取中间进度
print(result.state) # "done" | "failed"
print(result.progress) # 如果 state 为 running,包含已解析页数
错误码速查
| 错误码 | 含义 | 解决方向 |
|---|---|---|
| A0202 | Token 错误 | 检查 Token 和 Bearer 前缀 |
| A0211 | Token 过期 | 到 Token 管理页续期 |
| -60005 | 文件超过 200 MB | 拆分文件 |
| -60006 | 文件超过 200 页 | 拆分或指定 page_ranges |
| -60008 | 文件读取超时 | 检查 URL 可达性 |
| -30003 | Flash 接口页数超限 | 改用 Precision Extract |
| -60018 | 当日解析额度用尽 | 明日后重试或升级套餐 |