本文准备环境:itchat、python3.6、win10

       这两天一直在跑数据,由于处理的是A股全市场Level 1和Level 2的超高频数据,数据量很大,尽管开了多进程,还是要跑很久,而且因为不好预估时间,加上生怕程序中途出什么bug,就要频繁的登录服务器查看程序执行情况,看程序是否跑完,或者有没有中途出bug,这其实挺折磨人的。要是程序跑完了或者出bug了,可以直接让程序自己通知我,这样就不用总是登录服务器查看,就省事多了。之前看过一篇介绍itchat的文章,感觉可以通过itchat实现微信的实时监控,于是就尝试了下。

      itchat是一个python的第三方开源包,其是个人微信web api的python封装,因此我们可以通过这个包来实现相当多的微信操作,笔者自己也是刚接触,感兴趣的读者可以去这里了解。本文中,笔者将通过一个简单的例子来说明如何通过itchat来实现程序和个人微信的交互,这个例子要实现的功能为:通过向微信里的文件助手发送指定信息以查看程序运行情况,比如发送“check progress”,如果程序还在运行,则程序自动回复“the process is still running!”,如果程序已经执行完毕,则回复“the process is done!”。

       在实现交互之前,我们先简单的运用一下itchat。如图一,只需要导入->登陆->发送三行代码就可以实现向你微信的文件助手发送一条消息。运行这三条代码之后,会生成一个二维码,然后只要用自己的手机扫一扫并点击登陆,就可以登陆微信web端,当然,如果你之前已经登陆了网页版微信,那么这时网页版微信就会自动退出,登陆后,你手机微信的文件助手就会收到'Hello,filehelper'。

监控微信对话python 监控微信聊天信息_手机端

(图一)

       自然地,你还可以通过这种基础语句实现这样的功能:当你的任务执行完毕,程序最后会向你手机微信发送一条消息,说明程序成功执行完毕。比如图二的例子中,程序成功执行完毕后,你手机就会收到一条“succeed after 5 seconds sleeping”。

监控微信对话python 监控微信聊天信息_python_02

(图二)

       下面是上面两个例子的手机端微信收到的消息,显示的发送人是你本人。

监控微信对话python 监控微信聊天信息_python_03

       接下来,我们实现真正的交互并实时监测。要注意的是,由于实时监测需要微信web端始终保持运行状态,而同时又要保持处理任务的代码也一直在运行,因此这就需要通过两个线程或者进程来实现,一个线程用来执行任务,另一个线程用来检测任务线程的运行情况。下面直接上代码:

# -*- coding: utf-8 -*-

import time,threading

#此函数为任务处理函数,里面可以是你想要执行的任何语句
def f(a,b,p):
    time.sleep(100)
    p.append(1)
    
def run_wechat(p): 
    import itchat
    #注册消息类型为文本TEXT
    @itchat.msg_register(itchat.content.TEXT)  
    def check_progress(msg):
        if msg['ToUserName'] != 'filehelper': return
        if msg['Text'] == 'check progress':
            if p[-1]==1: 
                itchat.send('The process is done!', 'filehelper')
            elif p[-1]==0: 
                itchat.send('The process is still running!', 'filehelper')
                
    itchat.auto_login(True)
    itchat.run()

if __name__=='__main__':
    l=[0]

    t1=threading.Thread(target=f,args=(2,3,l))
    t2=threading.Thread(target=run_wechat,args=(l,))
    
    t1.start()
    t2.start()
    
    t1.join()
    t2.join()

       直接运行上面的代码,就可以实现上述的实时监控的功能了。上面的代码中,函数f为要处理的任务,这里直接休眠100秒以实现实时交互的监测效果;run_wechat为微信监控程序,这里面先导入了itchat包,然后自己定义一个交互监测的函数check_progress,并通过装饰器函数将其消息类型注册为文本消息,因为不同的消息类型(语音、图片、文本视频等)需要显式注册才可以,不熟悉装饰器语法的读者可以看笔者之前写的一篇介绍函数装饰器的相关文章;然后再登陆,再通过itchat.run()让微信web端实时响应,这样就可以实现手机端微信和web的实时交互,也就可以实现手机端微信和这里运行的程序进行交互。

       那么如何实现线程之间的交流呢?即执行任务的线程如果运行完了,监控线程如何得知?这里是通过一个列表l来实现的,如代码所示,如果任务线程中的任务执行完毕,就会append(1),而初始的l值包含一个0,因此,在监控线程中,只要判断l的最后一个元素是0还是1,就可以判断任务线程是在执行还是已经执行完毕了,这就是交互检测函数check_progress的判断逻辑。

       下图是运行上面的代码后,手机端微信和程序的交互情况以及实时的反馈结果。图中的check progress是我手动输入的,然后因为任务线程是先休眠了100秒,所以刚开始程序回复的消息都是The process is still running!,最后大概100多秒之后,任务线程执行完毕并向列表l末尾append了一个1后,程序回复的就是The process is done!,由此我们判断任务已经执行完毕了。

监控微信对话python 监控微信聊天信息_python_04

(图三)

       以上就是一个简单的说明,在具体使用时,我们还可以在check_process中加入这样的功能:如果程序执行完毕,那么手机端可以发送指定消息给web端让其关闭微信检测线程,当web收到指定消息后,调用相关的函数即可结束该线程,以节省cpu资源;当然还可以实现更多的交互和功能,取决于用户自己的需求,有兴趣的读者可以自己去查看itchat的文档进一步的了解。最后,在编程时还需要注意以下几点:

1、itchat包在导入之后,便不能再通过join()方法阻塞该进程或线程,不然会造成线程卡死,因此,import itchat这条语句应该在独立线程中执行,而不能在有join()方法的主线程中执行,这就是为什么本文例子中itchat是在交互监测的独立线程中导入,而不是在外部导入的。

2、itchat导入以及其相关的功能只在python的子线程函数中有用,若想通过创建一个子进程独立运行交互监测程序就可能会报错。

3、由于在实际处理任务中,对于cpu密集型任务,为了充分利用cpu资源,python中是通过多进程实现的,而不是多线程,所以任务部分可以通过多进程处理,但是交互监测部分还是需要利用线程运行,以防出错。