惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MyScale Blog
MyScale Blog
人人都是产品经理
人人都是产品经理
云风的 BLOG
云风的 BLOG
小众软件
小众软件
F
Fortinet All Blogs
爱范儿
爱范儿
WordPress大学
WordPress大学
N
Netflix TechBlog - Medium
Recent Announcements
Recent Announcements
Google DeepMind News
Google DeepMind News
C
Check Point Blog
博客园 - 聂微东
D
Docker
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
aimingoo的专栏
aimingoo的专栏
Vercel News
Vercel News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
A
About on SuperTechFans
博客园 - 【当耐特】
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog
宝玉的分享
宝玉的分享
Jina AI
Jina AI
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - VipSoft

FastAPI 全局 HTTP 异常处理器 + 统一响应封装 SpringBoot 心跳日志不记录 access.log Qdrant Linux 安装(非Docker) LangChain — RAG 知识库(实操) LangChain — RAG 构建知识库(理论) LangChain — RAG 构建知识库(实操) Python PyCharm 运行,取不到 .env 文件中的值 Qdrant 安装(Windows) LangChain — RAG 构建知识库 Python 项目简单部署(Linux) LangChain 入门 服务端部署-FastAPI LangChain 入门 LangSmith LangChain 入门 实战 - 食谱推荐 LangChain 入门 Memory 会话记忆 LangChain 入门 Tools 工具 LangChain 入门 Tools 工具 LangChain 入门 Prompts 提示词 LangChain 入门 Message 消息 LangChain 入门 Model 的初始化和调用 LangChain 入门 Agent 的基本运行机制 AI 0基础学习,名词解析 LangChain 和 LangGraph AI大模型知识体系 Dify — Workflow - 数据可视化 Dify — 连接MySQL配置 Dify — Chatflow - 数据库智能查询 Dify — Chatflow - 文档知识库 Dify — Agent 智能体 高安全券码、注册码生成 Dify — 文本生成应用
MinerU - 将非结构化文档(PDF、图片、Office 文件等)转换为...
VipSoft · 2026-06-24 · via 博客园 - VipSoft

MinerU 是一款开源高精度文档解析引擎,将非结构化文档(PDF、图片、Office 文件等)转换为机器可读的 Markdown 和 JSON,专为 LLM 预训练、RAG 和 Agent 工作流场景设计。
当前整体效果仍在持续改进中。如果你遇到效果不理想、输出质量不稳定或明显的版式异常,欢迎提交 issue 或附带样例文件 / 截图反馈。

核心解析能力:

  • 公式 → LaTeX · 表格 → HTML,精准还原复杂版面
  • 支持扫描件、手写体、多栏布局、跨页表格合并
  • 输出符合人类阅读顺序,自动去除页眉页脚
  • VLM + OCR 双引擎,支持 109 种语言识别

🐍 Python SDK

安装

pip install mineru-open-sdk
uv add mineru-open-sdk --default-index https://pypi.tuna.tsinghua.edu.cn/simple

Agent 轻量解析(免 Token)

from mineru import MinerU

client = MinerU()
result = client.flash_extract("https://cdn-mineru.openxlab.org.cn/demo/example.pdf")
print(result.markdown)

精准解析(需 Token)

from mineru import MinerU

# 从 https://mineru.net 获取免费 Token
client = MinerU("your-api-token")
result = client.extract("https://cdn-mineru.openxlab.org.cn/demo/example.pdf")
print(result.markdown)
print(result.images)  # 提取的图片列表

🦜 LangChain RAG 集成

langchain-mineru 是官方 LangChain 文档加载器,一行代码将任意文档转为 LangChain Document 对象,直接接入 RAG 流水线。

安装

pip install langchain-mineru

最简示例(无需 Token)

1. 基础用法(默认 flash 模式,无需 Token)

from langchain_mineru import MinerULoader

loader = MinerULoader(source="demo.pdf")   # 默认 flash 模式,无需 Token
docs = loader.load()
print(docs[0].page_content[:500])
print(docs[0].metadata)

默认使用 mode="flash",适合快速预览和轻量解析。

2. Precision 模式(需 Token)

适合长文档、大文件,以及对解析保真度或标准 API 输出要求更高的场景。Flash 模式也支持 OCR、公式、表格开关,但仍受 flash API 自身限制。

from langchain_mineru import MinerULoader

loader = MinerULoader(
    source="/path/to/manual.pdf",
    mode="precision",
    token="your-api-token",  # 或设置 MINERU_TOKEN 环境变量
    split_pages=True,
    pages="1-5",
)

docs = loader.load()
for doc in docs:
    print(doc.metadata.get("page"), doc.page_content[:200])

3. 接入 LangChain RAG 流水线

from langchain_mineru import MinerULoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS

loader = MinerULoader(source="demo.pdf", split_pages=True)
docs = loader.load()

splitter = RecursiveCharacterTextSplitter(chunk_size=1200, chunk_overlap=200)
chunks = splitter.split_documents(docs)

vs = FAISS.from_documents(chunks, OpenAIEmbeddings())
results = vs.similarity_search("这个文档的核心结论是什么?", k=3)
for r in results:
    print(r.page_content[:200])

默认使用 mode="flash"(无需 API Token);切换到 mode="precision" 可获得更高精度的解析结果(需要 Token 认证)。如果用于 RAG,建议对 PDF 开启 split_pages=True,这样可以得到更细粒度的页级 Document

🔗 全部集成

框架 / 工具 状态 说明
LangChain ✅ 官方 pip install langchain-mineru
LlamaIndex ✅ 社区 见 MinerU-Ecosystem
RAGFlow ✅ 支持 文档加载器集成
RAG-Anything ✅ 支持 多模态 RAG 流水线
Flowise ✅ 支持 可视化 RAG 构建器
Dify ✅ 原生插件 内置文档加载器
FastGPT ✅ 原生插件 接入文档
Claude Desktop ✅ MCP uvx mineru-open-mcp
Cursor ✅ MCP .cursor/mcp.json 配置
Windsurf ✅ MCP stdio / streamable-http
OpenClaw / ZeroClaw ✅ Agent 技能 ClawHub
Go SDK ✅ 官方 go get .../sdk/go@latest
TypeScript SDK ✅ 官方 npm install mineru-open-sdk
Python SDK ✅ 官方 pip install mineru-open-sdk

MinerU Open API SDK (Python)

MinerU Open API SDK 是一个完全免费的 Python 库,用于连接 MinerU 文档提取服务。只需一行代码,即可将任何文档(PDF、图片、Word、PPT、Excel)或网页转换为高质量的 Markdown。


🚀 核心特性

  • 完全免费:文档提取服务没有任何隐藏费用。
  • Agent 轻量解析 (No Auth):无需 API Token 即可立即提取。
  • 精准解析:提供完整的版式保留、图片、表格及公式支持。
  • 批量与轮询原语:既提供开箱即用的阻塞式接口,也提供适合异步工作流的 submit/query 接口。
  • 内置保存辅助方法:可直接保存 Markdown、HTML、LaTeX、DOCX,或解压完整结果包。

📦 安装指南

pip install mineru-open-sdk

🛠️ 快速上手

适合快速预览。无需配置 Token。

from mineru import MinerU

# Agent 轻量解析无需传入 Token
client = MinerU()
result = client.flash_extract("https://cdn-mineru.openxlab.org.cn/demo/example.pdf")

print(result.markdown)

支持超大文件、丰富的资产(图片/表格)及多种输出格式。

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)
print(result.images) # 获取提取出的图片列表

🧩 支持的公开接口

Client 生命周期

  • MinerU(token: str | None = None, base_url: str = ..., flash_base_url: str | None = None)
  • client.close()
  • client.set_source("your-app")
  • 支持上下文管理器:with MinerU(...) as client:

阻塞式解析接口

  • client.extract(...) -> ExtractResult
  • client.extract_batch(...) -> Iterator[ExtractResult]
  • client.crawl(...) -> ExtractResult
  • client.crawl_batch(...) -> Iterator[ExtractResult]
  • client.flash_extract(...) -> ExtractResult

提交 / 查询接口

  • client.submit(...) -> str
  • client.submit_batch(...) -> str
  • client.get_batch(batch_id) -> list[ExtractResult]
  • client.get_task(task_id) -> ExtractResult

结果保存辅助方法

  • result.save_markdown(path, with_images=True)
  • result.save_docx(path)
  • result.save_html(path)
  • result.save_latex(path)
  • result.save_all(dir)
  • image.save(path)

常用结果字段

  • result.state
  • result.progress
  • result.markdown
  • result.images
  • result.content_list
  • result.docx
  • result.html
  • result.latex
  • result.task_id

📊 模式对比

特性 Agent 轻量解析 (Flash) 精准解析 (Precision)
身份认证 免登录 (No Auth) 需登录 (Token)
处理速度 极速 标准
文件大小上限 最大 10 MB 最大 200 MB
文件页数上限 最大 20 页 最大 200 页
支持格式 PDF, 图片, Docx, PPTx, Excel PDF, 图片, Doc/x, Ppt/x, Html
内容完整度 Markdown(公式和表格默认开启,OCR 默认关闭) 完整资源 (图片、表格、公式全部保留)
输出格式 Markdown MD, Docx, LaTeX, HTML, JSON

⚙️ 默认行为与参数说明

MinerU(...)

参数 默认值 省略时行为
token None 若未传入,则读取环境变量 MINERU_TOKEN
base_url https://mineru.net/api/v4 标准 API 的默认地址
flash_base_url SDK 内置默认 flash 地址 可用于测试或私有部署

如果既没有传入 token,环境变量 MINERU_TOKEN 也未设置,则 client 进入 flash-only modeflash_extract() 可用,其他需要鉴权的方法会抛出 NoAuthClientError

全功能接口

这些默认值适用于 extract()extract_batch()submit()submit_batch()crawl() / crawl_batch() 也会间接继承其中的大部分行为。

参数 默认值 省略时行为
model None 自动推断:.html / .htm"html",其余默认 "vlm"
ocr 不设置 默认关闭 OCR(API 默认行为)
formula 不设置 默认开启公式识别(API 默认行为)
table 不设置 默认开启表格识别(API 默认行为)
language 不设置 默认中文 "ch"(API 默认行为)
pages None 默认处理完整文档
extra_formats None 仅返回默认的 Markdown / JSON 结果
file_params None 批量方法中的 per-file 参数覆盖。dict[str, FileParam],key 为路径/URL,FileParam 包含 pagesocrdata_id 字段
timeout 单任务 300 extract() / crawl() 的总轮询超时
timeout 批量 1800 extract_batch() / crawl_batch() 的总轮询超时
参数 默认值 省略时行为
language "ch" 默认中文
page_range None 默认处理 flash API 允许的完整页范围
is_ocr None OCR 默认关闭(API 默认行为)
enable_formula None 公式识别默认开启(API 默认行为)
enable_table None 表格识别默认开启(API 默认行为)
timeout 300 总轮询超时

crawl() / crawl_batch()

  • crawl() 等价于 extract(url, model="html", ...)
  • crawl_batch() 等价于 extract_batch(urls, model="html", ...)

📖 详细用法

全功能提取选项

result = client.extract(
    "./论文.pdf",
    model="vlm",             # "vlm" | "pipeline" | "html"
    ocr=True,                # 启用 OCR 识别扫描件
    formula=True,            # 公式识别
    table=True,              # 表格识别
    language="en",           # "ch" | "en" | 等
    pages="1-20",            # 页码范围
    extra_formats=["docx"],  # 额外导出为 docx, html, 或 latex
    timeout=600,
)

result.save_all("./output/") # 保存 Markdown 和所有相关资源

上下文管理器

from mineru import MinerU

with MinerU("your-api-token") as client:
    result = client.extract("./论文.pdf")
    print(result.markdown)

批量处理

# 边处理边返回结果
for result in client.extract_batch(["a.pdf", "b.pdf", "c.pdf"]):
    print(f"{result.filename}: 已完成")

批量处理 - 为每个文件指定不同页码

from mineru import FileParam

batch_id = client.submit_batch(
    ["a.pdf", "b.pdf"],
    file_params={
        "a.pdf": FileParam(pages="1-5"),
        "b.pdf": FileParam(pages="10-20"),
    },
)

网页爬取 (Crawl)

result = client.crawl("https://www.baidu.com")
print(result.markdown)

🔄 submit() / get_batch() 语义说明

这一组接口最容易被误用:

  • submit() 返回的是 batch_id
  • submit_batch() 返回的也是 batch_id
  • 因此最常见的异步流程应该是 submit(...) -> get_batch(batch_id)
  • 对于异步轮询,建议始终沿用 batch 这一套语义

推荐的异步流程

batch_id = client.submit("大报告.pdf")

# 轮询 batch,直到第一个结果完成
while True:
    results = client.get_batch(batch_id)
    result = results[0]
    if result.state in ("done", "failed"):
        break

if result.state == "done":
    do_something(result.markdown)

🤖 AI Agent 自动化集成

本 SDK 设计时充分考虑了 LLM 工作流集成。您可以通过 result.stateresult.progress 轻松监控任务状态。

batch_id = client.submit("大报告.pdf")
# ... 稍后 ...
result = client.get_batch(batch_id)[0]
if result.state == "done":
    do_something(result.markdown)

发票快速生成汇总表

PDF 发票 → MinerU SDK 批量提取 → LLM 结构化提取 → Excel

pip install mineru-open-sdk openai openpyxl python-dotenv

.env

MINERU_TOKEN=你的MinerU Token
LLM_API_KEY=你的Moonshot API Key
LLM_BASE_URL=https://api.moonshot.cn/v1
LLM_MODEL=moonshot-v1-128k

完整代码

整个脚本只有三个函数。关键设计:extract_batch 是 yield 式返回——解完一张就立刻喂给 LLM,不用等全部解完。

"""
MinerU 发票提取器
PDF 发票 → MinerU SDK 批量提取 JSON → LLM 结构化提取 → Excel
"""
import os
import sys
import json
from pathlib import Path
from dotenv import load_dotenv

from mineru import MinerU, FileParam
from openai import OpenAI
from openpyxl import Workbook

# -------- 加载环境变量 --------
load_dotenv()

MINERU_TOKEN = os.getenv("MINERU_TOKEN")
LLM_API_KEY = os.getenv("LLM_API_KEY")
LLM_BASE_URL = os.getenv("LLM_BASE_URL", "https://api.moonshot.cn/v1")
LLM_MODEL = os.getenv("LLM_MODEL", "moonshot-v1-128k")

EXTRACT_PROMPT = (
    '你是一个发票信息提取器。以下是MinerU SDK从发票图片中提取的content_list。'
    '每个文本块格式:{"type": "text", "text": "发票号码:144000000000", ...} '
    '或 {"type": "table", "table_body": "<table>...<td>价税合计(小写)</td>'
    '<td>¥ 90000.00</td>...</table>"}。'
    '请找出:1)发票号码(以"发票号码:"开头的text冒号后数字) '
    '2)开票日期("开票日期:"开头,转YYYY-MM-DD) '
    '3)价税合计(表格中"价税合计(小写)"对应¥后面数字)。'
    '只返回JSON,不要任何解释或思考过程。'
    '格式:{"invoice_number":"","date":"","total":""}'
)


# -------- 函数 1:MinerU 批量解析,解完一个 yield 一个 --------
def parse_invoices(pdf_dir: str):
    """将目录下所有 PDF/图片通过 MinerU SDK 批量提取,解完一个 yield 一个"""
    files = []
    for ext in ["*.pdf", "*.jpg", "*.jpeg", "*.png", "*.bmp"]:
        files.extend(sorted(Path(pdf_dir).glob(ext)))
    if not files:
        print("No files found (supported: pdf, jpg, png, bmp)")
        return

    client = MinerU(MINERU_TOKEN)

    # extract_batch 支持的全局参数:
    #   model     - 模型版本: "vlm"(推荐) / "pipeline" / "html",默认自动推断
    #   ocr       - 是否开启 OCR,默认 False
    #   formula   - 是否开启公式识别,默认 True
    #   table     - 是否开启表格识别,默认 True
    #   language  - 文档语言,默认 "ch"
    #   extra_formats - 额外导出格式: ["docx", "html", "latex"]
    #   timeout   - 轮询超时秒数,默认 1800
    #   file_params - 按文件覆盖参数,key 为文件路径,value 为 FileParam

    # FileParam 支持的字段:
    #   pages   - 页码范围,如 "1-5"
    #   ocr     - 覆盖全局 OCR 开关
    #   data_id - 自定义业务标识

    # 发票是扫描件/图片,需要开 OCR;通过 FileParam 按文件设置参数
    file_params = {str(f): FileParam(ocr=True) for f in files}
    for result in client.extract_batch(
        [str(f) for f in files],
        table=True,         # 发票中的金额在表格里,确保开启
        file_params=file_params,
    ):
        print(f"  Parsed: {result.filename}")
        yield {"filename": result.filename, "content": result.content_list}
    client.close()


# -------- 函数 2:LLM 提取结构化字段 --------
def extract_fields(invoice: dict, llm: OpenAI) -> dict:
    """将单张发票的 content_list 喂给 LLM,提取发票号码/日期/金额"""
    content_str = json.dumps(invoice["content"], ensure_ascii=False)
    resp = llm.chat.completions.create(
        model=LLM_MODEL,
        messages=[{"role": "user", "content": EXTRACT_PROMPT + content_str}],
        temperature=0,
    )
    raw = resp.choices[0].message.content.strip()
    try:
        fields = json.loads(raw)
    except json.JSONDecodeError:
        fields = {"invoice_number": "PARSE_ERROR", "date": "", "total": ""}
    fields["filename"] = invoice["filename"]
    print(f"  Extracted: {invoice['filename']}")
    return fields


# -------- 函数 3:写入 Excel --------
def write_excel(data: list[dict], output: str = "发票汇总.xlsx"):
    """将提取结果写入 Excel"""
    wb = Workbook()
    ws = wb.active
    ws.append(["文件名", "发票号码", "开票日期", "价税合计"])
    for row in data:
        ws.append([
            row.get("filename"),
            row.get("invoice_number"),
            row.get("date"),
            row.get("total")
        ])
    wb.save(output)
    print(f"已保存: {output}")


# -------- 主流程:流水线式处理 --------
def main():
    pdf_dir = sys.argv[1] if len(sys.argv) > 1 else "./invoices"
    llm = OpenAI(api_key=LLM_API_KEY, base_url=LLM_BASE_URL)

    results = []
    for invoice in parse_invoices(pdf_dir):        # 解完一张
        results.append(extract_fields(invoice, llm))   # 立刻提取

    write_excel(results)

if __name__ == "__main__":
    main()
python invoice_extractor.py ./invoices

image

MinerU 在线 API 实战教程
MinerU 多环境部署实践:从开源容器化到信创生态适配