中文编程,最精致的python访客登记系统实例项目,微信机器人不再只当人工智障------07 - 浩海泛舟的文章 - 知乎 https://zhuanlan.zhihu.com/p/51771041
泛舟n天没更新,终于把这篇琢磨出来了.
在泛舟的零基础入门系列里,开篇就指明了编程就是一个 数据输入>>>方法计算>>>输出结果 这个恒久不变的套路.或者可以装一点,叫道生一,一生二,二生三,三生万物.所有的编程,都是这样一个连环套中套.小套大再更大套大一直下去.
而回到我们的正题,就是我上上一篇的代码,可以算是面向过程的代码,直接描述流程,基本不能重用,重复的特别多.
而接下来做的代码优化,就是要优化成面向对象的代码.我习惯叫面向套路的代码,这里,也就是面向套路的编程.
看下面流程图,就是整体程序的流程,也就是真个程序的套路:
上面的代码,就是整个主程序的代码.
根据消息,判断来自谁,判读超时,读取任务记录表,根据任务记录表的步骤,读取步骤对应的方法.每一条消息,都是这个套路.就完成了一个来访登记程序的主要套路.为什么任务记录,任务时间这些不写在这个主方法,或者叫住套路里面,因为这个套路每条信息都会重新更新一次,如果写在里面,就根本不可能做到步骤记录.
再看这个住套路里面套了两个小一级的套路,可以理解成里面包含了两个组件.一个是 方法_超时判断,一个是方法_步骤处理.如果主套路是第一层,那么这里就是第二层.
超时判断这里,没有套到其他方法,所以这里就再没有下一层了.
方法_步骤处理,这里很明显就是整个程序的重点部分.而其中最重点的就是这个:
根据任务记录,读取步骤对应的信息类型,检测信息类型是否吻合,然后重新构造方法名称.再调用 eval函数,这个函数厉害,就是可以根据字符串调用名称相同的函数.就是这个方法,可以动态调用其他方法.在这里,就是可以动态调用其他套路.
根据我们实际情况和流程设计,步骤一共六部,也就是6套方法套路.我就不具体说,看下图.
整个程序总共六层套路.
其实一般使用并没有那么复杂,泛舟的经验就是,爱怎么写怎么写,不管黑猫白猫,捉到老鼠的就是好猫.能帮泛舟完成任务,节省时间的,就是好程序.但是总得有点追求,毕竟泛舟写在网上供所有人阅读的嘛.最后贴上泛舟优化后的程序代码.下一篇将继续优化代码,继续套路之旅.
感谢各位的阅读,望勿喷.
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 4 10:19:35 2018
模块 itchat ,中文测试
@author: 浩海泛舟
"""
import time as 包_时间
import itchat as 包_微信机器人
import 身份证识别 as 包_身份证识别 #import 包名不能是中文
import pandas as 包_科学计算
from pandas.core.frame import DataFrame as 包_制表
def 方法_更新excel记录(数据):
错误代码 = 0
try:
#读取excel文档
电子表格1 = './excel/访客登记表.xlsx'
数据表1 = 包_科学计算.read_excel(电子表格1, sheet_name=None)['Sheet1']
#数据 = [['张一','sxxx0089','面试','2018-11-30 14:35']]
数据表 = []
数据表.append(数据)
数据表2 = 包_制表(数据表)
数据表2.columns = ['姓名','身份证号码','来访目的','来访时间']
#合并两个表
数据列 = [数据表1,数据表2]
数据表3 = 包_科学计算.concat(数据列,sort=False) #要加后面的 sort=False ,不然程序提示错误
数据表3.to_excel(电子表格1,index = False)
except:
错误代码 = 1
return 错误代码
def 方法_图片检测(消息):
信息列表 = []
回复信息 = ''
if 消息['Type'] != 'Text':
图片名称 = 消息['FileName']
图片路径 = './pic/%s'%图片名称
消息['Text'](图片路径)
图片 = 包_身份证识别.方法_获取图片码(图片路径)
#print(图片)
try:
姓名,性别,民族,出生日期,地址,身份证号码 = 包_身份证识别.方法_获取身份证信息(图片)
回复信息 = '姓名:%s \n性别:%s \n民族:%s \n出生日期:%s \n地址:%s \n身份证号码:%s \n请确认身份证信息是否正确 \n请回复 是或否'%(姓名,性别,民族,出生日期,地址,身份证号码)
信息列表 = [姓名,性别,民族,出生日期,地址,身份证号码]
return 信息列表,回复信息
except:
回复信息 ='图片处理失败,请发送正确的身份证图片,或者选择更清晰的身份证图片发送!'
return 信息列表,回复信息
else:
return 信息列表,回复信息
def 方法_回复信息(回复内容,回复对象):
回复 = 包_微信机器人.send(回复内容,回复对象)
print(回复['BaseResponse']['ErrMsg'])
def 方法_超时判断(消息):
global 任务记录
global 任务时间
消息时间 = 消息['CreateTime']
if 0 < (消息时间-任务时间) < 301: #判读时间差,是不是5分钟之内.
return
else:
任务记录 = '步骤0'
return
def 方法_步骤0(消息):
global 任务记录
global 任务时间
if 消息['Text'] == '来访登记':
任务记录 = '步骤2'
任务时间 = 消息['CreateTime']
方法_回复信息(步骤_回复信息_字典['步骤1'],消息['FromUserName'])
else:
方法_回复信息(步骤_回复信息_字典['步骤0'],消息['FromUserName'])
return
def 方法_步骤1(消息):
方法_步骤0(消息)
return
def 方法_步骤2(消息):
global 任务记录
global 任务时间
global 身份证信息临时表
global 步骤_回复信息_字典
信息列表,回复信息 = 方法_图片检测(消息)
身份证信息临时表 = 信息列表[:]
任务记录 = '步骤3'
任务时间 = 消息['CreateTime']
步骤_回复信息_字典['步骤2'] = 回复信息
方法_回复信息(回复信息,消息['FromUserName'])
def 方法_步骤3(消息):
global 任务记录
global 任务时间
global 步骤_回复信息_字典
global 访客信息记录表
if 消息['Text'] in ['是','否']:
if 消息['Text'] == '是':
回复信息 = '请输入来访目的'
任务记录 = '步骤4'
任务时间 = 消息['CreateTime']
步骤_回复信息_字典['步骤3'] = 回复信息
访客信息记录表 = [身份证信息临时表[0],身份证信息临时表[-1]]
方法_回复信息(回复信息,消息['FromUserName'])
else:
回复信息 = '请重新发送清晰身份证图片'
任务记录 = '步骤2'
任务时间 = 消息['CreateTime']
步骤_回复信息_字典['步骤3'] = 回复信息
方法_回复信息(回复信息,消息['FromUserName'])
else:
回复信息 = 步骤_回复信息_字典['步骤2']
方法_回复信息(回复信息,消息['FromUserName'])
def 方法_步骤4(消息):
global 任务记录
global 任务时间
global 来访目的
global 步骤_回复信息_字典
回复信息 = '请确认来访目的是否正确,请输入 是或否 '
任务记录 = '步骤5'
任务时间 = 消息['CreateTime']
步骤_回复信息_字典['步骤4'] = 回复信息
来访目的 = 消息['Text']
方法_回复信息(回复信息,消息['FromUserName'])
def 方法_步骤5(消息):
global 任务记录
global 任务时间
global 来访目的
global 访客信息记录表
global 步骤_回复信息_字典
if 消息['Text'] in ['是','否']:
if 消息['Text'] == '是':
回复信息 = '正在写入登记信息'
步骤_回复信息_字典['步骤5'] = 回复信息
方法_回复信息(回复信息,消息['FromUserName'])
来访时间 = 包_时间.strftime("%Y-%m-%d %H:%M",包_时间.localtime())
访客信息记录表[2] = 来访目的
访客信息记录表[3] = 来访时间
写入文件 = 方法_更新excel记录(访客信息记录表)
if 写入文件 == 0:
任务记录 = '步骤0'
回复信息 = '登记完成,谢谢!'
步骤_回复信息_字典['步骤5'] = 回复信息
方法_回复信息(回复信息,消息['FromUserName'])
else :
任务记录 = '步骤6'
回复信息 = 'excel表出现问题,可能excel表被打开或者表格被移除,请检查!已经处理好问题请输入:是;重新开始处理登录程序,请输入:否.'
步骤_回复信息_字典['步骤5'] = 回复信息
方法_回复信息(回复信息,消息['FromUserName'])
else:
任务时间 = 消息['CreateTime']
回复信息 = '请重新发送来访目的'
任务记录 = '步骤4'
方法_回复信息(回复信息,消息['FromUserName'])
else:
回复信息 = 步骤_回复信息_字典['步骤4']
方法_回复信息(回复信息,消息['FromUserName'])
def 方法_步骤6(消息):
global 任务记录
global 步骤_回复信息_字典
global 访客信息记录表
if 消息['Text'] == '是':
#访客信息记录表 = 访客信息记录表[:2]
方法_步骤5(消息)
else:
任务记录 = '步骤0'
回复信息 = 步骤_回复信息_字典[任务记录]
方法_回复信息(回复信息,消息['FromUserName'])
def 方法_步骤处理(消息):
global 任务记录
global 任务时间
global 步骤_信息类型_字典
global 步骤_回复信息_字典
if 消息['Type'] == 步骤_信息类型_字典[任务记录]:
方法名称 = '方法_' + 任务记录
eval(方法名称)(消息)
else:
if 任务记录 == '步骤0':
方法_回复信息(步骤_回复信息_字典[任务记录],消息['FromUserName'])
else:
上一步骤 = '步骤' + str(int(任务记录[2:])-1)
方法_回复信息(步骤_回复信息_字典[上一步骤],消息['FromUserName'])
步骤_信息类型_字典 = {
'步骤0':'Text',
'步骤1':'Text',
'步骤2':'Picture',
'步骤3':'Text',
'步骤4':'Text',
'步骤5':'Text',
'步骤6':'Text'
}
步骤_回复信息_字典 ={
'步骤0':'上一次操超时或没有对应的关键字,您是需要登记来访信息吗?请重新输入关键字:来访登记',
'步骤1':'请给我发送清晰的身份证图片,以便提取身份证信息!',
'步骤2':'Picture',
'步骤3':'Text',
'步骤4':'Text',
'步骤5':'Text',
'步骤6':'Text'
}
#步骤任务说明 = ['步骤名称','检测消息类型','任务类型','关键字','处理方法','回复信息']
包_微信机器人.auto_login(hotReload=True) # itchat.auto_login(hotReload=True) 推出程序后暂存登陆状态,即一段时间不用扫码。
#获取公司微信号机器码,用于后面作判断
朋友列表 = 包_微信机器人.search_friends(name = '公司微信号')
公司微信机器码 = 朋友列表[0]['UserName']
#print(朋友列表)
#创建任务记录表
任务记录 = '步骤0'
任务时间 = int(包_时间.time())
身份证信息临时表 = []
来访目的 = ''
访客信息记录表 = []
#注册信息类型,作用是当微信收到文本信息,或者图片信息时,执行下面的程序.
@包_微信机器人.msg_register([包_微信机器人.content.TEXT,包_微信机器人.content.PICTURE])
def 方法_消息处理(消息):
#判读是否公司微信号
if str(消息['FromUserName']) == 公司微信机器码:
print('判断成功!')
#判断时间
方法_超时判断(消息)
#根据步骤处理消息
方法_步骤处理(消息)
else:
print('不是公司账号,不处理!')
if __name__ == '__main__':
包_微信机器人.auto_login()
包_时间.sleep(1)
包_微信机器人.send("文件助手你好哦", toUserName="filehelper")
包_微信机器人.run()