当前位置: 首页 > 后端技术 > Python

实用功能#用Python升级你的微信

时间:2023-03-25 21:31:23 Python

自动回复机器人大家好,我是查理。微信自推出以来,一直没有自动回复功能。这一定是他们的主意。但是有些人确实对这个功能有一定的需求。举两个例子:不想一直被消息打扰的人。需要批量处理消息的人(比如微商)设计了几个功能:[x]立即接收消息自动回复[x]收到消息后在指定时间回复[x]为不同的朋友定制不同的回复内容[x]随时在手机端控制itchat在终端上操作,响应网页来实现一些功能,虽然看起来绕了点弯路,但是在微信的限制下,这似乎是最好的方式,就像带着枷锁跳舞。我们可以先设置几个全局变量作为功能开关和存储数据的容器。#自动回复开关SWITCH_REPLY=True#延迟回复开关SWITCH_DELAY=False#延迟时间DELAY_TIME=120#消息前缀开关SWITCH_PREFIX=True#消息前缀内容PREFIX_CONTENT="[自动回复]"#回复内容字典REPLY_DICT={}#延迟回复字典DELAY_REPLY_DICT={}然后在“文件管理器”中通过判断web端接收到的字符串指令进行不同的操作。这部分的代码比较简单,篇幅较长,这里就不贴出来了。完整的源码地址会在文末给出。如果这个时候我们收到朋友的消息,我们就需要程序给出自动回复。#获取发送消息的好友信息target_friend=itchat.search_friends(userName=msg['FromUserName'])iftarget_friend:#获取ta的昵称nickName=target_friend['NickName']ifnotREPLY_DICT.__contains__(nickName):#SetDefaultreplyREPLY_DICT[nickName]="不好意思,我有事还没看到消息,稍后回复,有急事可以给我打电话(?ω?`)"reply_content=REPLY_DICT[nickName]#判断自动回复开关ifSWITCH_REPLY:#判断延迟回复开关ifSWITCH_DELAY:localtime=time.time()DELAY_REPLY_DICT[nickName]=[localtime,msg['FromUserName']]print(DELAY_REPLY_DICT)ifnotSWITCH_DELAY:#判断消息前缀切换ifSWITCH_PREFIX:reply_content=PREFIX_CONTENT+REPLY_DICT[nickName]else:reply_content=REPLY_DICT[nickName]#发送消息itchat.send(reply_content,toUserName=msg['FromUserName'])很简单收到好友消息后立即自动回复很简单,但是如何延迟发送回复消息呢?(至于是否有必要实现这个功能,大家暂时先搁置一旁,不过我觉得很多场景都需要这个功能,也可以在评论区讨论哪些场景需要延迟自动回复。)现在回到技术问题,如何实现可以设置时间的延时自动回复,先说说自己的想法,抛砖引玉。一般发送消息需要使用队列,进出队列。我这里建立了一个字典,用来保存消息发送者的数据。key是消息发送者的昵称,value是一个长度为2的数组,分别存储消息发送者的微信id和接收消息时的时间戳。这样我就把每条发送的好友信息保存在这个字典里,然后把设置的延迟时间和消息时间戳和当前时间戳进行比较。如果当前时间戳较大,则执行发送消息的操作。此时再启动一个线程作为定时任务,定时检查字典中的每条数据是否达到发送的临界要求(当前时间戳>=消息时间戳+设置延迟时间)。Python中有专门的定时任务。该模块称为sched,但我试过了。sched会阻塞当前主线程和itchat线程,所以不适合。这里我还是使用threadingTimer作为定时器,但是要注意使用递归,否则运行一次就结束了。#延迟发送消息的函数defdelay_reply():#print("startexecution")globalDELAY_REPLY_DICTifSWITCH_DELAY:whilelen(DELAY_REPLY_DICT)>0:localtime=time.time()#print(localtime)#print(DELAY_REPLY_DICT[item][0])#打印(int(DELAY_TIME))foriteminlist(DELAY_REPLY_DICT.keys()):ifSWITCH_REPLY:reply_content=item+","+str(round(int(DELAY_TIME)/60,1))+"分钟过去了,"+REPLY_DICT[item]itchat.send(reply_content,toUserName=DELAY_REPLY_DICT[item][1])#print("Sendmessage")delDELAY_REPLY_DICT[item]print(DELAY_REPLY_DICT)globaltimer1timer1=threading.Timer(DELAY_TIME,delay_reply)timer1.start()至此主要功能已经实现。我用一个测试账号在我的微信上进行了各种测试。看看下面的截图:这时候功能已经基本完成了,是不是就结束了?别着急,再想一想,有什么需要改进的地方吗?用过微信网页端的同学应该都知道,当网页端长时间不运行时,会出现连接断开的情况。在我们的例子中,如果长时间没有收到微信消息,后台程序就会与微信失去连接,需要重新登录服务器重启程序,显然是很麻烦的。有什么简单的解决办法吗?我想到一些应用程序的后台通常有心跳检测机制,所以我模仿这个想法,定期向我的“文件管理器”发送一个字符串来保持连接。defkeep_alive():text="保持登录"itchat.send(text,toUserName="filehelper")globaltimer2timer2=threading.Timer(60*60,keep_alive)timer2.start()最后,我们需要发布这个程序在服务器上,让它24/7全天候服务我的微信。image这里需要注意的是,如果只使用pythonxxxx.py来运行的话,关闭shell会导致进程结束,所以我们需要使用nohuppythonxxxx.py&来全方位守护进程。这里啰嗦一句,nohup和&的功能不一样,很多人容易混淆。有兴趣的可以去查查资料,把它们区分开来。到目前为止,经过我们的一些培训,微信已经变得更好了。然而,这还远远不够。这个想法可以进一步扩展。比如可以通过手机微信控制电脑的开机和关机,电脑软件的启动和关闭。甚至可以控制家里的空调。难的。微信好友信息简单分析上面说了,既然我们可以通过itchat获取好友信息,那么name自然会有很多有趣的信息(这里不具体分析)。性别比例defget_sex():#获取好友数据my_friends=itchat.get_friends(update=True)[0:]sex={"male":0,"female":0,"other":0}foriteminmy_friends[1:]:s=item["Sex"]ifs==1:sex["male"]+=1elifs==2:sex["female"]+=1else:sex["other"]+=1total=len(my_friends[1:])#开始画饼图attr=list(sex.keys())v1=list(sex.values())pie=Pie("朋友的性别比例")馅饼。add("",attr,v1,v1,is_label_show=True)pie.render(path="sex_html/sex.html")性别比例全国好友省份分布deffriends_province():#获取好友省份province=get_data("Province")#Categoryprovince_distribution={}foriteminprovince:#删除英文省份,因为没有中文地图ifbool(re.search('[a-z]',item)):continueelifnotprovince_distribution.__contains__(item):province_distribution[item]=1else:province_distribution[item]+=1#删除名称为空的省份province_distribution.pop('')#提取地图接口需要的数据格式#print(province_distribution)province_keys=province_distribution.键()province_values=province_distribution。values()returnprovince_keys,province_values注意:需要自己安装地图,否则只会显示南海诸岛问题,https://www.jianshu.com/p/20fd061d0b96:解决方法,手动安装map全球国家地图:echarts-countries-pypkg(1.9MB):世界地图和213个国家,包括中国地图中国省份地图:echarts-china-provinces-pypkg(730KB):23个省、5个自治区中国市级地图:echarts-china-cities-pypkg(3.8MB):需要这些中国370个城市地图的朋友可以安装pip命令行:pipinstallecharts-countries-pypkgpipinstallecharts-china-provinces-pypkgpipinstallecharts-china-cities-pypkg特别说明,中国地图在echarts-countries-pypkg全国好友分发好友标签deffriends_signature():signature=get_data("Signature")wash_signature=[]foriteminsignature:#去掉emoji表情等非文字if"emoji"initem:continuerep=re.compile("1f\d+\w*|[<>/=【】『』♂ω]")item=rep.sub("",item)wash_signature.append(item)words="".join(wash_signature)print(wash_signature)wordlist=jieba.cut(words,cut_all=True)word_space_split="".join(wordlist)globalNickNameglobalSex#print(NickName,Sex)#图片的作用:生成的图片是这张图片的两倍大小#根据性别选择对应的性别模板图ifSex==2:coloring=np.array(Image.open("standard/girl.jpg"))elifSex==1:coloring=np.array(Image.open("standard/boy.jpg"))else:coloring=np.array(Image.open("standard/num.jpg"))#识别中文字体需要simkai.ttf,例如:simkai.ttf,my_wordcloud=WordCloud(background_color="white",max_words=800,mask=coloring,max_font_size=120,random_state=30,scale=2,font_path="fonts/STKAITI.TTF").generate(word_space_split)image_colors=ImageColorGenerator(着色)plt.imshow(my_wordcloud.recolor(color_func=image_colors))plt.imshow(my_wordcloud)plt.axis("off")plt.show()#保存图片my_wordcloud.to_file('Signature/signature.png')说明两点:1.要有标签模板生成对应的样式2.要加识别中文的字体