分享

教你几招用Python玩转微信

 乙甲壬 2020-07-17

今天我们就带你用Python玩转其中的一些功能。

01

撤回消息

如果有人撤回消息的时候,我们会很好奇,他又撤回了什么见不得人的消息,今天我们就用Python来实现一下第一时间把原消息转发到文件助手,当然也可以发回给发送者,哈哈,满足一下你们的好奇心!

我们先来了解一下微信撤回消息的原理:

其实微信撤回消息原理就是操作者在点击撤回的时候,客户端会自动发一条系统消息:“xxx撤回了一条消息”,然后对方app端收到消息后解析,替换原消息,改个显示的样式即可

猪哥给大家演示一下正常消息和撤回消息的内容到底有什么区别:
正常消息:Content='你好骚啊',大家留意一下MsgId='8784390488772995470'

教你几招用Python玩转微信


撤回消息:Content是一串xml格式的内容

教你几招用Python玩转微信


我们在下面把它格式化看看

<sysmsg type='revokemsg'> <revokemsg> <session>xxx</session> <oldmsgid>1090336364</oldmsgid> <msgid>8784390488772995470</msgid> <replacemsg><![CDATA['猪哥' 撤回了一条消息]]></replacemsg> </revokemsg></sysmsg>

分析上面撤回的Content字段我们发现<msgid>8784390488772995470</msgid>的id与我们之前发送消息的id是一致的,而<replacemsg>这个标签也验证了我们的猜想,确实是用新消息替换原消息。

2.找到被撤回消息

根据抓取正常消息和撤回消息的内容我们发现规则:撤回消息中会包含之前被撤回的那条消息的msgid,那我们只要找到之前那条消息就可以了,而wxpy模块默认为我们缓存了最近的200条消息,所以我们只要遍历这些历史消息然后比较msgid就可以找到被撤回的那条消息啦!

教你几招用Python玩转微信

如果你微信消息太过频繁,2分钟之内消息数量超过200,则可以将max_history设置大些。

3.转发被撤回消息

原理也搞懂了,被撤回的消息也找到了,就差最后一步转发消息了,如果你之前玩过wxpy肯定会了吧,只要一行代码就可以将消息转发:

msg.forward(bot.file_helper)

4.代码

原理和过程讲完了,代码贴出来给大家看看,注释还是比较详细,有不懂得话可以在学习群中问我。

教你几招用Python玩转微信

四、功能验证

教你几招用Python玩转微信

五、总结

微信消息防撤回功能实现简单,但实用性很好,目前项目的唯一缺点就是易用性差,简单说就是我们还没有将项目部署服务器,每次使用都得打开电脑然后运行还得一直开着,猪哥考虑后面将项目部署在云服务器上或者打包成apk,这样就使用起来就非常方便了,而且还可以把apk发给朋友,让朋友也体验此功能!

学会这招,再也不用好奇对方到底撤回了啥消息,快下载项目试试吧!下载项目后可直接运行不需要修改代码

Github项目地址:https://github.com/pig6/wxrobot
wxpy官方文档:https://wxpy./zh/latest

02

获取好友列表

WechatPCAPI 提供了方法 get_friends(),该方法返回信息包括:好友、群和公众号的列表信息,信息内容主要包括:微信号、昵称和自己设置的备注。

我们使用获取的昵称做个简单的词云展示,代码实现如下所示:

logging.basicConfig(level=logging.INFO)def on_message(message): passdef get_friends(): # 初始化微信实例 wx_inst = WechatPCAPI(on_message=on_message, log=logging) # 启动微信 wx_inst.start_wechat(block=True) # 等待登陆成功,此时需要人为扫码登录微信 while not wx_inst.get_myself():  time.sleep(5) print('登陆成功') nicknames = [] # 排除的词 remove = ['还是', '不会', '一些', '所以', '果然',     '起来', '东西', '为什么', '真的', '这么',     '但是', '怎么', '还是', '时候', '一个',     '什么', '自己', '一切', '样子', '一样',     '没有', '不是', '一种', '这个', '为了'   ] for key, value in wx_inst.get_friends().items():  if key in ['fmessage', 'floatbottle', 'filehelper'] or 'chatroom' in key:   continue  nicknames.append(value['wx_nickname']) words = [] for text in nicknames:  if not text:   continue  for t in jieba.cut(text):   if t in remove:    continue   words.append(t) global word_cloud # 用逗号隔开词语 word_cloud = ','.join(words)def nk_cloud():    # 打开词云背景图    cloud_mask = np.array(Image.open('bg.png'))    # 定义词云的一些属性    wc = WordCloud(        # 背景图分割颜色为白色        background_color='white',        # 背景图样        mask=cloud_mask,        # 显示最大词数        max_words=300,        # 显示中文        font_path='./fonts/simkai.ttf',        # 最大尺寸        max_font_size=70    )    global word_cloud    # 词云函数    x = wc.generate(word_cloud)    # 生成词云图片    image = x.to_image()    # 展示词云图片    image.show()    # 保存词云图片    wc.to_file('nk.png')

看一下效果:

教你几招用Python玩转微信

03

查看共同好友

思路

首先通过itchat这个微信个人号接口扫码登录个人微信网页版,获取可以识别好友身份的数据。这里是需要分别登录两人微信的,拿到两人各自的好友信息存到列表中。

这样一来,查共同好友就转化成了查两个列表中相同元素的问题。获取到共同好友信息后,可以通过命令行窗口print出来,也可以写入txt文件。

itchat

itchat是一个开源的微信个人号接口,使用python调用微信从未如此简单——其开发文档 https://itchat./zh/latest/#itchat

首先是安装itchat模块,例如:pip install itchat

安装完成在代码中通过 import itchat 导入,之后直接调用

#获取登录二维码,扫码登录微信网页版itchat.auto_login()#获取好友信息列表friendList = itchat.get_friends(update=True)

通过以上两行,就可以拿到好友数据信息了,之后再从中筛选有用的信息进行处理即可。这里有一处感觉特别酷,就是通过enableCmdQR参数在命令行中展示二维码:

#在命令行生成登录二维码itchat.auto_login(enableCmdQR=True)

好友信息处理

拿到的好友信息是什么样的呢?其实特别有用的并不多,你的微信号和联系方式是拿不到的。

教你几招用Python玩转微信

而这里的UserName,同一个你在不同的微信号中UserName并不相同。所以,在并没有一个可以特定区分好友的情况下,我们选择获取多组信息来组合拼凑成一个整体,这里我选择了以下数据组成一个字典dict:

{'City':'','PYQuanPin':'','Province':'','PYInitial':'','Sex':0,'Signature':'','Signature':'','NickName':''}

通过以上一个字典八组数据来代表每一位独立好友信息。接下来在要比较的两组好友信息列表中,进行查重,这里我采用了最笨的遍历方法:

for i in contactlist:    if i in contactlist2:        if i not in[contactlist[0],contactlist2[0],empty,emptyM,emptyF]:            common_list.append(i)            count += 1

记录信息

由于一些特殊字符因为编码问题无法写入txt文档,我选择既写入txt又同时print出来相结合的方式:

with open('record.txt','w') as f:    print(f'你们共有{count}位共同好友(若除性别外其它信息为空,不在此记录),他们分别是:')    f.write(f'你们共有{count}位共同好友,他们分别是:')    for i in display:        print(i)        try:            f.write(i+'')        except:            f.write('该好友信息中含有字符无法识别,请在窗口中查看')

回顾

整个流程下来,涉及到的就是itchat接口的使用、将信息赋值给list、获取两个list公共元素、将信息写入txt文件这四部分。

除了itchat接口获取好友数据看着复杂外,别的都是基础语法。而itchat相关的代码就几行,所以你说,python是不是贼好用?

代码下载

除了代码外,这里我也将py文件封装成了exe文件来直接下载,这样即使电脑没装python或者你不用python也可以拿来玩了。

04

消息轰炸

准备

  • Python3.6 需要安装python3.6并配置好环境路径

  • 安装好python后,打开电脑的CMD终端输入pip install itchat安装itchat模块

  • 需要设置好默认看图软件

核心代码

import itchatimport timeprint('扫一下弹出来的二维码')itchat.auto_login(hotReload=True)boom_remark_name = input('输入你要轰炸的人的微信备注,按回车建继续')message = input('输入你要轰炸的内容,按回车键开始轰炸')boom_obj = itchat.search_friends(remarkName=boom_remark_name)[0]['UserName']while True: time.sleep(0.5) print('正在轰炸。。。') itchat.send_msg(msg=message, toUserName=boom_obj)在学习过程中有什么不懂得可以加我的python学习交流扣扣qun,784758214群里有不错的学习视频教程、开发工具与电子书籍。与你分享python企业当下人才需求及怎么从零基础学习好python,和学习什么内容

代码讲解

import itchat

导入itchat模块

import time

导入time模块

itchat.auto_login(hotReload=True)

登录微信,采用热加载的方式登录网页版的微信,会生成一个itchat.pkl的文件,用于保持登录状态,有点类似于cookie

教你几招用Python玩转微信

boom_remark_name = input('输入你要轰炸的人的微信备注,按回车建继续') 这里一定要输入你给微信好友的备注名,否者无法定位到好友

message = input('输入你要轰炸的内容,按回车键开始轰炸')

这里输入要轰炸的内容

boom_obj = itchat.search_friends(remarkName=boom_remarkname)[0]['UserName']

这里通过微信好友的备注名找到微信好友的信息,再通过UserName定位到好友

while True: 死循环轰炸 time.sleep(0.5)设置睡眠,以免出现消息发送频繁导致不能发送微信消息,此处可自行设置,睡眠时间不能太短 print('正在轰炸。。。')

教你几招用Python玩转微信

itchat.send_msg(msg=message, toUserName=boom_obj)

教你几招用Python玩转微信

如何使用

  • 打开CMD终端

  • 输入python

  • 将We.py文件拖入终端

  • 按回车

  • 扫一下弹出来的二维码,确认登录微信

  • 输入你要轰炸的人的微信备注(!!!一定要是微信好友的备注,没有备注请添加备注)

  • 输入要轰炸的内容

  • 按回车键开始轰炸

如何退出

按Ctrl + C 退出轰炸

04

拍一拍

用appium模拟操控手机并截图,通过图像识别定位好友头像坐标,最后用appium模拟双击头像坐标,以此实现“拍一拍”功能。

效果展示:

具体步骤:

一、用appium操控手机

关于appium的安装及使用方法,这里就不再赘述了,直接进入操作步骤

1.用python打开微信,代码如下

desired_caps = {'platformName': 'Android',            'deviceName': 'VOG-AL00',            'appPackage': 'com.tencent.mm',            'appActivity': '.ui.LauncherUI',            'noReset': 'true',            'fullReset': 'false'}server = 'http://localhost:4723/wd/hub'driver = webdriver.Remote(server, desired_caps)

难点在于desired_cap参数的配置,这里再给大家介绍一下:

  • platformName:表示设备操作系统
    deviceName:表示设备名称
    apppackage:表示app程序包名
    appActivity:表示app入口Activity名。

将手机连接电脑,打开开发者模式,运行此程序,就会发现手机自动打开了微信。

二、模拟双击头像

1.原理介绍

我们都知道,微信“拍一拍”是通过双击好友头像实现的,如下图所示:

教你几招用Python玩转微信

想要双击头像,就要先获得头像在屏幕中的坐标

这里给大家介绍1个函数:

基于Python-opencv2的目标定位模块:Aircv使用其find_template函数,可以查找目标图像在原始图像中的坐标范围,用法如下:

def matchImg(imgsrc, imgobj, confidencevalue=0.7): imsrc = ac.imread(imgsrc) imgobj = ac.imread(imgobj) match_result = ac.find_template(imsrc, imgobj,confidencevalue) return match_result

其中imgsrc=原始图片路径,imgobj=待查找的目标图片路径。
如果未找到,则match_result=None;
若找到,则返回如下数据:

{'result':(570.0, 2771.0), 'rectangle': ((30, 1601), (30, 3941), (1110, 1601), (1110,3941)), 'confidence': 0.999999463558197}

其中:

  • result为匹配图片在原始图片上的中心坐标点,也就是我们要找的点击点;

  • rectangle为匹配图片在原始图像上四边形的坐标;

  • confidence为匹配相似率。

2.那么该如何在程序中自动获取获取好友头像坐标呢?

在客户端appium中,可以确定头像在屏幕中的像素为140×140
我们可以先把好友头像保存,再用ps把头像改为此像素。

然后在程序中创建1个while循环,在第一步完成的基础上,手动进入好友聊天框(其实也可以通过识别好友头像自动进入)

通过appium对手机屏幕截图并命名为src.png,将其和头像路径(obj.png)导入1中的检测函数:

driver.save_screenshot('src.png')imgsrc='src.png'imgobj='obj.png'match_result=matchImg(imgsrc, imgobj)

若返回None,则说明聊天窗口没检测到好友头像,继续循环;

若检测到头像坐标,则解析返回的坐标数据,用for循环模拟双击坐标位置:

if match_result is not None:    result = [match_result['rectangle'][0], match_result['rectangle'][3]]    for i in range(2):        driver.tap(result,100)    print('拍成功')else:    print('没找到头像')

这样就大功告成了

教你几招用Python玩转微信

是不是很简单?

05

自动告警

说到告警,相信每个运维人员都不会陌生。以往我们用来发送告警的方式往往是短信或者邮件,但是这两种方式要么不够灵活要么实时性不够。随着微信的普及,现在越来越多的互联网应用选择用微信作为平台发送告警信息,今天就跟大家分享一个利用Python实现微信告警的方法。

目前集成微信告警主要有两种方式:

  • 个人微信号发送告警

  • 订阅号/服务号/企业微信发送告警

个人微信号发送告警

使用个人号发送信息,其实就是通过调用API实现模拟网页登录与发信,这种方式需要使用个人账号扫描二维码登录以后,脚本才能运行,实现的效果与收到朋友的微信无异,还可以发送至指定群聊。听着都挺好,就是可惜当前微信已不支持网页登录了。。。(太坑爹,debug半天才发现…)

教你几招用Python玩转微信

企业微信发送告警

微信的公众号拆分成了订阅号与服务号,如果通过订阅号与服务号发送告警,即显得专业,又无需扫码登录,更适用于服务器上长期运行。但可惜订阅号与服务号群发信息的数量有限制(少得可怜,TX太抠了),我们今天就以企业微信的方式实现微信告警推送。

教你几招用Python玩转微信
注册企业微信

如果自己非当前所属的企业微信管理员,或者暂无企业微信,可以先申请一个,现在申请过程非常简单,申请入口:https://work.weixin.qq.com/

完成后可通过首页进行人员添加

教你几招用Python玩转微信

创建应用

在开始调用公众号的API之前,我们要先创建一个应用,告警可以发送到指定的应用中,同时我们还可以对应用授权,以限制可以看到告警的人员范围。

教你几招用Python玩转微信

创建完成后,点击应用图标可以看到如下内容,记录下AgentId、Secret的值,后续会使用到。

教你几招用Python玩转微信

点击企业信息,查看并记录企业ID,后续会用上。

教你几招用Python玩转微信
调用微信API

实现企业微信自动推送,需要调用如下两个微信的API,详细参数可查看官方文档。

  • 获取token:https://work.weixin.qq.com/api/doc#10013

  • 发送消息:https://work.weixin.qq.com/api/doc#10167

代码实现

如下代码实现调用企业微信进行推送的功能,可结合实际业务环境进行调用和修改。

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
#!/usr/bin/env python3# -*- coding: utf-8 -*-# @Time    : 2020/03/18 20:55# @Author  : Walton# @FileName: WeChatAlert.py# @Software: PyCharm# @Blog    :https://vonten.import timeimport jsonimport requestsDay = time.strftime('%Y{y}%m{m}%d{d}').format(y='年',m='月',d='日')def get_token():    '''    获取access_token    :return: access_token or None    '''    url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'    values = {'corpid': 'Your corpid',  #输入企业ID              'corpsecret': 'Your secret',  #输入应用secret值              }    req = requests.post(url, params=values)    if req.status_code == 200:        return json.loads(req.content)['access_token']    else:        print('access_token获取失败')        return Nonedef send_msg(agentid, content):    '''    调用微信API实现信息推送    :param agentid: 企业微信agentId    :param content: 推送内容    :return:    '''    url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + get_token()    header = {        'Content-Type': 'application/json'    }    form_data = {        'touser': '@all',        'toparty': ' PartyID1 | PartyID2 ',        'totag': ' TagID1 | TagID2 ',        'msgtype': 'textcard',        'agentid': agentid,        'textcard': {            'title': '自动告警',            'description': content,            'url': 'https://vonten.',            'btntxt': '更多'        },        'safe': 0    }    req = requests.post(url, data=json.dumps(form_data).encode('utf-8'), headers=header)    if req.status_code == 200:        return json.loads(req.content)    else:        print('告警推送失败')        return Noneif __name__ == '__main__':    send_msg('1000002','<div class=\'gray\'>{date}</div> <div class=\'normal\'>以下设备出现异常,请及时检查!</div><div class=\'highlight\'>XXX核心交换机</div>'.format(date=Day))
结果测试
教你几招用Python玩转微信

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多