作为APIcaller识别发票信息

我发现我如果不是更新系列博客(例如django做网站系列),就总会在千面加一个事件的起因。格式之固定简直像极了小学生写作文。
所以……事情的起因是这样的,一位朋友是做财务相关的工作的。有一天向我叙述了一下其中一项工作内容,即打开发票,将信息录入excel,并同步对发票扫描件进行重命名。作为一个热心的python爱好者,自然挺身而出,帮助其解决这个问题。

我的思路

自己调用库

这个小项目的思路可以说是很easy了,无非就是,打开图片,ocr识别,然后进行一系列操作。
说到ocr,我很自然而然的联想到python的两个库

  • PIL
    PIL的功能就是对图片进行一系列操作,如打开,锐化、改变大小、旋转等等,功能丰富。
  • tesseract
    它是一个强大的ocr识别库。

但是最终我没有用这个方案,一来我自己的tesseract没有经过机器学习,识别率低得可怕,二来自己调用的话确实挺麻烦,可能还得自己写个服务器、客户端,但是我急于交货(写完这段代码,我过1024屌丝节(屌丝节这个词是我一个程序员兄弟说的,那是他的自嘲,不过却是我的向往))

腾讯云

在这里我没有打广告,我为什么选择了腾讯云,因为我有很多腾讯云的产品了,再增加一个就是了。
而且它有相对完善的接口,文档也很清楚,识别率奇高,我只要做一个说得过去的APIcaller即可。同时把接口改写一下,封装到类里面去,面向对象的思维有很多好处,我这个脚本虽然是单进程单线程,但是我这个改写做出来之后呢,多线程其实问题也不大。

调用方法

腾讯云发票识别接口

代码

代码其实比较简单的,需要这个思路的可以直接复制,我给用我自己不成熟的面向对象思维封装起来了。注释我写的详细一些。

依赖的库

  • tencentcloud-sdk-python
    主要使用的核心库,集中了最主要的命令
  • PIL
    负责打开图片,压缩图片,因为部分图片过大,请求起来比较慢
  • base64
    负责把图片转化为base64代码,方便解析
  • json
    腾讯云返回的信息是json格式,我要转回python的字典,才可以方便的操作

更详细的内容,见代码注释

#安装tencentcloud-sdk-python库之后方可调用
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.ocr.v20181119 import ocr_client, models
#导入PIL的Image,打开图片,压缩图片用
from PIL import Image
#获取目录下的文件,以及改名必备
import os
#图片转base64,必备
import base64
#腾讯云返回的信息是json格式,我要转回python的字典,才可以方便的操作
import json
import time

#面向对象思维,创建类
class recognition:
    def __init__(self):
    	#requestId和key是腾讯云开通后申请的,我这里保护下隐私,隐藏起来
        self.requestId = "AKIDiBNIFx8aU7JE8n**************"
        self.key = "VllY9VbR1OUJtDH**************"
        #必备参数
        self.Action = "ap-beijing"
	
	#这个方法是把图片转化为base64的方法,并添加类的属性
    def getBase64(self, name):
        with open(name, "rb") as f:
            self.base64_data = base64.b64encode(f.read()).decode()

	#核心部分,图片解析,根据腾讯云的文档来做即可
    def getInformation(self):
        try:
            cred = credential.Credential(self.requestId, self.key)
            httpProfile = HttpProfile()
            httpProfile.endpoint = "ocr.tencentcloudapi.com"
            clientProfile = ClientProfile()
            clientProfile.httpProfile = httpProfile
            client = ocr_client.OcrClient(cred, "ap-beijing", clientProfile)
            req = models.VatInvoiceOCRRequest()
            dic = {"ImageBase64": self.base64_data}
            params = json.dumps(dic)
            req.from_json_string(params)
            self.resp = client.VatInvoiceOCR(req)

        except TencentCloudSDKException as err:
            print(err)

	#解析返回的数据,这个是根据返回的json来做的,他的格式是一个字典列表,即元素是字典的列表,需要遍历,获得想要的发票数据
    def analysis(self):
        self.data = json.loads(self.resp.to_json_string())
        self.fatherName = self.data['VatInvoiceInfos'][6]['Value']
        for i in self.data['VatInvoiceInfos']:
            if i['Name'] == "小写金额":
                self.value = i['Value']
                self.money = self.value.replace("¥", "")
                break

	#方法调用,这里可以开多线程其实,封装在函数里
    def start(self, name):
        self.getBase64(name)
        self.getInformation()
        self.analysis()
        os.rename(name, self.fatherName + "-" + self.money + ".jpg")
        print(self.data)
        print(self.fatherName)
        print(self.money)
#主函数部分应该不用解释了,很easy的方法。
if __name__ == "__main__":
	nameList = os.listdir()
	nameList.remove("main.py")
	for name in nameList:
	    sImg = Image.open(name)
	    w, h = sImg.size
	    dImg = sImg.resize((int(w/2), int(h/2)), Image.ANTIALIAS)
	    dImg.save(name)
	    try:
	        re = recognition()
	        re.start(name)
	    except AttributeError:
	        print(name + "错误")

总结

这个活没啥难度,主要是我进行了面向对象的改写。朋友们有想让我帮忙识别发票的,我可以来哦。

github

连接在此:
github上托管的代码地址

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值