使用Python来开发微信功能


Posted in Python onJune 13, 2018

在移动社交时代,微信已经成为我们生活不可或缺的一部分。2017年的《微信数据报告》中显示:每天有380亿条消息从微信上发出,其中6亿条是语音消息,有350万个活跃的公众账号,并存在着8亿活跃粉丝。在其他诸如支付、出行等方面,也更是与我们的生活休憩相关。正如它的slogan那样:微信,是一个生活方式。

和微信有关的第三方框架很多,比如「wxpy」「wxBot」等,今天要使用的是其中著名的「itchat」Python模块,它是由第三方开发者@LittleCoder等架构实现的接口,该API的使用场景可以不仅仅只是一个微信机器人,更多的功能可以由我们自己去发现拓展。「itchat」的功能非常强大,调用却十分简单,同时,将「itchat」结合「matplotlib」「jieba」等模块,可以对我们的微信好友的信息进行一些收集与分析,让我们能更直观的了解我们自己的圈子。

一个自动回复机器人

微信自上线以来,一直没有自动回复的功能,想必是有他们的理念。但是有些人群,确实对此功能有一定需求,我举两个栗子:

  • 不愿时刻被消息打扰的人
  • 消息需要批量处理的人们(比如微商)

对此,我设计了几个功能:

功能列表:

  • [x] 收到消息立即自动回复
  • [x] 收到消息延迟指定时间回复
  • [x] 对不同好友定制不同的回复内容
  • [x] 在手机端随时进行控制

itchat的原理是通过扫码进行远程微信网页端的登录,然后通过在移动端进行操作,网页端进行响应,来实现一些功能,虽然似乎绕了个弯子,但是在微信的限制下,这似乎已经是一种最佳的方式了,犹如戴着镣铐起舞。

首先我们需要考虑别的问题是:程序如何在微信端接收到你的指令。此时出现了一个非常重要的角色:文件管理器。(当网页端微信登陆后,消息列表会出现)此时,文件管理器充当了移动端和web端的桥梁。比如你给文件管理器传一个字符串作为指令,网页端接收到数据后就能根据你的预定来执行相应操作。

我们可以先通过设定几个全局变量来做作为功能的开关和保存数据的容器。

#自动回复开关
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'])
  if target_friend:
   #获取ta的昵称
   nickName=target_friend['NickName']
   if not REPLY_DICT.__contains__(nickName):
    #设置默认回复
    REPLY_DICT[nickName]="抱歉我有事暂未看到消息,稍后回复,若有急事可以电话联系(•ω•`)"
   
   reply_content=REPLY_DICT[nickName]
   #判断自动回复开关
   if SWITCH_REPLY:
    #判断延时回复开关
    if SWITCH_DELAY:
     localtime = time.time()
     DELAY_REPLY_DICT[nickName]=[localtime,msg['FromUserName']]
     print (DELAY_REPLY_DICT)
     
    if not SWITCH_DELAY:
     #判断消息前缀开关
     if SWITCH_PREFIX:
      reply_content = PREFIX_CONTENT + REPLY_DICT[nickName]
     else:
      reply_content = REPLY_DICT[nickName]
     #发送消息
     itchat.send(reply_content, toUserName=msg['FromUserName'])

收到朋友消息即时进行自动回复是很简单的,但是如何去做延时发送回复消息呢?(至于做这个功能有没有必要的问题可以先搁置,不过我认为在很多场景下是需要这个功能的,大家也可以在评论区讨论在什么场景下需要延迟自动回复)现在就回到技术的问题,如何实现可设置时间的延时自动回复。

我先谈一谈我的想法,抛砖引玉。一般发送消息需要用到队列,进行入队和出队,我在这里设置了一个字典来保存消息发送者的数据。键为消息发送者的昵称,值是一个长度为2的数组,分别保存消息发送者的微信id和接收消息时的时间戳。这样我将每条发送过来的朋友信息保存在这个字典中,再通过将设定延迟时间同消息时间戳求和与当前时间戳进行对比,若当前时间戳较大,那么执行发送消息的操作。

此时再开启一个线程作为定时任务,定时去检测字典中每条数据是否到达了发送的临界要求(当前时间戳>=消息时间戳+设定的延迟时间)Python中有个专门做定时任务的模块叫sched,但是我尝试了一下,sched会阻塞当前主线程,也会阻塞itchat的线程,所以并不合适。这里我还是采用了threading的Timer来充当定时器,不过要注意使用递归,否则将会出现运行一次就结束的情况。

#延迟发送消息的函数
def delay_reply():
 #print("开始执行")
 global DELAY_REPLY_DICT
 if SWITCH_DELAY:
  while len(DELAY_REPLY_DICT)>0:
   localtime = time.time()
   # print (localtime)
   # print (DELAY_REPLY_DICT[item][0])
   # print (int(DELAY_TIME))
   for item in list(DELAY_REPLY_DICT.keys()):
    if SWITCH_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 ("发送消息")
     del DELAY_REPLY_DICT[item]
   print (DELAY_REPLY_DICT)

 global timer1
 timer1=threading.Timer(DELAY_TIME,delay_reply)
 timer1.start()

到此为止,主要的功能已经实现了,我用一个测试账号对我的微信进行了各种测试,看一下以下截图:

使用Python来开发微信功能 

 

使用Python来开发微信功能
使用Python来开发微信功能
使用Python来开发微信功能
使用Python来开发微信功能
使用Python来开发微信功能

这时功能基本已经完成了,这就结束了吗?别着急,再想想有没有需要完善一下的地方?用过微信web端的同学应该知道,当web端长期处于未操作的状态下会失去连接。在我们这个情况下,假如你长时间未收到微信消息,后台程序将会与微信失去连接,再次开启需要登上服务器重启程序,这显然非常麻烦。有没有什么简单的解决办法呢?我想到一些应用的后台通常会做一道心跳检测机制,那我就模仿这个思路,定时给我的”文件管理器“发一个字符串,来保持连接。

def keep_alive():
 text="保持登录"
 itchat.send(text, toUserName="filehelper")
 global timer2
 timer2 = threading.Timer(60*60,keep_alive)
 timer2.start()

最后,我们需要将这个程序发布在服务器上,让它全天候为我的微信服务。

使用Python来开发微信功能 

这里需要注意,如果仅用 python xxxx.py 来运行的话,关闭shell会导致进程结束,所以我们需要使用 nohup python xxxx.py & 来全方位守护进程,这里??乱痪洌?ohup和&的功能是不一样的,很多人容易混淆,感兴趣的话可以去查下资料区分一下。

到此,微信经过了我们的稍稍调教,已经乖了一点。但是,这远远不够,思路可以继续拓展,比如实现通过手机微信来控制电脑的开关机,电脑软件的启动关闭,都是可以的,甚至实现控制家中的空调,理论上也未尝不可,只是比较有难度。

简单分析微信好友信息

上文提到,既然我们能通过itchat来获取好友的信息,那让我们看看都有哪些好玩的信息。这是以json形式返回的我的信息,同理我的好友的这些公开信息我也能获取到。

我们就来进行一些简单的的数据抓取,清洗与呈现。我看中的字段是:Sex、City、Province、Signature。我想做的是通过图表来直观地展示我微信好友中的 性别比例 , 家乡分布 (当然不一定准确,很多人都是胡乱设置的), 我的江苏朋友的市级分布 ,以及 好友个性签名的词云 。这部分内容主要是需要熟悉诸如pyecharts、jieba、wordcloud模块的API调取,难度不大,但需要细心调试。我这里就不详细赘述了,有疑问可以在评论区讨论。

性别比例

def get_sex():
 # 获取好友数据
 my_friends = itchat.get_friends(update=True)[0:]
 sex = {"male": 0, "female": 0, "other": 0}
 for item in my_friends[1:]:
  s = item["Sex"]
  if s == 1:
   sex["male"] += 1
  elif s == 2:
   sex["female"] += 1
  else:
   sex["other"] += 1
 total = len(my_friends[1:])

使用Python来开发微信功能 

好友省级分布

def get_data(type):
 result=[]
 my_friends = itchat.get_friends(update=True)[0:]
 for item in my_friends:
  result.append(item[type])
 return result
def friends_province():
 # 获取好友省份
 province= get_data("Province")
 # 分类
 province_distribution = {}
 for item in province:
  #删除英文省份,因为中国地图表中没有
  if bool(re.search('[a-z]',item)):
   continue
  elif not province_distribution.__contains__(item):
   province_distribution[item] = 1
  else:
   province_distribution[item] += 1
 #将省份名为空的删除
 province_distribution.pop('')
 #提取地图接口需要的数据格式
 province_keys=province_distribution.keys()
 province_values=province_distribution.values()
 return province_keys,province_values
if __name__ == '__main__':
 itchat.auto_login(True)
 微信好友省份分布
 attr,value=friends_province()
 map = Map("我的微信好友分布", "@寒食君",width=1200, height=600)
 map.add("", attr, value, maptype='china', is_visualmap=True,
   visual_text_color='#000')
 map.render()

使用Python来开发微信功能 

省内分布

def friends_jiangsu():
 # 获取好友城市
 city_distribution={}
 city = get_data("City")
 jiangsu_city=["南通市","常州市","淮安市","连云港市","南京市","苏州市","宿迁市","泰州市","无锡市","徐州市","盐城市","扬州市","镇江市"]
 for item in city:
  item=item+"市"
  if item in jiangsu_city:
   if not city_distribution.__contains__(item):
    city_distribution[item]=1
   else:
    city_distribution[item]+=1
 # 提取地图接口需要的数据格式
 city_keys=city_distribution.keys()
 city_values=city_distribution.values()
 return city_keys,city_values
if __name__ == '__main__':
 itchat.auto_login(True)
 微信江苏好友分布
 attr,value=friends_jiangsu()
 map = Map("江苏好友分布","@寒食君", width=1200, height=600)
 map.add("", attr, value, maptype='江苏', is_visualmap=True,
   visual_text_color='#000')
 map.render()

使用Python来开发微信功能 

个性签名词云

def friends_signature():
 signature = get_data("Signature")
 wash_signature=[]
 for item in signature:
  #去除emoji表情等非文字
  if "emoji" in item:
   continue
  rep = re.compile("1f\d+\w*|[<>/=【】『』♂ω]")
  item=rep.sub("", item)
  wash_signature.append(item)
 words="".join(wash_signature)
 wordlist = jieba.cut(words, cut_all=True)
 word_space_split = " ".join(wordlist)
 coloring = np.array(Image.open("C:/Users/casua/Desktop/test1.JPG"))
 my_wordcloud = WordCloud(background_color="white", max_words=800,
        mask=coloring, max_font_size=80, random_state=30, scale=2,font_path="C:/Windows/Fonts/STKAITI.ttf").generate(word_space_split)
 image_colors = ImageColorGenerator(coloring)
 plt.imshow(my_wordcloud.recolor(color_func=image_colors))
 plt.imshow(my_wordcloud)
 plt.axis("off")
 plt.show()

使用Python来开发微信功能 

总结

以上所述是小编给大家介绍的使用Python来开发微信功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python通过PIL获取图片主要颜色并和颜色库进行对比的方法
Mar 19 Python
python 网络编程详解及简单实例
Apr 25 Python
利用python爬取斗鱼app中照片方法实例
Dec 03 Python
Python排序搜索基本算法之堆排序实例详解
Dec 08 Python
Python学习之Anaconda的使用与配置方法
Jan 04 Python
python opencv之SURF算法示例
Feb 24 Python
python 用正则表达式筛选文本信息的实例
Jun 05 Python
python解决字符串倒序输出的问题
Jun 25 Python
python基于opencv检测程序运行效率
Dec 28 Python
python实现单目标、多目标、多尺度、自定义特征的KCF跟踪算法(实例代码)
Jan 08 Python
Python基于百度AI实现抓取表情包
Jun 27 Python
Python采集爬取京东商品信息和评论并存入MySQL
Apr 12 Python
python爬取足球直播吧五大联赛积分榜
Jun 13 #Python
Python实现多条件筛选目标数据功能【测试可用】
Jun 13 #Python
mac 安装python网络请求包requests方法
Jun 13 #Python
Scrapy基于selenium结合爬取淘宝的实例讲解
Jun 13 #Python
利用Anaconda简单安装scrapy框架的方法
Jun 13 #Python
基于scrapy的redis安装和配置方法
Jun 13 #Python
mac下给python3安装requests库和scrapy库的实例
Jun 13 #Python
You might like
php操作JSON格式数据的实现代码
2011/12/24 PHP
php一个解析字符串排列数组的方法
2015/05/12 PHP
54个提高PHP程序运行效率的方法
2015/07/19 PHP
php写入文件不覆盖的实例讲解
2019/09/17 PHP
屏蔽鼠标右键、Ctrl+n、shift+F10、F5刷新、退格键 的javascript代码
2007/04/01 Javascript
JavaScript 加号(+)运算符号
2009/12/06 Javascript
JavaScript实现网页图片等比例缩放实现代码及调用方式
2013/02/25 Javascript
js跨域请求的5中解决方式
2015/07/02 Javascript
一张Web前端的思维导图分享
2015/07/03 Javascript
微信小程序 获取相册照片实例详解
2016/11/16 Javascript
JavaScript数据结构之二叉查找树的定义与表示方法
2017/04/12 Javascript
webpack配置的最佳实践分享
2017/04/21 Javascript
详解Vue使用命令行搭建单页面应用
2017/05/24 Javascript
Koa 使用小技巧(小结)
2018/10/22 Javascript
JS+php后台实现文件上传功能详解
2019/03/02 Javascript
小程序云开发如何实现图片上传及发表文字
2019/05/17 Javascript
vue用ant design中table表格,点击某行时触发的事件操作
2020/10/28 Javascript
python标准算法实现数组全排列的方法
2015/03/17 Python
Django中的“惰性翻译”方法的相关使用
2015/07/27 Python
用python记录运行pid,并在需要时kill掉它们的实例
2017/01/16 Python
浅谈python中字典append 到list 后值的改变问题
2018/05/04 Python
浅谈在django中使用filter()(即对QuerySet操作)时踩的坑
2020/03/31 Python
Matplotlib中%matplotlib inline如何使用
2020/07/28 Python
Gucci法国官方网站:意大利奢侈品牌
2018/07/25 全球购物
沙特阿拉伯电子产品和家用电器购物网站:Black Box
2019/07/24 全球购物
简历中个人求职的自我评价模板
2013/11/29 职场文书
安全月活动总结
2014/05/05 职场文书
建筑施工安全责任书
2014/07/24 职场文书
交通事故死亡赔偿协议书
2014/12/03 职场文书
安全先进班组材料
2014/12/26 职场文书
营销计划书范文
2015/01/17 职场文书
2015年汽车销售工作总结
2015/04/07 职场文书
拾金不昧通报表扬范文
2015/05/05 职场文书
Python数据可视化之基于pyecharts实现的地理图表的绘制
2021/06/10 Python
Vue Element-ui表单校验规则实现
2021/07/09 Vue.js
MySQL数据库如何使用Shell进行连接
2022/04/12 MySQL