发票查验,发票采集,免验证码,批量查验,系统集成,代码分享之一

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 发票查验-免验证码,支持批量查验,系统集成,代码分享,有测试环境,从发票采集到发票查验再到查验结果应用的闭环实现

         最近工作上有个发票查验真伪的需求,由于发票数量不多,我都是让业务员把发票拍照然后通过系统把照片上传上来,然后人工到国税发票查验平台输入发票信息进行查验,但是现在发票数量越来越多,人工查验的效率太低,实在是处理不过来了。后来在网上看到一个大佬写的自动发票查验的文章和提供的测试地址: 发票查验测试链接,我觉得他的这种方法很不错,后来又进一步了解了一下他的大概实现逻辑,再加上我的一些想法和实践总结如下,分享出来供大家参考一下,希望有这方面经验的大佬多多指教。

       言归正传,发票查验其实就是在国家发票查验平台上输入发票代码、发票号码、开票日期、开票金额或校验码后六位来查询发票的详情。这里面还有一个验证码,验证码是用数字、字母和汉字组成的,说实在的有时候我都看不清楚验证码是什么,这个输入验证码的动作非常耗时,有时需要输入几遍才能通过。如果能够自动识别出验证码是什么,那就完全可以通过RPA机器人流程自动化处理来模拟人工输入,然后再直接抓取发票查验结果网页里面Element的value值获取所有的发票票面信息。当然我这种想法还不是最快的方式,刚才说的那位大佬他都不需要加载出网页,直接通过后台代码就能进行发票验证码的识别和post验证数据到国税平台,并解析出国税平台response回来的发票详细数据。他的这种方式我还没试验成功,但他提供的测试页面发票查询速度是真的快。

       验证码识别第一步我是先去掉多余的颜色,因为验证码是需要我输入红色、蓝色、黑色、黄色期中一种颜色的字符,我先把它要求颜色以外的颜色去掉,去色的代码我写的如下:

img = Image.open(fileFullPath)
img = img.convert("RGB")
pixdata = img.load()
for y in range(img.size[1]):
    for x in range(img.size[0]):
        pix = pixdata[x, y]
        if colorType == '2':   # 255, 0, 0 红色
            if pix[0] >= 128 and pix[1] < 128 and pix[2] < 128:
                pixdata[x, y] = (0, 0, 0)
            else:
                pixdata[x, y] = (255, 255, 255)
        elif colorType == '3':  # 255, 255, 0 黄色
            if pix[0] > 128 and pix[1] > 128 and pix[2] < 128:
                pixdata[x, y] = (0, 0, 0)
            else:
                pixdata[x, y] = (255, 255, 255)
        elif colorType == '1':   # 0, 0, 255 蓝色
            if pix[0] < 128 and pix[1] < 128 and pix[2] > 128:
                pixdata[x, y] = (0, 0, 0)
            else:
                pixdata[x, y] = (255, 255, 255)
        else:   # 0, 0, 0  # 黑色
            if pix[0] < 128 and pix[1] < 128 and pix[2] < 128:
                pixdata[x, y] = (0, 0, 0)
            else:
                pixdata[x, y] = (255, 255, 255)

image.gif

去色之后只留下了要识别的字符。然后我用的是百度飞浆的PaddleOCR来实现图片的识别,我试验了它的大、中、小三个模型,发现ch_PP-OCRv4这套模型的识别速度和稳定性最好,PaddleOCR的本地话部署网上有不少教程,部署没有什么难度,识别率能到60%,识别失败的情况多是字符中含有中文造成的。

       有了识别好的验证码下一步就是RPA了,我开始时是写RPA的脚本,后来发现这个过程太痛苦了,不同发票类型的查验结果界面还不一样,后来我发现用edge浏览器的webview2控件直接打开国税发票查询页面,这样就可以通过Selenium.WebDriver来操作浏览器,并可以通过命令行直接获得界面上Element的值,代码示例如图所示

JDCFPObject = JDCFP()
JDCFPObject.skph = getElementText('jqbm_jdcfp')
JDCFPObject.ghdw = getElementText('ghdw_jdcfp')
JDCFPObject.sfzhm = getElementText('gfsbh_jdcfp')
JDCFPObject.xhdwmc = getElementText('xhdwmc_jdcfp')
JDCFPObject.nsrsbh = getElementText('nsrsbh_jdcfp')
def getElementText(elementId):
    try:
        element = driver.find_element(By.ID, elementId)
        textStr = element.text
        return textStr
    except Exception as e1:
        #err = repr(e1)
        #raise Exception('获取id为:' + elementId + ' 的text出错(' + err + ')')
        return ''

image.gif

       这种方法获取到发票查验结果后就可以直接写代码和现有的系统做集成了。我这套方案查验一张发票大概需要10秒左右,比起那位大佬的查询速度慢很多。我这套方案核心就在于发票验证码的识别上,慢也是因为这个环节识别的验证码有一半的机会不正确,需要反复进行识别,后续我打算用一些打过标记的验证码来训练一下PaddleOCR的模型,估计会提高不少识别效率。总之每月初时几百张发票大概大半天的时间就可以自动查验完毕。这个效率对我来说是够用了,我是真没搞明白他是怎么实现这么快的查验速度的,希望有知道的大佬共享一下实现方案。

相关实践学习
基于阿里云短信服务的防机器人验证
基于阿里云相关产品和服务实现一个手机验证码登录的功能,防止机器人批量注册,服务端采用阿里云ECS服务器,程序语言选用JAVA,服务器软件选用Tomcat,应用服务采用阿里云短信服务,
相关文章
|
26天前
|
监控 安全 测试技术
在实施自动化和持续集成的过程中,如何确保代码的安全性和合规性?
在实施自动化和持续集成的过程中,如何确保代码的安全性和合规性?
|
2月前
|
安全 算法 Java
数据库信息/密码加盐加密 —— Java代码手写+集成两种方式,手把手教学!保证能用!
本文提供了在数据库中对密码等敏感信息进行加盐加密的详细教程,包括手写MD5加密算法和使用Spring Security的BCryptPasswordEncoder进行加密,并强调了使用BCryptPasswordEncoder时需要注意的Spring Security配置问题。
175 0
数据库信息/密码加盐加密 —— Java代码手写+集成两种方式,手把手教学!保证能用!
|
3月前
|
前端开发 C++ Windows
C++生成QML代码与QML里面集成QWidget
这篇文章介绍了如何在C++中生成QML代码,以及如何在QML中集成QWidget,包括使用Qt Widgets嵌入到QML界面中的技术示例。
|
4月前
|
Java Devops 持续交付
探索Java中的Lambda表达式:简化代码,提升效率DevOps实践:持续集成与部署的自动化之路
【8月更文挑战第30天】本文深入探讨了Java 8中引入的Lambda表达式如何改变了我们编写和管理代码的方式。通过简化代码结构,提高开发效率,Lambda表达式已成为现代Java开发不可或缺的一部分。文章将通过实际例子展示Lambda表达式的强大功能和优雅用法。
|
4月前
|
监控 前端开发 JavaScript
ARMS集成监控代码
【8月更文挑战第24天】
85 6
|
4月前
|
jenkins 持续交付 网络安全
利用 Jenkins 实现持续集成与持续部署-代码拉取终端的配置
【8月更文挑战第30天】在Jenkins服务器中,git和Gitee是常用的代码拉取终端。Git作为分布式版本控制系统,具备出色的灵活性和可扩展性;而Gitee则在国内网络环境下表现更佳,适合团队协作。Git配置包括安装、设置用户信息及生成SSH密钥等步骤;Gitee配置也类似,需注册账号、创建仓库、配置基本信息并设置远程仓库地址。开发人员提交代码后,可通过Webhook、定时轮询或事件监听等方式触发Jenkins动作,确保持续集成和部署高效运行。正确配置这些触发机制并通过测试验证其有效性至关重要。
70 2
|
3月前
|
jenkins 持续交付 网络安全
利用 Jenkins 实现持续集成与持续部署-代码拉取终端的配置
安装Git、配置用户信息、生成SSH密钥以及在Gitee上创建项目仓库等。
83 0
|
4月前
|
C# Windows 开发者
当WPF遇见OpenGL:一场关于如何在Windows Presentation Foundation中融入高性能跨平台图形处理技术的精彩碰撞——详解集成步骤与实战代码示例
【8月更文挑战第31天】本文详细介绍了如何在Windows Presentation Foundation (WPF) 中集成OpenGL,以实现高性能的跨平台图形处理。通过具体示例代码,展示了使用SharpGL库在WPF应用中创建并渲染OpenGL图形的过程,包括开发环境搭建、OpenGL渲染窗口创建及控件集成等关键步骤,帮助开发者更好地理解和应用OpenGL技术。
296 0
|
4月前
|
开发者 C# UED
WPF与多媒体:解锁音频视频播放新姿势——从界面设计到代码实践,全方位教你如何在WPF应用中集成流畅的多媒体功能
【8月更文挑战第31天】本文以随笔形式介绍了如何在WPF应用中集成音频和视频播放功能。通过使用MediaElement控件,开发者能轻松创建多媒体应用程序。文章详细展示了从创建WPF项目到设计UI及实现媒体控制逻辑的过程,并提供了完整的示例代码。此外,还介绍了如何添加进度条等额外功能以增强用户体验。希望本文能为WPF开发者提供实用的技术指导与灵感。
169 0
|
4月前
|
存储 开发者 C#
WPF与邮件发送:教你如何在Windows Presentation Foundation应用中无缝集成电子邮件功能——从界面设计到代码实现,全面解析邮件发送的每一个细节密武器!
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中集成电子邮件发送功能,详细介绍了从创建WPF项目到设计用户界面的全过程,并通过具体示例代码展示了如何使用`System.Net.Mail`命名空间中的`SmtpClient`和`MailMessage`类来实现邮件发送逻辑。文章还强调了安全性和错误处理的重要性,提供了实用的异常捕获代码片段,旨在帮助WPF开发者更好地掌握邮件发送技术,提升应用程序的功能性与用户体验。
71 0