成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

Python實現發(fā)票自動校核微信機器人的方法

瀏覽:148日期:2022-07-24 18:23:59

制作初衷:

外地開了票到公司后發(fā)現信息有錯誤,無法報銷; 公司的行政和財務經常在工作日被問及公司開票信息,影響心情和工作; 引入相應的專業(yè)APP來解決發(fā)票問題對于一般公司成本較高; 看到朋友孟要早睡寫過腳本來解決這個問題,但因為公司場景不相同,無法復用,所以新寫了一個

本代碼使用簡單的封裝方法,并做了比較走心的注釋,希望能給初學Python的小伙伴提供一些靈感,也能讓有實際需求的人可以快速修改、使用。

源碼地址:https://github.com/yc2code/WechatInvoiceParser

P.S. 工具基于微信網頁版,因為微信官方對于賬號有限制,新建的賬號可能無法使用,會報:KeyError: ’pass_ticket’,如圖:

Python實現發(fā)票自動校核微信機器人的方法

所以工具只能使用注冊時間較早的賬號

發(fā)票自動校核微信機器人代碼部分

1. 工具文件 ? Utils包含三個部分:發(fā)票校核類 Invoice、解析數據類 DataParser 和推送日志類 Pushover

Invoice 調用的百度API,上傳圖片信息,得到解析數據; DataParser 對得到的解析數據進行整理,得到發(fā)送給用戶的信息; Pushover 出現調用問題時,第一時間相關信息推送到維護者的設備上。

# -*- coding: utf-8 -*-# Utils.pyimport base64import csvimport osimport timeimport requestsfrom Config import configclass Invoice: ''' 發(fā)票識別類 使用百度發(fā)票識別API,免費使用 官方地址 https://ai.baidu.com/docs#/OCR-API/5099e085 其它功能及配置請移步官網 ''' @staticmethod def get_pic_content(image_path): ''' 方法--打開圖片 以二進制格式打開 ''' with open(image_path, ’rb’) as pic: return pic.read() @staticmethod def parse_invoice(image_binary): ''' 方法--識別圖片 調用百度接口,返回識別后的發(fā)票數據 以下內容基本根據API調用的要求所寫,無需糾結 各類報錯碼在官網文檔可查 百度API注冊及使用教程:http://ai.baidu.com/forum/topic/show/867951 ''' # 識別質量可選high及normal # normal(默認配置)對應普通精度模型,識別速度較快,在四要素的準確率上和high模型保持一致, # high對應高精度識別模型,相應的時延會增加,因為超時導致失敗的情況也會增加(錯誤碼282000) access_token = '你的access_token' api_url = f'https://aip.baidubce.com/rest/2.0/ocr/v1/vat_invoice?access_token={access_token}' quality = 'high' header = {'Content-Type': 'application/x-www-form-urlencoded'} # 圖像數據,base64編碼后進行urlencode,要求base64編碼和urlencode后大小不超過4M, # 最短邊至少15px,最長邊最大4096px,支持jpg/jpeg/png/bmp格式 image_data = base64.b64encode(image_binary) try: data = {'accuracy': quality, 'image': image_data} response = requests.post(api_url, data=data, headers=header) if response.status_code != 200: print(time.ctime()[:-5], 'Failed to get info') return None else: result = response.json()['words_result'] invoice_data = { ’檢索日期’: ’-’.join(time.ctime().split()[1:3]), ’發(fā)票代碼’: result[’InvoiceCode’], ’發(fā)票號碼’: result[’InvoiceNum’], ’開票日期’: result[’InvoiceDate’], ’合計金額’: result[’TotalAmount’], ’價稅合計’: result[’AmountInFiguers’], ’銷售方名稱’: result[’SellerName’], ’銷售方稅號’: result[’SellerRegisterNum’], ’購方名稱’: result[’PurchaserName’], ’購方稅號’: result[’PurchaserRegisterNum’], '發(fā)票類型': result['InvoiceType'] } return invoice_data except: message = '發(fā)票識別API調用出現錯誤' Pushover.push_message(message) return None finally: print(time.ctime()[:-5], '產生一次了調用') @staticmethod def save_to_csv(invoice_data): ''' 方法--日志保存 將識別記錄寫入文件夾下work_log.csv文件 若無此文件則自動創(chuàng)建并寫入表頭 ''' if 'work_log.csv' not in os.listdir(): not_found = True else: not_found = False with open(’./work_log.csv’, ’a+’) as file: writer = csv.writer(file) if not_found: writer.writerow(invoice_data.keys()) writer.writerow(invoice_data.values()) @staticmethod def run(image_path): ''' 主方法 解析完成返回信息,否則返回None ''' image_binary = Invoice.get_pic_content(image_path) invoice_data = Invoice.parse_invoice(image_binary) if invoice_data: Invoice.save_to_csv(invoice_data) return invoice_data return Noneclass DataParser: ''' 數據分析類 對識別返回后的數據進行整理,并于默認信息對比,查看有無錯誤 這里只簡單實現整理信息和檢查名稱和稅號的方法,有興趣可以增加其他豐富的方法 ''' def __init__(self, invoice_data): self.invoice_data = invoice_data def get_detail_message(self): ''' 對得到的發(fā)票信息的格式進行整理 :return: 返回整理好的發(fā)票信息 ''' values = [value for value in self.invoice_data.values()] detail_mess = f'完整信息為:' f'n發(fā)票代碼: {values[1]}n發(fā)票號碼: {values[2]}n開票日期: {values[3]}' f'n合計金額: {values[4]}n價稅合計: {values[5]}n銷售方名稱: {values[6]}' f'n銷售方稅號: {values[7]}n購方名稱: {values[8]}n購方稅號:{values[9]}' return detail_mess def get_brief_message(self): ''' 將信息中的名稱和稅號和默認值進行對比 只做對錯判斷,讀者豐富一下可以增加指出錯誤位置的信息 :return: 返回判斷的信息 ''' if self.invoice_data['購方名稱'] == config['company_name']: brief_mess = '購方名稱正確' else: brief_mess = '!購方名稱錯誤!' if self.invoice_data['購方稅號'] == config['company_tax_number']: brief_mess += 'n購方稅號正確' else: brief_mess += 'n!購方稅號錯誤!' return brief_mess def parse(self): brief_mess = self.get_brief_message() detail_mess = self.get_detail_message() return brief_mess, detail_messclass Pushover: ''' 消息推送類 本次使用Pushover為推送消息軟件(30 RMB,永久,推薦) 官網 https://pushover.net/ 可以向微信一樣把相關信息推送至不同設備 如果不需要可以把相關代碼注釋掉 ''' @staticmethod def push_message(message): message += '>>>來自Python發(fā)票校驗' try: requests.post('https://api.pushover.net/1/messages.json', data={ 'token': '你的Token', 'user': '你的User', 'message': message }) except Exception as e: print(time.ctime()[:-5], 'Pushover failed', e, sep='n>>>>>>>>>>n')

2. 微信機器人文件 ? Wechat包含一個部分:微信處理類 Wechat作用是初始化機器人,對微信的消息進行處理,分析并作出回應。

# -*- coding: utf-8 -*-# Wechat.pyimport osfrom wxpy import *class Wechat: ''' 微信處理類 對微信的消息進行處理,分析并作出回應 ''' def __init__(self, group_name, admin_name): self.bot = Bot() # 類被實例化的時候即對機器人實例化 self.group_name = group_name # 指定群聊名 self.admin_name = admin_name # 管理員微信名 self.received_mess_list = [] # 過濾后的消息列表 self.order_list = [] # 管理命令列表 self.pic_list = [] # 待解析圖片絕對路徑列表 def get_group_mess(self): ''' 方法--獲取消息 獲取所有正常消息,進行過濾后存進消息列表 ''' # 調用此方法時先清空上次調用時列表所存儲的數據 self.received_mess_list = [] for message in self.bot.messages: # 如果為指定群聊或管理員的消息,存入group_mess sender = message.sender.name # >>>這里有一點要注意,如果你是用一個微信作為機器人且作為管理員<<< # >>>然后用這個微信號在群聊發(fā)消息,則信息sender會之指向自己而不是群聊<<< # >>>建議使用單獨一個微信號作為機器人 if sender == self.group_name or sender == self.admin_name: self.received_mess_list.append(message) # 其他的消息過濾掉 self.bot.messages.remove(message) return None def parse_mess(self): ''' 方法--處理群聊消息 過濾獲得的指定群聊消息 設定所有新增群聊圖片的絕對路徑及群聊中產生的文字命令 ''' # 調用此方法時先清空上次調用時列表所存儲的數據 self.pic_list = [] self.order_list = [] # self.group_order = [] for message in self.received_mess_list: # 如果信息類型為圖片,則保存圖片并添加到圖片列表 if message.type == ’Picture’ and message.file_name.split(’.’)[-1] != ’gif’: self.pic_list.append(Wechat.save_file(message)) # 如果消息類型為文字,則視為命令,保存到命令列表中 if message.type == ’Text’: self.order_list.append(message) return None @staticmethod def save_file(image): ''' 方法--存儲圖片 這里使用靜態(tài)方法,是因為本方法和類沒有內部交互,靜態(tài)方法可以方便其他程序的調用 解析名稱,設定絕對路徑,存儲 :param image: 接收到的圖片(可以看成是wxpy產生的圖片類,它具有方法和屬性) :return: 返回圖片的絕對路徑 ''' path = os.getcwd() # 如果路徑下沒有Pictures文件夾,則創(chuàng)建,以存放接收到的待識別圖片 if 'Pictures' not in os.listdir(): os.mkdir('Pictures') # 設定一個默認的圖片格式后綴 file_postfix = 'png' try: # 嘗試把圖片的名稱拆分,分別獲取名稱和后綴 file_name, file_postfix = image.file_name.split(’.’) except Exception: # 當然有時候可能拆分不了,就把默認的后綴給它 file_name = image.file_name # 賦予絕對路徑 file_path = path + ’/Pictures/’ + file_name + ’.’ + file_postfix # 將圖片存儲到指定路徑下 image.get_file(file_path) return file_path def send_group_mess(self, message): ''' 方法--發(fā)送群消息 :param message: 需要發(fā)送的內容 ''' try: # 如果群聊名稱被改變,搜索時會報錯,如果找不到群聊,消息不會發(fā)送 group = self.bot.groups().search(self.group_name)[0] group.send(message) except IndexError: print('找不到指定群聊,信息發(fā)送失敗') return None def send_parse_log(self): ''' 方法--發(fā)送查詢日志 向群聊內發(fā)送查詢日志 ''' try: # 如果群聊名稱被改變,搜索時會報錯,如果找不到群聊,消息不會發(fā)送 group = self.bot.groups().search(self.group_name)[0] except IndexError: print('找不到指定群聊,查詢日志發(fā)送失敗') return None try: group.send_file('./work_log.csv') except: group.send('Oops, no log yet') return None def send_system_log(self): ''' 方法--發(fā)送系統(tǒng)日志 向群聊內發(fā)送查詢日志 ''' try: # 如果群聊名稱被改變,搜索時會報錯,如果找不到群聊,消息不會發(fā)送 group = self.bot.groups().search(self.group_name)[0] except IndexError: print('找不到指定群聊,系統(tǒng)日志發(fā)送失敗') return None try: group.send_file('./system_log.text') except: group.send('System log not found') return None

3. 主文件 ? Main包含一個main函數,一部分為發(fā)票識別和處理,另一部分對于指令做出反應。

# -*- coding: utf-8 -*-# Main.pyimport timefrom Utils import Invoice, DataParserfrom Config import configfrom Wechat import *# Author : 達希# Email : way2go.dash@gmail.comdef main(): ''' 主方法 一部分為發(fā)票識別和處理,另一部分對于指令做出反應 ''' # 輸出重定向,將print語句都寫進系統(tǒng)日志文件 file = open('./system_log.text', 'a+') sys.stdout = file # 實例化微信機器人,傳入群聊名和管理員名 wechat = Wechat(config['group_name'], config['admin_name']) while True: time.sleep(1) wechat.get_group_mess() wechat.parse_mess() # 若群聊有要處理的圖片,則迭代解析 if wechat.pic_list: for pic in wechat.pic_list: invoice_data = Invoice.run(pic) if invoice_data: data_parser = DataParser(invoice_data) brief_mess, detail_mess = data_parser.parse() wechat.send_group_mess(detail_mess) # 先發(fā)送發(fā)票識別詳細信息 time.sleep(0.5) wechat.send_group_mess(brief_mess) # 返回名稱和稅號是否有錯誤 else: wechat.send_group_mess('請求未成功,請重試或聯(lián)系管理員') # 若有相關命令,則做出相應反應 if wechat.order_list: for order in wechat.order_list: if '開票信息' in order.text: wechat.send_group_mess(config['company_name']) time.sleep(0.5) wechat.send_group_mess(config['company_tax_number']) elif 'SEND LOG' in order.text: wechat.send_parse_log() elif 'SEND SYSTEM LOG' in order.text: wechat.send_system_log() elif 'BREAK' in order.text: wechat.send_group_mess('收到關機指令,正在關機') file.close() return Noneif __name__ == '__main__': main()

4. 配置文件 ? Config

包含微信的配置文件信息

config = { 'group_name': '發(fā)票校核ASAP', # 校核群聊名稱,由于本代碼默認沒有同名群聊,所以建議設為復雜值 'admin_name': '達希', # 管理員微信名(非備注) 'company_name': '代碼網絡技術無限公司', # 默認購方名稱 'company_tax_number': 'XXX00000000000XXX' # 默認購方稅號}

Python實現發(fā)票自動校核微信機器人的方法

另外,代碼在運行時會在同文件夾下創(chuàng)建一個Picture的文件夾,用于存儲待解析的圖片,會創(chuàng)建 work_log.csv 文件,用于存儲識別信息的記錄,還有 system_log.text 用于輸出運行相應的日志。

由于本身需求較少,所以以上代碼功能相對單薄,僅僅作為一個輔助的小腳本使用。若要進行優(yōu)化完善,wxpy庫提供了很多豐富的功能,可以在此基礎上打造更加合理完善的,符合個性化需求的微信機器人。

總結

到此這篇關于Python制作發(fā)票自動校核微信機器人的文章就介紹到這了,更多相關Python制作發(fā)票自動校核微信機器人內容請搜索好吧啦網以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: 微信 Python
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
91精品福利在线一区二区三区 | 91免费看片在线观看| 一本大道av伊人久久综合| 亚洲人123区| 欧美巨乳波霸| 精品美女在线观看| 粉嫩久久99精品久久久久久夜| 欧美日韩高清影院| 精品一区二区三区久久| 欧美性xxxxx极品少妇| 水蜜桃久久夜色精品一区的特点 | 欧美日韩一本到| 免费观看一级欧美片| 91高清在线观看| 天天综合色天天综合| 久久网站免费| 日韩精品一二区| 色综合久久久久久久久久久| 日韩精品电影一区亚洲| 色国产综合视频| 麻豆视频观看网址久久| 欧洲精品在线观看| 精品一区中文字幕| 4438x亚洲最大成人网| 国产精品亚洲一区二区三区在线| 制服丝袜成人动漫| 成人伦理片在线| 国产日产亚洲精品系列| 国产综合精品一区| 国产精品免费丝袜| 136国产福利精品导航网址| 亚洲蜜桃精久久久久久久| 国产一区二区三区高清| 亚洲成人黄色小说| 欧美亚洲一区二区在线| 国内国产精品久久| 欧美xxxx老人做受| 色综合天天综合网天天狠天天| 国产亚洲成aⅴ人片在线观看| 欧美黄色一区二区| 亚洲色图制服丝袜| 美女尤物久久精品| 精品一区二区影视| 精品日韩99亚洲| 91小视频免费看| 国产精品久99| 国产视频精品网| 蜜桃免费网站一区二区三区| 7799精品视频| 99精品视频一区二区| 综合网在线视频| 老妇喷水一区二区三区| 久久99久国产精品黄毛片色诱| 91精品国产欧美一区二区成人 | 红桃视频国产精品| 亚洲摸摸操操av| 色婷婷综合久久久中文一区二区| 国内成人精品2018免费看| 欧美mv和日韩mv国产网站| 狠狠88综合久久久久综合网| 亚洲午夜av在线| 欧美日韩一卡二卡三卡| www.一区二区| 亚洲精品精品亚洲| 精品视频一区 二区 三区| 99久久er热在这里只有精品66| 亚洲视频电影在线| 欧美在线|欧美| 91首页免费视频| 亚洲最新视频在线观看| 欧美日韩精品三区| 午夜久久tv| 日韩专区在线视频| 精品剧情在线观看| 国产精品久久久久9999高清| 国产伦精品一区二区三区在线观看| 国产欧美精品一区二区色综合朱莉 | 性8sex亚洲区入口| 国产一区二区电影| 中文字幕的久久| 色综合久久久久综合99| 不卡电影一区二区三区| 亚洲精品高清在线观看| 欧美日本乱大交xxxxx| 欧美亚韩一区| 日韩二区三区四区| 精品国产91洋老外米糕| 国产亚洲亚洲| 国产精品18久久久久久久久| 亚洲视频免费在线观看| 欧美日韩在线观看一区二区| 欧美激情视频一区二区三区在线播放| 亚洲国产精品一区二区久久| 欧美电视剧在线观看完整版| 国产日韩免费| 成人一级片网址| 亚洲成人自拍网| 欧美一区二区三区小说| 日韩视频精品在线观看| 狠狠色狠狠色综合日日91app| 国产精品久久网站| 欧美色国产精品| 亚洲高清二区| 成人小视频在线| 天天综合色天天综合色h| 欧美韩国一区二区| 欧美日韩日日骚| 夜夜爽av福利精品导航| 成人禁用看黄a在线| 亚洲超碰精品一区二区| 国产女同互慰高潮91漫画| 欧美在线看片a免费观看| 欧美欧美全黄| 国产专区综合网| 亚洲国产综合91精品麻豆| 国产三区在线成人av| 欧美日韩国产小视频| 一区二区三区偷拍| 你懂的国产精品永久在线| 日韩av一区二区在线影视| 国产精品国产三级国产三级人妇 | 久久精品人人做人人爽人人| 日本乱人伦aⅴ精品| 国产精品激情| 高清成人免费视频| 日韩国产高清影视| 国产精品高潮呻吟久久| 日韩欧美一区在线观看| 日本高清视频一区二区| 日韩五码在线| 91亚洲永久精品| 国产一区日韩二区欧美三区| 亚洲国产精品久久不卡毛片| 国产精品每日更新在线播放网址| 欧美狂野另类xxxxoooo| 久久这里只有| 99精品视频免费观看视频| 欧美在线视频二区| 成人精品gif动图一区| 美女脱光内衣内裤视频久久影院| 亚洲欧美日韩久久精品| 精品福利在线导航| 欧美肥妇bbw| 欧美性色综合网| 久久影院亚洲| 国产精品亚洲一区| 亚洲国产欧美日韩| 国产精品对白刺激久久久| 91丨九色丨国产丨porny| 粉嫩欧美一区二区三区高清影视 | 国产清纯在线一区二区www| 91精品国产欧美日韩| 日本道免费精品一区二区三区| 亚洲一二三区精品| 欧美黄在线观看| 99国产一区二区三精品乱码| 国产乱码精品一区二区三区av| 麻豆91在线播放免费| 天堂资源在线中文精品| 一区二区三区小说| 亚洲人成网站影音先锋播放| 欧美国产一区视频在线观看| 久久亚区不卡日本| 精品成人在线观看| 精品久久国产97色综合| 日韩一区二区三区视频在线| 欧美精品久久久久久久久老牛影院| 日本福利一区二区| 免费久久久一本精品久久区| 国产情侣一区| 亚洲美女一区| 国产欧美不卡| 国产精品亚洲综合色区韩国| 国产一区二区三区久久久久久久久 | 91极品美女在线| 色悠悠久久综合| 亚洲一区欧美激情| 国产伦精品一区二区三区视频黑人| 亚洲美女黄色| 亚洲资源av| 国产伦理一区| 久久aⅴ国产紧身牛仔裤| 免费毛片一区二区三区久久久| 免费看亚洲片| 久久综合久久久| 欧美亚日韩国产aⅴ精品中极品| 欧美少妇xxx| 欧美电影一区二区| 日韩精品一区二区三区三区免费| 精品国产不卡一区二区三区| 久久久久久久久久久电影| 国产日韩欧美精品综合| 国产精品人妖ts系列视频| 国产精品久久久久影院亚瑟 | 亚洲电影第三页| 日精品一区二区| 看片网站欧美日韩| 国产精品99久久久久久久女警 | 亚洲激情自拍| 国产伦一区二区三区色一情|