美文网首页
PRO-001:微信短信发送技术准备

PRO-001:微信短信发送技术准备

作者: 杨强AT南京 | 来源:发表于2018-10-27 18:00 被阅读211次

    在Python语言中,有一个微信接口模块itchat,可以用来实现微信的一些功能,本主题专门使用itchat来实现一些应用:

    1. 掌握iChat的API结构;
    2. 应用iChat的API实现用户需求;

    前提:安装iChat模块

        > pip install itchat
    

    安装过程截图:

    Python3.6版本下,itchat模块安装过程

    一、itchat的API结构

      使用dir函数可以获取itchat中的API信息;
      代码:

      import  itchat
      print(dir(itchat))
    

      上述代码在python交互编程模式下,与ipython中都可以使用。
      获取的API信息如下(从ipython中拷贝的):

    ['Core', 'VERSION', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', 'add_friend', 'add_member_into_chatroom', 'auto_login', 'check_login', 'components', 'config', 'configured_reply', 'content', 'core', 'create_chatroom', 'delete_member_from_chatroom', 'dump_login_status', 'get_QR', 'get_QRuuid', 'get_chatrooms', 'get_contact', 'get_friends', 'get_head_img', 'get_mps', 'get_msg', 'instanceList', 'load_login_status', 'log', 'login', 'logout', 'msg_register', 'new_instance', 'originInstance', 'returnvalues', 'revoke', 'run', 'search_chatrooms', 'search_friends', 'search_mps', 'send', 'send_file', 'send_image', 'send_msg', 'send_raw_msg', 'send_video', 'set_alias', 'set_chatroom_name', 'set_logging', 'set_pinned', 'show_mobile_login', 'start_receiving', 'storage', 'update_chatroom', 'update_friend', 'upload_file', 'utils', 'web_init']

      根据字面意思,大致也知道上述函数的作用,具体的使用可以使用help函数获取。代码如下:

      help(itchat.login)
    

    或者

      help('itchat.login')
    

    获取的帮助结果如下:

    Help on method login in module itchat.components.login:

    login(enableCmdQR=False, picDir=None, qrCallback=None, loginCallback=None, exitCallback=None) method of itchat.core.Core instance 帮助输出截图

    二、itchat的使用

    1. 登录/登出

    (1)登录函数

    def login(self, enableCmdQR=False, picDir=None, qrCallback=None, loginCallback =None, exitCallback=None):
    log in like web wechat does
        for log in
            - a QR code will be downloaded and opened
            - then scanning status is logged, it paused for you confirm
            - finally it logged in and show your nickName
        for options
            - enableCmdQR: show qrcode in command line
                - integers can be used to fit strange char length
            - picDir: place for storing qrcode
            - qrCallback: method that should accept uuid, status, qrcode
            - loginCallback: callback after successfully logged in
                        - if not set, screen is cleared and qrcode is deleted
            - exitCallback: callback after logged out
                        - it contains calling of logout
        for usage
            ..code::python
    
                import itchat
                itchat.login()
    
        it is defined in components/login.py
        and of course every single move in login can be called outside
                 you may scan source code to see how
            - and modified according to your own demand
    

      使用代码

    #coding=utf-8
    import  itchat
    itchat.login()
    

      login函数执行过程中会产生一个二维码图片,more存放在login运行的当前工作目录,并且使用工具打开。

    login登录运行过程

    在用户使用手机扫描登录前,login处于阻塞状态;等扫描登录完成,会提示登录成功。登录成功后的输出:

    登录成功后的输出截图

      通过设置qrCallback与loginCallback可以控制登录过程,比如使用定制二维码显示,以及登录成功后的一些定制处理。qrCallback回调在长时间没有登录的情况,会被反复调用。
    同时还可以使用命令行显示二维码,命令行模式下qrCallback参数设置后无效,在命令行(或者控制台)显示二维码注意:enableCmdQR参数可以设置为True或者False,也可以是整数,整数也是True,但可以指定二维码显示的宽度,某些平台下控制台一个字符占用2个字符,可以设置为2,这样二维码显示才会正常,否则显示不是太正常。
    代码:

    #命令行模式
    itchat.login(enableCmdQR=2,loginCallback=login_cb)
    

      效果:

    命令行二维码

      可以将enableCmdQR赋值为负值改变命令行二维码的背景与前景色。

      还有一个auto_login函数也可以实现自动登录,该函数的声明如下:

    auto_login(hotReload=False, statusStorageDir='itchat.pkl', enableCmdQR=False, picDir=None, qrCallback=None, loginCallback=None, exitCallback=None)
    

      第一个参数是掉线后,短时间内登录,不扫描二维码。

    (2)登出函数

        def logout(self):
            ''' logout
                if core is now alive
                    logout will tell wechat backstage to logout
                and core gets ready for another login
                it is defined in components/login.py
            '''
            raise NotImplementedError()
    

    (3)登录状态检测

        def check_login(self, uuid=None):
            ''' check login status
                for options:
                    - uuid: if uuid is not set, latest uuid you fetched will be used
                for return values:
                    - a string will be returned
                    - for meaning of return values
                        - 200: log in successfully
                        - 201: waiting for press confirm
                        - 408: uuid timed out
                        - 0  : unknown error
                for processing:
                    - syncUrl and fileUrl is set
                    - BaseRequest is set
                blocks until reaches any of above status
                it is defined in components/login.py
            '''
    

      如果uuid参数为None,默认是最后一次登录的uuid。

    2. 信息获取

      与操作文件系统一样,登录后,就是微信信息获取,主要是好友信息,群信息,公众号信息等。
      好友、群聊、公众号信息提供常见的操作函数:

    # 函数类型 说明
    1   get_XXX  获取
    2   update_XXX  更新
    3   search_XXX  搜索
    4   add_XXX  添加
    5   delete_XXX  删除
    6   set_XXX  修改

      下面我们仅仅列出get_XXXX相关的函数声明。
    (1)get_contact获取群聊信息
      get_contact与get_chatrooms作用一样。

    def get_contact(self, update=False):
        ''' fetch part of contact
            for part
                - all the massive platforms and friends are fetched
                - if update, only starred chatrooms are fetched
            for options
                - update: if not set, local value will be returned
            for results
                - chatroomList will be returned
            it is defined in components/contact.py
        '''
        raise NotImplementedError()
    

    (2)get_friends获取好友

    def get_friends(self, update=False):
        ''' fetch friends list
            for options
                - update: if not set, local value will be returned
            for results
                - a list of friends' info dicts will be returned
            it is defined in components/contact.py
        '''
        raise NotImplementedError()
    

    (3)get_chatrooms获取群聊

    def get_chatrooms(self, update=False, contactOnly=False):
        ''' fetch chatrooms list
            for options
                - update: if not set, local value will be returned
                - contactOnly: if set, only starred chatrooms will be returned
            for results
                - a list of chatrooms' info dicts will be returned
            it is defined in components/contact.py
        '''
        raise NotImplementedError()
    

    (4)get_mps获取公众号

    def get_mps(self, update=False):
        ''' fetch massive platforms list
            for options
                - update: if not set, local value will be returned
            for results
                - a list of platforms' info dicts will be returned
            it is defined in components/contact.py
        '''
        raise NotImplementedError()
    

    (5)获取好友,群聊、公众号的例子

      #coding=utf-8
      import  itchat
      from  itchat.storage.templates import ContactList
      itchat.auto_login()
      print(itchat.get_contact())
      print(itchat.get_chatrooms())
      print(itchat.get_friends())
      print(itchat.get_mps())
    
      print(type(itchat.get_contact()))
      print(type(itchat.get_chatrooms()))
      print(type(itchat.get_friends()))
      print(type(itchat.get_mps()))
    

      获取的好友、群聊、公众号信息如下:

    获取的信息输出

      获取的信息返回的都是列表,列表的类型如下:

    <class 'itchat.storage.templates.ContactList'>
    <class 'itchat.storage.templates.ContactList'>
    <class 'itchat.storage.templates.ContactList'>
    <class 'itchat.storage.templates.ContactList'>

    (6)ContactList类型定义

    class ContactList(list):
        ''' when a dict is append, init function will be called to format that dict '''
        def __init__(self, *args, **kwargs):
            super(ContactList, self).__init__(*args, **kwargs)
            self.__setstate__(None)
        @property
        def core(self):
            return getattr(self, '_core', lambda: fakeItchat)() or fakeItchat
        @core.setter
        def core(self, value):
            self._core = ref(value)
        def set_default_value(self, initFunction=None, contactClass=None):
            if hasattr(initFunction, '__call__'):
                self.contactInitFn = initFunction
            if hasattr(contactClass, '__call__'):
                self.contactClass = contactClass
        def append(self, value):
            contact = self.contactClass(value)
            contact.core = self.core
            if self.contactInitFn is not None:
                contact = self.contactInitFn(self, contact) or contact
            super(ContactList, self).append(contact)
        def __deepcopy__(self, memo):
            r = self.__class__([copy.deepcopy(v) for v in self])
            r.contactInitFn = self.contactInitFn
            r.contactClass = self.contactClass
            r.core = self.core
            return r
        def __getstate__(self):
            return 1
        def __setstate__(self, state):
            self.contactInitFn = None
            self.contactClass = User
        def __str__(self):
            return '[%s]' % ', '.join([repr(v) for v in self])
        def __repr__(self):
            return '<%s: %s>' % (self.__class__.__name__.split('.')[-1],
                self.__str__())
    

    ContactList继承是是内置列表类型list。

    3. 好友、群聊、公众号信息处理

    (1)好友、群聊、公众号信息结构定义
      实际上上面代码返回的列表中元素类型是不同的,下面可以使用代码输出:

    #coding=utf-8
    import  itchat
    from  itchat.storage.templates import ContactList
    itchat.auto_login()
    list_contact=itchat.get_contact()
    list_chatrooms=itchat.get_chatrooms()
    list_friends=itchat.get_friends()
    list_mps=itchat.get_mps()
    
    print(type( list_contact[0]))
    print(type( list_chatrooms[0]))
    print(type( list_friends[0]))
    print(type( list_mps[0]))
    

      列表中类型分别是:

    <class 'itchat.storage.templates.Chatroom'>
    <class 'itchat.storage.templates.Chatroom'>
    <class 'itchat.storage.templates.User'>
    <class 'itchat.storage.templates.MassivePlatform'>

    (2)Chatroom信息结构
      Chatroom最上层父类是dict类型,继承结构:

    class Chatroom(AbstractUserDict)
    class AbstractUserDict(AttributeDict)
    class AttributeDict(dict)
    

    根据字典的特点,信息的索引主要靠key,获取其key如下:

    import  itchat
    
    from itchat.storage.templates import  Chatroom
    from itchat.storage.templates import User
    from itchat.storage.templates import MassivePlatform
    
    
    itchat.auto_login()
    list_contact=itchat.get_contact()
    list_chatrooms=itchat.get_chatrooms()
    list_friends=itchat.get_friends()
    list_mps=itchat.get_mps()
    
    print(list_contact[0].keys())
    print(list_chatrooms[0].keys())
    print(list_friends[0].keys())
    print(list_mps[0].keys())
    

      字典keys如下:

    dict_keys(['MemberList', 'Uin', 'UserName', 'NickName', 'HeadImgUrl', 'ContactFlag', 'MemberCount', 'RemarkName', 'HideInputBarFlag', 'Sex', 'Signature', 'VerifyFlag', 'OwnerUin', 'PYInitial', 'PYQuanPin', 'RemarkPYInitial', 'RemarkPYQuanPin', 'StarFriend', 'AppAccountFlag', 'Statues', 'AttrStatus', 'Province', 'City', 'Alias', 'SnsFlag', 'UniFriend', 'DisplayName', 'ChatRoomId', 'KeyWord', 'EncryChatRoomId', 'IsOwner', 'IsAdmin', 'Self'])

    (3)User信息结构
      User与Chatroom基本上一样。

    class User(AbstractUserDict)
    class AbstractUserDict(AttributeDict)
    class AttributeDict(dict)
    

      User是字典key如下:

    dict_keys(['MemberList', 'UserName', 'City', 'DisplayName', 'PYQuanPin', 'RemarkPYInitial', 'Province', 'KeyWord', 'RemarkName', 'PYInitial', 'EncryChatRoomId', 'Alias', 'Signature', 'NickName', 'RemarkPYQuanPin', 'HeadImgUrl', 'UniFriend', 'Sex', 'AppAccountFlag', 'VerifyFlag', 'ChatRoomId', 'HideInputBarFlag', 'AttrStatus', 'SnsFlag', 'MemberCount', 'OwnerUin', 'ContactFlag', 'Uin', 'StarFriend', 'Statues', 'WebWxPluginSwitch', 'HeadImgFlag'])

    (4)MassivePlatform信息结构
       MassivePlatform与Chatroom基本上一样。

    class MassivePlatform(AbstractUserDict)
    class AbstractUserDict(AttributeDict)
    class AttributeDict(dict)
    

       MassivePlatform是字典key如下:

    dict_keys(['MemberList', 'Uin', 'UserName', 'NickName', 'HeadImgUrl', 'ContactFlag', 'MemberCount', 'RemarkName', 'HideInputBarFlag', 'Sex', 'Signature', 'VerifyFlag', 'OwnerUin', 'PYInitial', 'PYQuanPin', 'RemarkPYInitial', 'RemarkPYQuanPin', 'StarFriend', 'AppAccountFlag', 'Statues', 'AttrStatus', 'Province', 'City', 'Alias', 'SnsFlag', 'UniFriend', 'DisplayName', 'ChatRoomId', 'KeyWord', 'EncryChatRoomId', 'IsOwner'])

      下面是用户信息的获取:

    #coding=utf-8
    import  itchat
    
    itchat.auto_login()
    list_friends=itchat.get_friends()
    
    one_user=list_friends[0]
    for key in one_user:
        print(key,":",one_user[key])
    

    下面是获取的的部分用户信息:

    微信用户本人信息

    4. 用户信息接收

      接收消息采用的是类似事件处理的注册方式,一单某个函数注册以后(注册时函数需要与某个消息类型关联),当接收到相应类型的消息,该函数就调用。
    (1)消息注册的方式
      消息的注册,使用的是python的装饰器技术,装饰器的定义如下:

        def msg_register(self, msgType, isFriendChat=False, isGroupChat=False, isMpChat=False):
    

      参数说明:

    msgType: 指定该方法用于处理的消息类型
    isFriendChar: 处理好友消息
    isGroupChat: 处理群消息
    isMpChat: 处理公众号消息

    (2)消息的类型
      其中msgType的值支持如下集中:

    消息类型 类型说明
    TEXT  文本
    PICTURE  图片
    FRIENDS  好友
    CARD  名片
    MAP  位置
    SHARING  共享
    RECORDING  语音=VOICE
    ATTACHMENT  附件
    VIDEO  视频
    VIOCE  音频= RECORDING
    NOTE  消息撤回
    SYSTEM  系统

    上述消息类型的定义如下:

    TEXT       = 'Text'
    MAP        = 'Map'
    CARD       = 'Card'
    NOTE       = 'Note'
    SHARING    = 'Sharing'
    PICTURE    = 'Picture'
    RECORDING  = VOICE = 'Recording'
    ATTACHMENT = 'Attachment'
    VIDEO      = 'Video'
    FRIENDS    = 'Friends'
    SYSTEM     = 'System'
    

      提示:在itchat的安装库文件content.py中定义。使用的时候,需要import itchat.content,省事的import方式:

      from itchat.content import *
    

      下面是一段接收所有类型的信息的代码:

    #coding=utf-8
    import  itchat
    from itchat.content import *
    
    @itchat.msg_register(msgType=INCOME_MSG,isFriendChat=True,isGroupChat=True,isMpChat=True)
    def recv_msg(msg):
        print(msg);
    #登录
    itchat.auto_login()
    #运行
    itchat.run(debug=True)
    #退出登录
    itchat.logout()
    

      获得消息显示如下:

    获取没有经过分析的聊天信息

    5. 用户信息类型与处理

      通过注册消息处理函数,实现异步回调的方式来接收聊天信息,传递过来的消息类型是:

    class 'itchat.storage.messagequeue.Message'
    

      Message类与上面User本质也是一个字典类型,继承结构如下:

    Message-> AttributeDict->dict

    class Message(AttributeDict):
    class AttributeDict(dict):
    

      不同类型的信息,其字典keys是不同的,就是内容有差别:

    dict_keys(['MsgId', 'FromUserName', 'ToUserName', 'MsgType', 'Content', 'Status', 'ImgStatus', 'CreateTime', 'VoiceLength', 'PlayLength', 'FileName', 'FileSize', 'MediaId', 'Url', 'AppMsgType', 'StatusNotifyCode', 'StatusNotifyUserName', 'RecommendInfo', 'ForwardFlag', 'AppInfo', 'HasProductId', 'Ticket', 'ImgHeight', 'ImgWidth', 'SubMsgType', 'NewMsgId', 'OriContent', 'EncryFileName', 'User', 'Type', 'Text', 'SystemInfo'])

    dict_keys(['Type', 'Text', 'SystemInfo', 'FromUserName', 'ToUserName', 'User'])

      下面是一个专门接收好友文本信息的代码:

    #coding=utf-8
    import  itchat
    from itchat.content import *
    
    @itchat.msg_register(msgType=INCOME_MSG,isFriendChat=True,isGroupChat=False,isMpChat=False)
    def recv_msg(msg):
        print(msg['Type'])
        if msg['Type'] == TEXT :
            print(msg['Text'])
    
    #登录
    itchat.auto_login()
    #运行
    itchat.run(debug=True)
    #退出登录
    itchat.logout()
    

      接收到信息如下:

    简单的用户聊天信息接收,可以根据需要做更加复杂的处理

    6. 用户信息发送

      发送用户消息,有两种方式:
    (1)原生消息发送

    def send_raw_msg(self, msgType, content, toUserName):
        ''' many messages are sent in a common way
            for demo
                .. code:: python
    
                    @itchat.msg_register(itchat.content.CARD)
                    def reply(msg):
                        itchat.send_raw_msg(msg['MsgType'], msg['Content'], msg['FromUserName'])
    
            there are some little tricks here, you may discover them yourself
            but remember they are tricks
            it is defined in components/messages.py
        '''
    
      def send(self, msg, toUserName=None, mediaId=None):
        ''' wrapped function for all the sending functions
            for options
                - msg: message starts with different string indicates different type
                    - list of type string: ['@fil@', '@img@', '@msg@', '@vid@']
                    - they are for file, image, plain text, video
                    - if none of them matches, it will be sent like plain text
                - toUserName: 'UserName' key of friend dict
                - mediaId: if set, uploading will not be repeated
            it is defined in components/messages.py
        '''
        raise NotImplementedError()
    

    (2)快捷发送函数

      #发送文本
      def send_msg(self, msg='Test Message', toUserName=None)
    
      #发送文件
      def send_file(self, fileDir, toUserName=None, mediaId=None)
    
      #发送图像
      def send_image(self, fileDir, toUserName=None, mediaId=None)
    
      #发送视频
      def send_video(self, fileDir=None, toUserName=None, mediaId=None):
    

      下面简单的展示一个发动短信的例子(其他视频,语音基本上类似)。

    #coding=utf-8
    import  itchat
    import  time
    
    #登录
    itchat.auto_login()
    
    #根据昵称找用户
    user=itchat.search_friends(nickName='赵德柱')[0]
    
    #每隔5秒给用户发一个短信
    for i in range(10):
        itchat.send_msg(msg="辣鸡短信,不必理会!",toUserName=user['UserName'])
        time.sleep(5)
    
    #退出登录
    itchat.logout()
    

      上面代码可以改成个人好友信息测试。


    资源

      本文使用的测试代码下载地址:【 下载

    相关文章

      网友评论

          本文标题:PRO-001:微信短信发送技术准备

          本文链接:https://www.haomeiwen.com/subject/oxnrtqtx.html