影刀RPA新手教程:OCR文字识别实战——发票识别验证码与截图文字提取
一、OCR指令怎么用:截图→识别→取文本
影刀的OCR在指令面板搜"OCR"就能看到。核心指令就一个:【OCR文字识别】。
三件套:
- 截图——指定屏幕区域(或窗口/全屏)
- OCR识别——把截图丢给OCR引擎
- 取文本——从识别结果里提取关键词
最简流程:
1. 截取屏幕区域 (x=100, y=200, width=400, height=200) 2. OCR文字识别(截图变量) → 识别结果 3. 打印(识别结果)如果要识别指定窗口:
1. 截取窗口("记事本") → 截图 2. OCR文字识别(截图) → 文本识别前两个优化必做:
- 截图范围尽可能精确——全屏截图OCR又慢又容易误识别多余文字,精确到只有目标文字的区域
- 如果背景杂乱,先用图像处理提高对比度(灰度化/二值化),识别率翻倍
二、发票识别实战
发票识别的核心需求:从发票图片上提取金额、日期、发票号。
完整流程:
步骤1:加载发票图片 读取文件 → 保存为图片变量 步骤2:定位发票关键区域 发票号通常右上角 金额在右下角"合计金额"附近 日期在中间偏上 步骤3:分别截取各区域 截取发票号区域 → ocr_发票号 截取金额区域 → ocr_金额 截取日期区域 → ocr_日期 步骤4:正则清洗OCR结果 OCR原始输出:"发票号码: 4401234567 (电子)" 正则提取: 用 \d{10,12} 提取发票号 OCR原始输出:'合计金额(大写):零圆零角零分 小写:¥1,580.00' 正则提取: 用 [\d,]+\.\d{2} 提取金额 OCR原始输出:'开票日期:2024年06月25日' 正则提取: 用 \d{4}年\d{2}月\d{2}日 提取日期正则清洗是关键——OCR识别出来的不是干净的"1580.00",而是带着"合计金额"“小写”"¥"这些杂质的字符串。
Python块里做正则清洗(比影刀指令快):
importredefclean_invoice_data(ocr_text):# 正则提取发票号invoice_no=re.search(r'发票号码[::]\s*(\d{10,12})',ocr_text)inv_no=invoice_no.group(1)ifinvoice_noelse''# 正则提取金额amount_pat=re.search(r'[合小]计[金额]*[::].*?([\d,]+\.\d{2})',ocr_text)amount=amount_pat.group(1).replace(',','')ifamount_patelse''# 正则提取日期date_pat=re.search(r'(\d{4})年(\d{1,2})月(\d{1,2})日',ocr_text)date=f"{date_pat.group(1)}-{date_pat.group(2).zfill(2)}-{date_pat.group(3).zfill(2)}"ifdate_patelse''return{'发票号':inv_no,'金额':amount,'日期':date}# 输入来自影刀的ocr结果变量result=clean_invoice_data(ocr_text)第一种发票格式的正则好使,换一种发票格式就废了。建议多收集几种发票模板,每种写一套正则。
我第一次做发票识别时匹配了3个客户的发票模板,第4个客户的发票排版完全不同——金额不在右下角而在中下部。正则全挂。后来改成先OCR全图,再关键词定位——找到"合计金额"四个字,从它后面截取50个字符,再用正则。这套逻辑适配度就高很多。
三、验证码识别:能过就过,过不了上打码平台
影刀的OCR对简单的验证码(纯数字、无干扰线、无扭曲)识别率还可以——大概60%-70%。复杂验证码(字母数字混合、带噪点、变形、滑块)就不行了。
简单数字验证码的流程:
1. 截取验证码图片区域(精确到验证码本身,不要截多余区域) 2. OCR文字识别(验证码截图) → 验证码文本 3. 输入验证码 4. 如果登录失败 → 刷新验证码 → 重新识别如果OCR老识别错——加个预处理。
Python块做图片预处理:
fromPILimportImage,ImageFilter,ImageEnhanceimportiodefpreprocess_captcha(img_bytes):# img_bytes来自影刀的截图数据img=Image.open(io.BytesIO(img_bytes))# 转灰度img=img.convert('L')# 提高对比度enhancer=ImageEnhance.Contrast(img)img=enhancer.enhance(2.0)# 二值化(黑白分明)threshold=128img=img.point(lambdap:255ifp>thresholdelse0)# 去噪(可选)img=img.filter(ImageFilter.MedianFilter(3))# 转回bytesoutput=io.BytesIO()img.save(output,format='PNG')returnoutput.getvalue()# 返回预处理后的图片 → 再用影刀OCR识别OCR搞不定的验证码——对接第三方打码平台。
流程:
1. 截取验证码图片 2. HTTP请求(打码平台API) → 传入图片Base64 3. 返回识别结果 4. 输入登录框市面上打码平台(快识别、图鉴、超级鹰等)API都差不多——一个Base64编码的图片扔过去,返回数字字母串。一次几分钱到一毛钱。识别率95%以上。
注意:尽量别依赖打码平台——流程稳定性取决于网络和第三方服务。能绕过验证码的就绕过(cookie保持登录态、减少登录频次)。
四、截图文字提取:全屏截了再找关键字
场景——一个监控大屏,上面有实时数据,不能通过API获取,只能截屏再用OCR。
步骤1:全屏截图 截取屏幕区域(全屏) → 截图 步骤2:OCR全图 OCR文字识别(截图) → 全量文本 步骤3:关键字提取 查找"今日销售额" → 取后面数字 查找"在线设备数" → 取后面数字 查找"告警信息" → 取后面文本Python块实现关键字提取:
importredefextract_kpi(ocr_full_text):result={}# 提取销售额sales_match=re.search(r'今日销售额[::]\s*([\d,]+\.?\d*)\s*万元?',ocr_full_text)result['今日销售额']=sales_match.group(1)ifsales_matchelse'0'# 提取在线设备数device_match=re.search(r'在线设备数[::]\s*(\d+)',ocr_full_text)result['在线设备数']=device_match.group(1)ifdevice_matchelse'0'returnresult# 返回给影刀kpi=extract_kpi(ocr_text)全屏OCR的坑——识别出来的文本很多是乱序的。监控大屏上数字分布在不同位置,OCR可能先读左边再读右边,中间穿插识别。所以取数字时尽量用正则去匹配上下文关键字,别按行号取。
五、OCR五大坑和解决方案
坑1:识别准确率不够
纯文字识别率大概90%,但加上杂乱的背景、特殊字体、颜色干扰,准确率直接掉到60%。
解决方案:
- 截图前先用图像增强——转灰度、二值化、去噪
- 缩小截图范围——只截需要的文字区域,不截多余背景
- 文字多个来源验证——比如金额既OCR识别又通过位置计算双重校验
坑2:特殊字符识别错误
OCR最常见的错误:0和O不分、1和l不分、逗号和点号混淆、¥识别成Y。
解决方案:根据业务逻辑约束修正。发票号里不可能有字母O,直接替换成0。金额里¥后面的数字不可能有字母。
坑3:手写体识别率极低
印刷体OCR准确率90%+,手写体只有40%不到。签名、手写备注——OCR基本废了。
解决方案:手写体区域单独标注,人工处理。或者用专门的深度学习OCR模型(PaddleOCR手写模型),但需要在Python里额外集成。
坑4:背景干扰严重
发票的底纹、水印、印章会严重干扰OCR。红色印章盖在黑色文字上,OCR可能把印章纹路当成文字辨认。
解决方案:
- 先用颜色过滤去印章(红色通道分离)
- 提高对比度后二值化,把浅色背景滤掉
坑5:多行混排识别错乱
表格里的数据——表头和内容可能被OCR混在一起。比如"姓名张三年龄25"而不是"姓名 张三\n年龄 25"。
解决方案:截图范围精确到单元格级别,一格格单独识别。或者用PaddleOCR的表格识别模式。
六、批量发票识别→写入Excel完整实战
100张发票图片放在一个文件夹,逐张识别并提取数据存入Excel。
--- 主流程 --- 文件夹路径 = "D:/发票/" 文件列表 = 获取文件列表(文件夹路径) 创建Excel("发票汇总.xlsx") 写入表头("发票号", "金额", "日期", "文件名") 循环: file in 文件列表: 读取文件(file) → 图片变量 OCR识别(图片变量) → ocr文本 Python块 → 正则清洗(ocr文本) → 返回: 发票号, 金额, 日期 写入Excel(发票号, 金额, 日期, file) 打印("处理完成: " + file)Python正则清洗块(放在流程的资源文件里。):
importredefparse_invoice(ocr_result):# 多模板匹配# 模板1:标准增值税发票inv_no_1=re.search(r'发票号码[::]\s*(\d{12})',ocr_result)amount_1=re.search(r'[合小]计[金额]*[::].*?([\d,]+\.\d{2})',ocr_result)date_1=re.search(r'(\d{4})\s*年\s*(\d{1,2})\s*月\s*(\d{1,2})\s*日',ocr_result)ifinv_no_1andamount_1:return{'发票号':inv_no_1.group(1),'金额':amount_1.group(1).replace(',',''),'日期':f"{date_1.group(1)}-{date_1.group(2).zfill(2)}-{date_1.group(3).zfill(2)}"}# 模板2:电子发票inv_no_2=re.search(r'(\d{20})',ocr_result)# 电子发票号20位amount_2=re.search(r'金额\s*[¥¥]?\s*([\d,]+\.\d{2})',ocr_result)ifinv_no_2andamount_2:return{'发票号':inv_no_2.group(1),'金额':amount_2.group(1).replace(',',''),'日期':''}# 都没匹配到return{'发票号':'','金额':'','日期':''}# 输出result=parse_invoice(ocr_text)通过多模板匹配,不同格式的发票走不同正则——适配度最大化。
home.linyan.cloud —— 影刀RPA自动化解决方案
内容标签:影刀RPA #OCR文字识别 #发票识别 #验证码 #截图提取 #正则清洗
作者:林焱