赞
踩
之前我们讲了如何利用python自动获取微信聊天记录,感兴趣的小伙伴可查看我之前的文章。不过,之前的方法都只获取了微信的聊天内容,有些场景或项目中可能需要我们记录各条消息的发送时间。这一节我们来看一下如何获取微信聊天消息的发送时间。
1. 微信PC客户端
(注:这里最好把微信客户端升级至较新版本)
2. python3.x
3. wxauto
pip install wxauto -i https://pypi.tuna.tsinghua.edu.cn/simple
在wxauto.py中,有这么一段代码,用于解析微信聊天窗口中的一些系统消息,如:消息发送时间、撤回信息、“某某邀请某某入群”等等。
def SplitMessage(MsgItem): uia.SetGlobalSearchTimeout(0) MsgItemName = MsgItem.Name if MsgItem.BoundingRectangle.height() == WxParam.SYS_TEXT_HEIGHT: Msg = ('SYS', MsgItemName, ''.join([str(i) for i in MsgItem.GetRuntimeId()])) elif MsgItem.BoundingRectangle.height() == WxParam.TIME_TEXT_HEIGHT: Msg = ('Time', MsgItemName, ''.join([str(i) for i in MsgItem.GetRuntimeId()])) elif MsgItem.BoundingRectangle.height() == WxParam.RECALL_TEXT_HEIGHT: if '撤回' in MsgItemName: Msg = ('Recall', MsgItemName, ''.join([str(i) for i in MsgItem.GetRuntimeId()])) else: Msg = ('SYS', MsgItemName, ''.join([str(i) for i in MsgItem.GetRuntimeId()])) else: Index = 1 User = MsgItem.ButtonControl(foundIndex=Index) try: while True: if User.Name == '': Index += 1 User = MsgItem.ButtonControl(foundIndex=Index) else: break Msg = (User.Name, MsgItemName, ''.join([str(i) for i in MsgItem.GetRuntimeId()])) except: Msg = ('SYS', MsgItemName, ''.join([str(i) for i in MsgItem.GetRuntimeId()])) uia.SetGlobalSearchTimeout(10.0) return Msg
不过这里的方法只是将这些消息提取出来,没有对时间做进一步解析。我以这个方法为基础,加入了时间转换等代码,使其能够更好地解析时间,满足我们的需求:
def SplitMessageWithTime(MsgItem, step): uia.SetGlobalSearchTimeout(0) MessageInfos = WxUtils.GetMessageInfos(MsgItem) MsgItemName = MsgItem.Name time_pattern1 = r'([01]?[0-9]|2[0-3]):[0-5][0-9]' time_pattern2 = r'新消息' # 用于后面的正则表达式匹配时间 """ 这是我自己设计的一个逻辑。因为不同的电脑分辨率不同,我们不能以一个固定的像素值来判断获取到的消息是系统消息、还是聊天正文消息。因此我以第一次 获取的系统消息为基准,按比例来区分系统消息和聊天正文。一般来说,聊天正文的控件高度要略大于系统消息的控件高度。(这里可能设计得不太好,大家有 更好的方法可以指出) """ # 以第一条内容的尺寸为标准,设定其他控件的尺寸 if step == 0: WxParam.SYS_TEXT_HEIGHT = MsgItem.BoundingRectangle.height() WxParam.TIME_TEXT_HEIGHT = MsgItem.BoundingRectangle.height() * 1.2 WxParam.CHAT_TEXT_HEIGHT = MsgItem.BoundingRectangle.height() * 1.4 Msg = None # 记录'查看更多消息'的标签宽度 if re.search('查看更多消息', MsgItemName): Msg = ('SYS', MsgItemName, MessageInfos) # 获取时间 elif MsgItem.BoundingRectangle.height() <= WxParam.TIME_TEXT_HEIGHT and re.search(time_pattern1, MsgItemName): WxUtils.publish_time = MsgItemName Msg = ('Time', MsgItemName, MessageInfos) # 获取特殊时间 elif MsgItem.BoundingRectangle.height() <= WxParam.TIME_TEXT_HEIGHT and re.search(time_pattern2, MsgItemName): WxUtils.publish_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M') Msg = ('Time', WxUtils.publish_time, [WxUtils.publish_time]) # 聊天消息 elif MsgItem.BoundingRectangle.height() >= WxParam.CHAT_TEXT_HEIGHT: Index = 1 User = MsgItem.ButtonControl(foundIndex=Index) try: while True: if User.Name == '': Index += 1 User = MsgItem.ButtonControl(foundIndex=Index) else: break if WxUtils.publish_time != '': Msg = (User.Name, MsgItemName, MessageInfos, WxUtils.publish_time) # 已经有时间则为消息设置时间 else: Msg = (User.Name, MsgItemName, MessageInfos, '') # 没有时间则先设置为'',后续会继续向前滚动鼠标 except: Msg = ('SYS', MsgItemName, MessageInfos) # 系统标签 elif MsgItem.BoundingRectangle.height() == WxParam.SYS_TEXT_HEIGHT: Msg = ('SYS', MsgItemName, MessageInfos) else: Msg = ('Other', MsgItemName, MessageInfos) uia.SetGlobalSearchTimeout(10.0) return Msg
原理就是分别读取微信聊天窗口的时间和聊天内容,并将聊天内容和对应的时间放到同一个元组中。由于微信的消息发送时间可能会含有“昨天 14:00”、“星期一 14:00”等这种时间格式,这显然是不可用的。因此我们在解析这些元组时,转换里面的时间YYYY-MM-DD HH:MM的格式。
可能有人会问,你怎么知道哪条消息对应哪个时间?大家可在debug模式下查看获取的所有消息,这里的消息获取是从上往下,时间自然也是从早期到现在。我在代码里面设置了一个变量记录最新时间,如果获取的时间晚于变量,则将变量的值更新为更晚的时间。每次的聊天消息的时间都用这个最晚时间。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。