5分钟学会MinerU API调用:轻松搞定扫描件文字识别与内容总结
5分钟学会MinerU API调用:轻松搞定扫描件文字识别与内容总结
1. 快速上手:为什么你需要MinerU?
想象一下这个场景:你收到一份PDF格式的合同扫描件,需要快速提取关键条款;或者你有一堆学术论文截图,想要快速了解每篇的核心观点。传统方法是什么?要么手动打字,要么用通用OCR工具识别,然后自己整理总结——整个过程耗时耗力,还容易出错。
这就是MinerU智能文档理解服务要解决的问题。它就像一个专门处理文档的AI助手,你给它一张图片,它不仅能准确识别上面的文字,还能理解内容、总结要点,甚至回答你的问题。
最吸引人的三点:
- 轻量快速:1.2B的小模型,在普通电脑CPU上就能跑,响应速度飞快
- 文档专精:专门针对文档场景优化,处理表格、公式、复杂排版比通用工具强得多
- 简单易用:提供标准的API接口,几行代码就能集成到你的系统里
接下来,我会带你用5分钟时间,从零开始学会怎么调用MinerU的API,让你也能轻松实现文档自动化处理。
2. 准备工作:启动服务与检查状态
2.1 启动MinerU服务
如果你已经在CSDN星图平台找到了MinerU镜像,启动过程非常简单:
- 点击“部署”按钮,等待镜像启动完成
- 系统会提供一个访问地址,通常是
http://localhost:8080或类似的URL - 点击HTTP访问按钮,就能看到MinerU的Web界面了
2.2 验证服务是否正常
在开始写代码之前,先确认服务已经正常运行。打开命令行工具,输入:
curl http://localhost:8080/health
如果看到这样的返回结果,说明一切正常:
{"status":"ok","model":"MinerU2.5-2509-1.2B"}
如果返回错误或者超时,可能需要检查:
- 服务是否完全启动(等待1-2分钟再试)
- 网络连接是否正常
- 端口号是否正确
3. 核心API调用:从图片到文字的魔法
3.1 理解API的工作方式
MinerU的API设计得很直观,你只需要做两件事:
- 把图片传给它
- 告诉它你想做什么
它支持多种指令,比如:
- “请提取图中的所有文字”
- “总结这份文档的主要内容”
- “表格里的数据是什么?”
- “这段代码是什么意思?”
3.2 最简单的Python调用示例
让我们从一个完整的例子开始。假设你有一张文档截图 document.png,想要提取上面的文字:
import requests
import base64
import json
# 第一步:准备图片
def encode_image_to_base64(image_path):
"""把图片转换成base64编码的字符串"""
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode('utf-8')
# 第二步:构建请求
image_base64 = encode_image_to_base64("document.png")
payload = {
"model": "mineru",
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"image_url": f"data:image/jpeg;base64,{image_base64}"
},
{
"type": "text",
"text": "请将图中的文字完整提取出来"
}
]
}
],
"stream": False
}
# 第三步:发送请求
response = requests.post(
"http://localhost:8080/v1/chat/completions",
headers={"Content-Type": "application/json"},
data=json.dumps(payload),
timeout=30
)
# 第四步:处理结果
if response.status_code == 200:
result = response.json()
extracted_text = result['choices'][0]['message']['content']
print("提取到的文字:")
print(extracted_text)
else:
print(f"请求失败:{response.status_code}")
print(response.text)
运行这段代码,你就能看到图片里的文字被完整地提取出来了。是不是很简单?
4. 实战应用:三种常见场景的完整解决方案
4.1 场景一:扫描件文字提取(合同、报告、票据)
很多公司需要处理大量的扫描文档,比如合同、财务报表、发票等。手动录入不仅慢,还容易出错。
优化后的代码示例:
class DocumentProcessor:
def __init__(self, api_url="http://localhost:8080"):
self.api_url = api_url
def extract_text_from_scanned_doc(self, image_path, output_file=None):
"""
从扫描件中提取文字,支持保存到文件
参数:
image_path: 图片路径
output_file: 可选,保存提取结果的文本文件路径
"""
# 编码图片
with open(image_path, "rb") as f:
image_data = base64.b64encode(f.read()).decode('utf-8')
# 构建请求
request_data = {
"model": "mineru",
"messages": [
{
"role": "user",
"content": [
{"type": "image", "image_url": f"data:image/jpeg;base64,{image_data}"},
{"type": "text", "text": "请准确提取图片中的所有文字,保持原文格式"}
]
}
]
}
# 发送请求
response = requests.post(
f"{self.api_url}/v1/chat/completions",
json=request_data,
timeout=60 # 给大文件多一点时间
)
if response.status_code == 200:
text_content = response.json()['choices'][0]['message']['content']
# 如果需要保存到文件
if output_file:
with open(output_file, 'w', encoding='utf-8') as f:
f.write(text_content)
print(f"文字已保存到:{output_file}")
return text_content
else:
print(f"提取失败:{response.status_code}")
return None
# 使用示例
processor = DocumentProcessor()
# 提取合同扫描件
contract_text = processor.extract_text_from_scanned_doc(
"contract_scan.jpg",
output_file="contract_text.txt"
)
# 提取发票
invoice_text = processor.extract_text_from_scanned_doc("invoice.png")
实用技巧:
- 对于模糊的扫描件,可以先使用图片处理库(如PIL)进行锐化和对比度调整
- 如果文档有多页,可以每页单独处理,然后合并结果
- 重要的合同或法律文件,建议人工核对关键条款
4.2 场景二:文档内容总结(论文、文章、报告)
当你需要快速了解一份长文档的核心内容时,让MinerU帮你总结是最省时的方法。
智能总结代码示例:
def summarize_document(image_path, summary_type="brief"):
"""
总结文档内容
参数:
image_path: 文档图片路径
summary_type: 总结类型,可选 "brief"(简短), "detailed"(详细), "bullet"(要点)
"""
# 根据类型选择不同的提示词
prompts = {
"brief": "用一段话总结这份文档的核心内容",
"detailed": "详细总结这份文档的主要观点和结论",
"bullet": "用要点列表的形式总结这份文档的关键信息"
}
prompt = prompts.get(summary_type, "总结这份文档的内容")
# 编码图片
with open(image_path, "rb") as f:
image_base64 = base64.b64encode(f.read()).decode('utf-8')
# 发送总结请求
response = requests.post(
"http://localhost:8080/v1/chat/completions",
json={
"model": "mineru",
"messages": [
{
"role": "user",
"content": [
{"type": "image", "image_url": f"data:image/jpeg;base64,{image_base64}"},
{"type": "text", "text": prompt}
]
}
]
}
)
if response.status_code == 200:
summary = response.json()['choices'][0]['message']['content']
return summary
else:
return f"总结失败:{response.status_code}"
# 使用示例
# 简短总结学术论文
paper_summary = summarize_document("research_paper.png", "brief")
print("论文核心内容:")
print(paper_summary)
# 详细总结业务报告
report_summary = summarize_document("business_report.png", "detailed")
print("\n报告详细总结:")
print(report_summary)
# 要点总结会议纪要
meeting_summary = summarize_document("meeting_minutes.png", "bullet")
print("\n会议要点:")
print(meeting_summary)
让总结更准确的小技巧:
- 指定总结重点:比如“总结技术方案部分”或“重点关注数据结果”
- 控制总结长度:添加“控制在200字以内”或“分三点说明”
- 提取特定信息:比如“找出所有的日期和责任人”
4.3 场景三:表格数据提取(财务报表、数据报表)
表格是文档中最有价值也最难处理的部分。MinerU在这方面表现特别出色。
表格提取与结构化代码:
def extract_table_data(image_path, table_description=None):
"""
提取图片中的表格数据
参数:
image_path: 包含表格的图片路径
table_description: 可选,表格描述,如“提取销售数据表格”
"""
# 准备提示词
if table_description:
prompt = f"{table_description},以表格形式返回数据"
else:
prompt = "提取图片中的表格数据,以清晰的表格格式返回"
# 处理图片
with open(image_path, "rb") as f:
image_data = base64.b64encode(f.read()).decode('utf-8')
# 发送请求
response = requests.post(
"http://localhost:8080/v1/chat/completions",
json={
"model": "mineru",
"messages": [
{
"role": "user",
"content": [
{"type": "image", "image_url": f"data:image/jpeg;base64,{image_data}"},
{"type": "text", "text": prompt}
]
}
]
},
timeout=45 # 表格处理可能需要更长时间
)
if response.status_code == 200:
table_data = response.json()['choices'][0]['message']['content']
# 尝试解析为结构化数据
import re
# 查找表格数据
rows = []
for line in table_data.split('\n'):
if '|' in line and '---' not in line: # 跳过分隔线
# 清理并分割单元格
cells = [cell.strip() for cell in line.split('|') if cell.strip()]
if cells:
rows.append(cells)
return {
"raw_text": table_data,
"structured_rows": rows if rows else None
}
else:
return {"error": f"请求失败:{response.status_code}"}
# 使用示例
# 提取财务报表
financial_table = extract_table_data("financial_statement.png", "提取利润表数据")
print("表格数据:")
print(financial_table["raw_text"])
if financial_table["structured_rows"]:
print("\n结构化数据:")
for row in financial_table["structured_rows"]:
print(row)
处理复杂表格的建议:
- 明确指定表格:如果图片中有多个表格,用“左上角的表格”或“标题为'销售数据'的表格”来指定
- 要求特定格式:添加“用CSV格式返回”或“用Markdown表格格式”
- 分批处理:对于特别大的表格,可以分区域截图处理
5. 高级技巧与问题解决
5.1 批量处理多个文档
当你需要处理大量文档时,单个处理效率太低。这里提供一个批量处理的方案:
import os
from concurrent.futures import ThreadPoolExecutor, as_completed
def batch_process_documents(image_folder, output_folder, process_type="extract"):
"""
批量处理文件夹中的所有图片文档
参数:
image_folder: 包含图片的文件夹路径
output_folder: 输出结果文件夹
process_type: 处理类型,extract(提取) 或 summarize(总结)
"""
# 创建输出文件夹
os.makedirs(output_folder, exist_ok=True)
# 获取所有图片文件
image_files = []
for file in os.listdir(image_folder):
if file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')):
image_files.append(os.path.join(image_folder, file))
print(f"找到 {len(image_files)} 个图片文件")
def process_single_file(image_path):
"""处理单个文件"""
try:
filename = os.path.basename(image_path)
output_file = os.path.join(output_folder, f"{os.path.splitext(filename)[0]}.txt")
if process_type == "extract":
result = extract_text_from_scanned_doc(image_path)
else:
result = summarize_document(image_path)
if result:
with open(output_file, 'w', encoding='utf-8') as f:
f.write(result)
return filename, True
else:
return filename, False
except Exception as e:
print(f"处理 {image_path} 时出错:{e}")
return os.path.basename(image_path), False
# 使用线程池并发处理
results = []
with ThreadPoolExecutor(max_workers=3) as executor: # 控制并发数,避免服务器压力过大
future_to_file = {executor.submit(process_single_file, img): img for img in image_files}
for future in as_completed(future_to_file):
filename, success = future.result()
results.append((filename, success))
# 统计结果
success_count = sum(1 for _, success in results if success)
print(f"处理完成:成功 {success_count}/{len(image_files)} 个文件")
return results
# 使用示例
# 批量提取文字
batch_results = batch_process_documents(
image_folder="./scanned_docs",
output_folder="./extracted_texts",
process_type="extract"
)
# 批量总结内容
summary_results = batch_process_documents(
image_folder="./reports",
output_folder="./summaries",
process_type="summarize"
)
5.2 常见问题与解决方案
在实际使用中,你可能会遇到一些问题。这里是一些常见问题的解决方法:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 返回空内容或乱码 | 图片质量太差、文字太小 | 1. 确保图片清晰度至少300dpi 2. 调整图片对比度 3. 尝试黑白二值化处理 |
| 请求超时 | 图片太大、服务器忙 | 1. 压缩图片到2MB以内 2. 增加超时时间到60秒 3. 分批处理大文件 |
| 识别结果不准确 | 复杂排版、特殊字体 | 1. 使用更明确的指令,如"识别第三段文字" 2. 对图片进行预处理 3. 分区域截图识别 |
| 内存不足 | 同时处理太多请求 | 1. 减少并发数量 2. 增加服务器内存 3. 使用队列顺序处理 |
图片预处理代码示例:
from PIL import Image, ImageEnhance
import cv2
import numpy as np
def preprocess_image_for_ocr(image_path, output_path=None):
"""
预处理图片,提高OCR识别准确率
"""
# 方法1:使用PIL调整对比度和锐度
img = Image.open(image_path)
# 转换为灰度图
if img.mode != 'L':
img = img.convert('L')
# 增强对比度
enhancer = ImageEnhance.Contrast(img)
img = enhancer.enhance(2.0) # 增加对比度
# 增强锐度
enhancer = ImageEnhance.Sharpness(img)
img = enhancer.enhance(2.0)
# 方法2:使用OpenCV进行二值化(备选)
# img_cv = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
# _, img_binary = cv2.threshold(img_cv, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
if output_path:
img.save(output_path)
return output_path
else:
# 保存到临时文件
temp_path = "temp_processed.png"
img.save(temp_path)
return temp_path
# 使用预处理后的图片
processed_image = preprocess_image_for_ocr("blurry_document.jpg")
result = extract_text_from_scanned_doc(processed_image)
5.3 性能优化建议
- 连接复用:如果需要频繁调用API,使用Session可以提升性能
import requests
# 创建会话,复用TCP连接
session = requests.Session()
# 在循环中使用同一个session
for image_path in image_list:
response = session.post(api_url, json=payload, timeout=30)
- 异步处理:对于大量文档,使用异步可以大幅提升处理速度
import aiohttp
import asyncio
async def async_extract_text(session, image_path):
"""异步提取文字"""
# 编码图片
with open(image_path, "rb") as f:
image_data = base64.b64encode(f.read()).decode('utf-8')
payload = {
"model": "mineru",
"messages": [{
"role": "user",
"content": [
{"type": "image", "image_url": f"data:image/jpeg;base64,{image_data}"},
{"type": "text", "text": "提取文字"}
]
}]
}
async with session.post(api_url, json=payload) as response:
return await response.json()
# 批量异步处理
async def process_batch_async(image_paths):
async with aiohttp.ClientSession() as session:
tasks = [async_extract_text(session, path) for path in image_paths]
results = await asyncio.gather(*tasks)
return results
- 结果缓存:对于相同的文档,避免重复处理
import hashlib
import json
from pathlib import Path
class CachedMinerUClient:
def __init__(self, cache_dir="./cache"):
self.cache_dir = Path(cache_dir)
self.cache_dir.mkdir(exist_ok=True)
def get_cache_key(self, image_path, prompt):
"""生成缓存键"""
# 使用文件内容和提示词生成唯一键
with open(image_path, "rb") as f:
file_hash = hashlib.md5(f.read()).hexdigest()
prompt_hash = hashlib.md5(prompt.encode()).hexdigest()
return f"{file_hash}_{prompt_hash}.json"
def process_with_cache(self, image_path, prompt):
"""带缓存的处理"""
cache_key = self.get_cache_key(image_path, prompt)
cache_file = self.cache_dir / cache_key
# 检查缓存
if cache_file.exists():
print(f"使用缓存结果:{cache_key}")
with open(cache_file, 'r', encoding='utf-8') as f:
return json.load(f)
# 调用API
result = self.call_mineru_api(image_path, prompt)
# 保存到缓存
with open(cache_file, 'w', encoding='utf-8') as f:
json.dump(result, f, ensure_ascii=False, indent=2)
return result
6. 总结
6.1 核心要点回顾
通过这5分钟的学习,你应该已经掌握了MinerU API调用的核心技能:
- 基础调用很简单:只需要准备图片、构建请求、发送请求、处理结果四步
- 应用场景广泛:文字提取、内容总结、表格识别都能轻松搞定
- 代码可复用:本文提供的代码示例可以直接用在你的项目中
- 性能足够好:在普通电脑上就能快速运行,适合各种规模的应用
6.2 最佳实践建议
根据我的使用经验,给你几个实用建议:
对于新手:
- 先从清晰的文档图片开始,熟悉基本流程
- 使用简单的指令,比如“提取文字”或“总结内容”
- 逐步尝试更复杂的需求,比如表格提取或多轮对话
对于项目集成:
- 一定要添加错误处理和重试机制
- 考虑使用异步处理提升批量任务效率
- 对于重要文档,建议保留人工审核环节
性能优化:
- 图片大小控制在2MB以内
- 复杂文档可以分区域处理
- 使用连接池和缓存减少重复请求
6.3 下一步学习方向
如果你已经掌握了基础调用,可以进一步探索:
- 多轮对话:基于之前的识别结果继续提问,比如“刚才那个表格里,第三行数据是什么?”
- 复杂指令:尝试更具体的需求,如“提取所有加粗的文字”或“找出文档中的日期和金额”
- 系统集成:将MinerU集成到你的OA系统、知识库或自动化流程中
- 自定义处理:结合其他工具,比如将提取的文字自动翻译、分类或生成报告
MinerU最吸引人的地方在于它的平衡性——既有不错的识别准确率,又保持了轻量和快速的特点。对于大多数文档处理需求来说,它都是一个性价比很高的选择。
现在,你可以开始用这些代码解决实际的文档处理问题了。从最简单的文字提取开始,逐步尝试更复杂的应用场景。记住,最好的学习方式就是动手实践。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐

所有评论(0)