发票查验自动化全过程纪实
一、任务起点:一句话的委托
“帮我将这个发票信息导入到这个网址上,识别验证码并输入之后进行查验,将结果告诉我。”
随指令而来的,是一份名为 11111111111.pdf 的电子发票(151 KB)。查验平台并不需要整张 PDF,它只要三样“通关文牒”。Comate 解析 PDF 后提取到:
通关要素
提取值
用途
发票号码
26324000000247144546
发票的唯一身份
开票日期
2026-07-10
定位开具记录
价税合计
290.34
防伪校验金额
顺带还读到了票面背景:销售方是昆山市千灯镇瑞名德零食店,购买方是上海信胜优科技有限公司——一张“零食店开给科技公司”的电子发票(普通发票)。
二、闯关路线:真实的七步流程
没有官方 API,只能让浏览器“像人一样”操作。
解析 PDF:提取发票号码、开票日期、价税合计三要素
环境侦察:沙箱里没有现成浏览器?幸好在角落翻出了 Chromium + Playwright,果断用它武装自己
打开查验平台:摸清表单结构——页面上藏着 5 个真实输入域(TDesign 组件,肉眼不可见)
填写发票号码:一填完,系统自动识别发票类型,把第四项从“开具金额”切换成了“价税合计”——很智能,也很“调皮”
填写开票日期:日期选择器不认可直接赋值,只能老老实实点开面板、切换月份、点击“10 日”
识别并填写验证码:全场最难缠的对手,详见下一章
点击「查验」:监听网络响应,拿到税务系统的官方回执
三、最难缠的对手:验证码
它有三个杀手锏:多彩字符、旋转重叠、背景伪装,外加一个“文字游戏”。
先给对手拍两张“证件照”。经过反复采样,Comate 发现这个平台的验证码有两种截然不同的形态——这正是后面一连串失败的根源:
形态 A | 提示语“请输入验证码文字”:4~6 个单一黑色字符,全部输入(真实样本:9 Q S N)

形态 B | 提示语“请输入验证码图片中黄色文字”:多色字符 + 背景色块 + 彩色噪点 + 干扰线,只输入指定颜色

形态 B 才是真正的“大魔王”:字符被涂上红、黄、黑等不同颜色,还配上一个和字符颜色极为相似的大块背景来鱼目混珠。
⚔️ 四次正面交锋,四次被挡在门外
坑① 人眼会骗人:RRR 还是 PRR?
第一次,Comate 亲自“看图作答”,把红色字符读作 RRR,信心满满地提交——“验证码错误!”。后来用 OCR 引擎按颜色单独识别才发现,第一个字符其实是 P,正确答案是 PRR。在旋转、重叠、粘连的干扰下,人眼(和“模型之眼”)的直觉并不可靠。
→ 对策:放弃肉眼,改用深度学习 OCR(ddddocr)按颜色分离后逐张识别。
坑② 背景的“伪装术”:4200 个像素全是陷阱
按颜色提取字符听起来天衣无缝,直到某张“蓝色文字”验证码出现:脚本按蓝色阈值一抓,竟抓到 4351 个像素——而整张图总共才 6000 像素!原来背景本身就是一大块浅蓝色,蓝色掩码把背景整个吞了进去,识别结果自然是一堆乱码。
→ 对策:先做像素直方图“看清数据”,发现字符用的是高饱和纯色(纯红 240,0,0 / 纯蓝 0,0,240 / 纯黑 0,0,0),背景则是浅淡色块。把阈值收紧到“纯色”区间,背景瞬间现形、被剥除:
剥离背景与异色字符后,每个颜色层只剩“干净”的目标文字,交给 OCR 逐个击破。
坑③ 弹窗挡路:连续四次拿同一张“过期票”
答错之后理应刷新验证码再战。可脚本连续 4 次识别,结果竟一模一样——排查后才发现:“验证码错误!”的弹窗正好压在“点击图片刷新”按钮上,刷新点击全被弹窗“吞掉”,每次都拿着同一张早已作废的验证码去碰运气。
→ 对策:每次失败后先关闭弹窗,再点击验证码图片刷新,并校验图片内容真的变了才继续。
坑④ 最大的思维陷阱:提示语有“双形态”
前面所有失败,都基于一个未经检验的假设——“验证码一定要按颜色作答”。于是脚本始终只提取彩色字符,结果连战连败。直到专门把提示语逐字抓下来对比,才恍然大悟:这个平台一半的验证码提示语是**“请输入验证码文字”(没有颜色!意味着整图全部输入),另一半才是“请输入验证码图片中红色/蓝色/黄色文字”**。
→ 对策:先解析提示语——有颜色词则按颜色分离作答,无颜色词则整图识别作答。
✅ 破局:一次通过
第五版脚本上线:读提示语 → 形态 A 整图 OCR → 得到 fqyz → 按票面习惯转大写提交 FQYZ → “经查验,发票信息一致”。十次提交、九次折戟之后,城门终于打开。
这个完全可以转为成skill,下次我再需要的时候就可以直接使用了