Python 网页微信itchat分析
itchat 可以做什么
itchat 封装了微信 web api,蛮好用的,可以做一些有意思的事情:
另外还有个库 itchatmp 和公众号管理相关的
脑洞可以这么打开:
- 管理
所有聊天记录备份
聊天记录监控(一个打入敌人内部的人…加了 n 多群)
群聊管理,自动拉群,定时群发(拜年)
红包监控,但是不能直接抢…
监控公众号推送
撤回消息保存
谁删了我?
- 账号云图分析
联系人统计分析,个人关注的公众号,做口味分析
好友签名云图
头像整合?分析
聊天记录分析?–>词云
- 控制入口,后台的空间任意想象 webapi app–>微信入口—>any 后台
聊天机器人
一秒变逗逼—>nlp
可指定在哪个群,变成哪种人(逗逼,暴躁男,文艺男…),
收到问题–>后台—>回复问题
收到文本–>后台–>回复各种萌萌哒语音
收到语音–>后台 tts,分析后–>回复各种指令,控制
收到图像–>后台分析—>给出反馈,如美化,识别结果 等
自动问题告警
itchat 实现分析
封装的还是不错的,可以剖析下
AbstractUserDict
先搞清楚以下继承链:
list->AttributeDict->AbstractUserDict-->(User, ChatRoom,MassivePlatform)
list->增加list.name的方式,和list['name']一致-->增加了很多方法,send相关的-->
具体的实现子类,User需要send,聊天室需要send,公众号需要send
update
set_alias
set_pinned
verify
get_head_image
delete_member
add_member
send_raw_msg
send_msg
send_file
send_image
send_vedio
send
search_member
AbstractUserDict 里的 send,基本都是调用 core 里的,core 是通过 property 设置的一个属性
def send_image(self, fileDir, mediaId=None):
return self.core.send_image(fileDir, self.userName, mediaId)
core 类里也不是真正实现函数地方,还有其他地方
def send_msg(self, msg='Test Message', toUserName=None):
''' send plain text message
for options
- msg: should be unicode if there's non-ascii words in msg
- toUserName: 'UserName' key of friend dict
it is defined in components/messages.py
'''
raise NotImplementedError()
应该是 core.py 最后的 load_components,各种的实现又放在各自的 py 里,如 contact.py,hotreload.py 等
具体的 requets 用法,都在这些文件里,好好看懂,基本就是这个了.
from .contact import load_contact
from .hotreload import load_hotreload
from .login import load_login
from .messages import load_messages
from .register import load_register
def load_components(core):
load_contact(core)
load_hotreload(core)
load_login(core)
load_messages(core)
load_register(core)
在 load_xxx 指向了真正的调用者,这样的好处?封装,解耦把? 还有绝的比较好的,就是简化 import
def load_contact(core):
core.update_chatroom = update_chatroom
core.update_friend = update_friend
core.get_contact = get_contact
core.get_friends = get_friends
core.get_chatrooms = get_chatrooms
core.get_mps = get_mps
core.set_alias = set_alias
core.set_pinned = set_pinned
core.add_friend = add_friend
core.get_head_img = get_head_img
core.create_chatroom = create_chatroom
core.set_chatroom_name = set_chatroom_name
core.delete_member_from_chatroom = delete_member_from_chatroom
core.add_member_into_chatroom = add_member_into_chatroom
Contactlist
还有 1 个 contactlist,继承自 list, 也是把 core 当成了一个属性
list->Contactlist
ContactList 有 1 个 ContactClass 成员,就是上面的 AbstractUserDict 的子类实现,通过 set_default_value 赋值:
def set_default_value(self, initFunction=None, contactClass=None):
if hasattr(initFunction, '__call__'):
self.contactInitFn = initFunction
if hasattr(contactClass, '__call__'):
self.contactClass = contactClass
调用 ContactList.append 时,会用到:
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)
Storage
哪个类又用到了 ContactList?是 Storage.存 1 个用户所有的联系人信息?核心是实现了各种 search
class Storage(object):
def __init__(self, core):
self.userName = None
self.nickName = None
self.updateLock = Lock()
self.memberList = ContactList()
self.mpList = ContactList()
self.chatroomList = ContactList()
self.msgList = Queue(-1)
self.lastInputUserName = None
self.memberList.set_default_value(contactClass=User)
self.memberList.core = core
self.mpList.set_default_value(contactClass=MassivePlatform)
self.mpList.core = core
self.chatroomList.set_default_value(contactClass=Chatroom)
self.chatroomList.core = core
def search_friends(self, name=None, userName=None, remarkName=None, nickName=None,
wechatAccount=None):
def search_chatrooms(self, name=None, userName=None):
def search_mps(self, name=None, userName=None):
Storage 又被谁用?自然是 core 里引用:
class Core(object):
def __init__(self):
''' init is the only method defined in core.py
alive is value showing whether core is running
- you should call logout method to change it
- after logout, a core object can login again
storageClass only uses basic python types
- so for advanced uses, inherit it yourself
receivingRetryCount is for receiving loop retry
- it's 5 now, but actually even 1 is enough
- failing is failing
'''
self.alive, self.isLogging = False, False
self.storageClass = storage.Storage(self)
self.memberList = self.storageClass.memberList
self.mpList = self.storageClass.mpList
self.chatroomList = self.storageClass.chatroomList
self.msgList = self.storageClass.msgList
self.loginInfo = {}
self.s = requests.Session()
self.uuid = None
self.functionDict = {'FriendChat': {}, 'GroupChat': {}, 'MpChat': {}}
self.useHotReload, self.hotReloadDir = False, 'itchat.pkl'
self.receivingRetryCount = 5