DeepSeek-OCR-2实战教程:自定义后处理脚本,实现OCR结果自动分类归档
DeepSeek-OCR-2实战教程自定义后处理脚本实现OCR结果自动分类归档1. 引言从识别到归档让OCR真正为你所用你用过OCR工具吗是不是经常遇到这样的场景扫描了一堆发票、合同、会议纪要工具确实把文字都识别出来了但接下来才是最头疼的——你得手动把这些内容一个个复制粘贴然后分门别类地保存到不同的文件夹里。我最近在帮一家小型企业做文档数字化他们每个月要处理几百张各种类型的单据。用传统的OCR工具识别准确率确实不错但识别后的整理工作几乎占用了总时间的一半。员工们抱怨说“识别是快了但整理更累了。”这就是我们今天要解决的问题。DeepSeek-OCR-2深求·墨鉴本身已经是个很优秀的OCR工具但它的输出结果还需要我们手动处理。能不能让这个过程自动化呢能不能让OCR识别出来的内容自动按照我们设定的规则进行分类、归档甚至提取关键信息答案是肯定的。通过编写自定义的后处理脚本我们可以让DeepSeek-OCR-2不仅“看得懂”文字还能“理解”内容然后自动完成后续的所有整理工作。在这篇教程里我会手把手教你如何理解DeepSeek-OCR-2的输出格式编写Python脚本来自动处理OCR结果根据内容关键词自动分类文档提取关键信息并生成结构化数据将处理结果自动保存到指定位置学完这篇教程你就能把OCR从一个单纯的“文字识别工具”升级为“智能文档处理系统”。无论是个人整理资料还是企业处理大量文档效率都能提升好几倍。2. 理解DeepSeek-OCR-2的输出数据长什么样在开始写脚本之前我们得先搞清楚DeepSeek-OCR-2到底输出了什么。只有了解了数据的结构我们才能有针对性地处理它。2.1 两种输出格式Markdown和JSONDeepSeek-OCR-2深求·墨鉴主要提供两种输出格式Markdown格式这是你在界面上直接看到的适合人类阅读。比如识别一张发票可能会输出这样的内容# 增值税专用发票 **发票代码**123456789012 **发票号码**202401150001 **开票日期**2024年1月15日 **购买方**某某科技有限公司 纳税人识别号91110108MA12345678 地址、电话北京市海淀区xxx路xx号 010-12345678 开户行及账号中国银行北京分行 1234567890123456789 **货物或应税劳务名称** **规格型号** **单位** **数量** **单价** **金额** **税率** **税额** 办公用品 - 批 1 2000.00 2000.00 13% 260.00 **价税合计大写**贰仟贰佰陆拾元整 **价税合计小写**2260.00 **销售方**某某办公用品有限公司 纳税人识别号91110105MA87654321JSON格式这是程序处理时更喜欢的格式包含了详细的结构化信息。DeepSeek-OCR-2实际上在后台会生成类似这样的数据结构{ text: 完整的识别文本内容, blocks: [ { type: text, bbox: [100, 200, 300, 250], text: 增值税专用发票, confidence: 0.98 }, { type: text, bbox: [100, 260, 300, 280], text: 发票代码123456789012, confidence: 0.95 }, // ... 更多文本块 ], tables: [ { bbox: [50, 400, 550, 500], cells: [ [货物或应税劳务名称, 规格型号, 单位, 数量, 单价, 金额, 税率, 税额], [办公用品, -, 批, 1, 2000.00, 2000.00, 13%, 260.00] ] } ] }2.2 关键信息在哪里从上面的例子可以看出OCR识别出来的信息是有规律的标题和关键字段通常以加粗、冒号分隔的形式出现表格数据对于发票、报价单等文档重要数据往往在表格里位置信息每个文本块都有坐标信息bbox这有助于理解文档结构理解这些特点很重要因为我们的后处理脚本就是要利用这些规律来提取和分类信息。3. 环境准备搭建你的自动化处理平台好了理论部分讲完了现在开始动手。首先我们需要准备好运行环境。3.1 基础环境要求你需要准备Python 3.8或更高版本基本的文本编辑器VS Code、PyCharm等都可以DeepSeek-OCR-2深求·墨鉴的访问权限如果你还没有安装Python可以去官网下载安装。安装完成后打开命令行工具输入python --version确认安装成功。3.2 安装必要的Python库我们需要几个Python库来帮助处理OCR结果。打开命令行依次执行以下命令# 创建项目文件夹 mkdir ocr_postprocess cd ocr_postprocess # 创建虚拟环境可选但推荐 python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate # Mac/Linux: source venv/bin/activate # 安装所需库 pip install pandas openpyxl python-docx让我解释一下这些库的作用pandas处理表格数据的神器我们用它来整理提取出来的信息openpyxl读写Excel文件方便导出处理结果python-docx生成Word文档用于创建格式化的报告3.3 获取OCR输出数据为了测试我们的脚本我们需要一些真实的OCR输出数据。有两种方式获取方式一使用DeepSeek-OCR-2的API如果有如果你有API访问权限可以直接调用接口获取JSON格式的识别结果。方式二手动导出数据对于大多数用户更实际的做法是用DeepSeek-OCR-2识别一些文档将识别结果保存为Markdown文件用我们的脚本处理这些Markdown文件我建议你先收集几种不同类型的文档进行测试比如发票增值税发票、普通发票合同或协议会议纪要产品说明书每种类型准备2-3个样本这样我们测试脚本时就能看到不同情况下的处理效果。4. 核心脚本编写让OCR结果自动分类现在进入最核心的部分——编写后处理脚本。我会分步骤讲解每个步骤都有完整的代码示例。4.1 第一步读取和解析OCR输出首先我们创建一个Python脚本文件命名为ocr_processor.pyimport os import re import json import pandas as pd from datetime import datetime from pathlib import Path class OCRPostProcessor: OCR后处理主类 def __init__(self): # 定义文档分类规则 self.category_rules { 发票: [发票, 增值税, 收据, 账单, 付款], 合同: [合同, 协议, 约定书, 备忘录], 会议纪要: [会议, 纪要, 记录, minutes, agenda], 报告: [报告, 分析, 总结, 评估], 其他: [] # 默认分类 } # 关键信息提取规则 self.extraction_rules { 发票: { 发票代码: r发票代码[:]\s*(\S), 发票号码: r发票号码[:]\s*(\S), 开票日期: r开票日期[:]\s*(\S), 金额: r金额[:]\s*([¥\$]?\d[.,]?\d*), 公司名称: r(?:购买方|销售方)[:]\s*([^\n]) }, 合同: { 合同编号: r合同编号[:]\s*(\S), 签订日期: r签订日期[:]\s*(\S), 甲方: r甲方[:]\s*([^\n]), 乙方: r乙方[:]\s*([^\n]), 金额: r金额[:]\s*([¥\$]?\d[.,]?\d*) } } def read_ocr_output(self, file_path): 读取OCR输出文件 try: with open(file_path, r, encodingutf-8) as f: content f.read() return content except Exception as e: print(f读取文件失败: {e}) return None这个类初始化时定义了两组规则分类规则根据文档内容中的关键词来判断文档类型提取规则针对每种文档类型定义要提取哪些关键信息4.2 第二步自动分类文档接下来我们添加文档分类的功能def classify_document(self, content): 根据内容自动分类文档 if not content: return 其他 content_lower content.lower() # 统计每个分类关键词的出现次数 category_scores {} for category, keywords in self.category_rules.items(): if category 其他: continue score 0 for keyword in keywords: # 计算关键词出现次数 score content_lower.count(keyword.lower()) if score 0: category_scores[category] score # 找出得分最高的分类 if category_scores: best_category max(category_scores.items(), keylambda x: x[1])[0] return best_category else: return 其他这个方法的逻辑很简单扫描文档内容看看哪些关键词出现得最多就归到哪一类。比如一个文档里多次出现“发票”、“增值税”、“金额”这些词就会被分类为“发票”。4.3 第三步提取关键信息分类完成后我们根据文档类型提取关键信息def extract_key_info(self, content, category): 提取关键信息 if category not in self.extraction_rules: return {} info {} rules self.extraction_rules[category] for field, pattern in rules.items(): match re.search(pattern, content) if match: info[field] match.group(1).strip() else: info[field] # 额外处理提取表格数据 if 表格 in content or --- in content: table_data self.extract_table_data(content) if table_data: info[表格数据] table_data return info def extract_table_data(self, content): 从Markdown中提取表格数据 lines content.split(\n) table_lines [] in_table False for line in lines: # Markdown表格通常以|开始和结束 if | in line and (--- not in line): in_table True # 清理表格行 clean_line line.strip(|).split(|) clean_line [cell.strip() for cell in clean_line] table_lines.append(clean_line) elif in_table and not line.strip(): # 遇到空行表格结束 break if table_lines: return table_lines return None这里用到了正则表达式来匹配特定的信息模式。比如r发票代码[:]\s*(\S)这个模式可以匹配“发票代码123456”这样的文本并提取出“123456”。4.4 第四步自动归档和保存最后我们把处理好的文档保存到合适的位置def save_document(self, content, category, info, original_path): 保存处理后的文档 # 创建分类文件夹 output_dir Path(processed_docs) / category output_dir.mkdir(parentsTrue, exist_okTrue) # 生成文件名 timestamp datetime.now().strftime(%Y%m%d_%H%M%S) # 尝试使用文档中的关键信息作为文件名的一部分 if 发票号码 in info and info[发票号码]: filename f发票_{info[发票号码]}_{timestamp}.md elif 合同编号 in info and info[合同编号]: filename f合同_{info[合同编号]}_{timestamp}.md else: # 使用原始文件名 original_name Path(original_path).stem filename f{original_name}_{timestamp}.md # 保存Markdown内容 md_path output_dir / filename with open(md_path, w, encodingutf-8) as f: f.write(content) # 保存提取的信息到Excel用于汇总 self.save_to_excel(info, category, timestamp, md_path) return str(md_path) def save_to_excel(self, info, category, timestamp, md_path): 保存提取的信息到Excel汇总表 excel_path Path(processed_docs) / 文档汇总.xlsx # 准备数据行 row_data { 分类: category, 处理时间: timestamp, 文件路径: str(md_path), **info # 展开所有提取的信息 } # 如果Excel文件不存在创建新的 if not excel_path.exists(): df pd.DataFrame([row_data]) else: # 读取现有文件追加新行 df pd.read_excel(excel_path) df pd.concat([df, pd.DataFrame([row_data])], ignore_indexTrue) # 保存Excel文件 df.to_excel(excel_path, indexFalse)这个保存功能做了几件事按照分类创建不同的文件夹用有意义的名称保存文件比如包含发票号码同时把提取的信息汇总到一个Excel表格里方便后续查询和统计5. 完整使用示例处理一批文档现在我们把所有功能整合起来看看完整的处理流程def main(): 主函数批量处理OCR输出文件 processor OCRPostProcessor() # 假设我们的OCR输出文件都在一个文件夹里 input_dir ocr_outputs processed_count 0 print(开始处理OCR输出文件...) print( * 50) # 遍历所有文件 for filename in os.listdir(input_dir): if filename.endswith(.md) or filename.endswith(.txt): file_path os.path.join(input_dir, filename) print(f\n处理文件: {filename}) # 1. 读取文件 content processor.read_ocr_output(file_path) if not content: print( → 读取失败跳过) continue # 2. 分类文档 category processor.classify_document(content) print(f → 分类结果: {category}) # 3. 提取关键信息 info processor.extract_key_info(content, category) print(f → 提取信息: {len(info)} 条) # 4. 保存处理结果 saved_path processor.save_document(content, category, info, file_path) print(f → 已保存到: {saved_path}) processed_count 1 print(\n * 50) print(f处理完成共处理 {processed_count} 个文件) print(f汇总表格: processed_docs/文档汇总.xlsx) if __name__ __main__: main()运行这个脚本你会看到类似这样的输出开始处理OCR输出文件... 处理文件: 发票_20240115.md → 分类结果: 发票 → 提取信息: 6 条 → 已保存到: processed_docs/发票/发票_202401150001_20240320_143022.md 处理文件: 采购合同.md → 分类结果: 合同 → 提取信息: 5 条 → 已保存到: processed_docs/合同/合同_HT2024001_20240320_143023.md 处理文件: 月度会议纪要.md → 分类结果: 会议纪要 → 提取信息: 2 条 → 已保存到: processed_docs/会议纪要/月度会议纪要_20240320_143024.md 处理完成共处理 3 个文件 汇总表格: processed_docs/文档汇总.xlsx6. 高级功能扩展让脚本更智能基础功能已经实现了但我们可以做得更好。下面是一些高级功能的扩展思路6.1 自动重命名图片文件如果你的原始文档是图片可以让脚本自动重命名图片文件与处理后的文档对应def rename_image_file(image_path, info, category): 根据提取的信息重命名图片文件 if not os.path.exists(image_path): return image_path # 构建新文件名 timestamp datetime.now().strftime(%Y%m%d) if category 发票 and 发票号码 in info: new_name f发票_{info[发票号码]}_{timestamp}.jpg elif category 合同 and 合同编号 in info: new_name f合同_{info[合同编号]}_{timestamp}.jpg else: # 保留原文件名但加上分类前缀 original_name os.path.basename(image_path) new_name f{category}_{original_name} # 重命名文件 new_path os.path.join(os.path.dirname(image_path), new_name) os.rename(image_path, new_path) return new_path6.2 自动发送邮件通知对于重要的文档比如大额发票可以设置自动邮件通知import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart def send_notification(info, category): 发送处理完成通知 if category 发票 and 金额 in info: amount info[金额] # 假设金额超过10000元需要通知 try: # 提取数字部分 amount_num float(re.search(r[\d.], amount).group()) if amount_num 10000: send_email( subjectf大额发票处理通知{info.get(发票号码, 未知)}, bodyf已处理一张大额发票\n\n{json.dumps(info, indent2, ensure_asciiFalse)} ) except: pass6.3 集成到工作流中你可以把这个脚本集成到各种工作流中方案一定时自动运行使用Windows的任务计划或Linux的cron job定时扫描某个文件夹自动处理新出现的OCR文件。方案二与DeepSeek-OCR-2直接集成如果你能修改DeepSeek-OCR-2的代码可以在识别完成后直接调用这个后处理脚本。方案三创建简单的Web界面用Flask或Streamlit创建一个简单的Web界面上传图片后自动完成识别处理归档的全流程。7. 常见问题与解决方案在实际使用中你可能会遇到一些问题。这里我总结了一些常见情况和解决方法7.1 问题分类不准确症状发票被分到了“合同”类或者会议纪要被分到了“其他”。可能原因关键词设置不合理文档内容特殊不符合常见模式解决方案# 1. 调整分类规则 self.category_rules { 发票: [发票, 增值税, 专用发票, 普通发票, 电子发票, 收据], 合同: [合同, 协议, 协议书, 合作, 条款, 甲方, 乙方], # ... 其他分类 } # 2. 增加权重机制 # 给某些关键词更高的权重 keyword_weights { 增值税专用发票: 3, # 这个关键词特别重要 发票: 2, 收据: 1, # ... 其他 } # 3. 使用机器学习分类高级 # 如果文档类型很多可以考虑训练一个简单的文本分类模型7.2 问题信息提取不全症状有些关键信息没提取出来或者提取错了。可能原因正则表达式不够全面文档格式多变解决方案# 1. 使用更灵活的正则表达式 # 原来的 r发票代码[:]\s*(\S) # 改进后 r发票代码[:]\s*([^\n]?)(?\n|$) # 2. 多种模式尝试 def extract_with_multiple_patterns(content, patterns): 尝试多种模式提取 for pattern in patterns: match re.search(pattern, content) if match: return match.group(1).strip() return # 3. 使用位置信息如果有JSON数据 # 如果能有JSON格式的OCR输出可以利用文本块的位置信息 # 比如“发票代码”通常出现在文档的右上角7.3 问题处理速度慢症状处理大量文档时速度很慢。解决方案# 1. 批量处理减少文件IO def batch_process(files): 批量处理多个文件 all_results [] for file_path in files: content read_file(file_path) category classify(content) info extract_info(content, category) all_results.append((content, category, info)) # 批量保存 batch_save(all_results) # 2. 使用多线程对于大量文件 import concurrent.futures def process_files_concurrently(file_list): 多线程处理文件 with concurrent.futures.ThreadPoolExecutor(max_workers4) as executor: futures [] for file_path in file_list: future executor.submit(process_single_file, file_path) futures.append(future) # 等待所有任务完成 results [] for future in concurrent.futures.as_completed(futures): results.append(future.result()) return results7.4 问题特殊字符处理症状文档中有特殊符号、换行符等影响处理结果。解决方案def clean_content(content): 清理文本内容 # 替换全角字符为半角 content content.replace(, :).replace(, ,) # 合并多余的空格和换行 content re.sub(r\n{3,}, \n\n, content) content re.sub(r {2,}, , content) # 处理常见的OCR识别错误 corrections { 0: O, # 数字0被识别为字母O 1: I, # 数字1被识别为字母I 5: S, # 数字5被识别为字母S } for wrong, right in corrections.items(): content content.replace(wrong, right) return content8. 总结通过这篇教程我们完成了一个完整的OCR后处理系统。让我们回顾一下核心收获8.1 我们实现了什么自动文档分类让OCR识别出的文档自动归到正确的类别关键信息提取从大段文字中自动找出最重要的信息智能归档保存按照分类和内容特征自动组织文件数据汇总统计所有处理结果自动记录到Excel表格8.2 这个系统的价值在哪里对于个人用户整理扫描的纸质资料不再头疼快速从大量文档中找到需要的信息建立个人的数字文档库对于企业用户财务部门自动整理发票方便报销和做账行政部门自动归档合同和协议项目团队自动整理会议纪要和报告整体上提升文档处理效率减少人工错误8.3 下一步可以做什么如果你已经掌握了基础功能可以考虑这些进阶方向支持更多文档类型简历、名片、证件、报表等更智能的分类使用机器学习模型代替规则匹配集成到现有系统与公司的OA、ERP系统对接增加审核流程对于重要文档加入人工审核环节多语言支持处理英文、日文等其他语言的文档8.4 最后的建议开始使用时我建议你从小处着手先处理一种类型的文档比如发票做好做精逐步完善规则根据实际遇到的情况不断调整分类和提取规则保留人工检查初期可以设置一个抽查机制确保自动处理的准确性做好备份自动化处理前确保原始文件有备份技术的价值在于解决实际问题。DeepSeek-OCR-2已经提供了优秀的识别能力加上我们这套后处理脚本就能形成一个完整的文档数字化解决方案。希望这个教程能帮你真正把OCR技术用起来让文档处理变得轻松高效。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2419675.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!