Python|用Python实现一个简单的微信聊天机器人

刚学习Python,做点小玩意练练手( ̄▽ ̄)~*

文章目录
目录
一、准备工作
二、环境搭建
1. 安装安卓工具
2. UIAutomator2安装
3. 配置手机环境
4. 安装weditor
【Python|用Python实现一个简单的微信聊天机器人】三、程序分析
1. 连接手机
2. 启动weditor
3. 整理思路
四、代码实现
五、效果展示
总结




一、准备工作 IDE:pycharm2019
Python:3.7
还有安卓手机一台(^_-)
代码git:代码地址




二、环境搭建



1. 安装安卓工具 首先进入谷歌官网,下载对应的SDK工具,这里我使用的是android-sdk_r24.4.1
Python|用Python实现一个简单的微信聊天机器人
文章图片


下载完之后解压,打开SDK Manager,安装对应的工具(PS:这里我就直接无脑下一步)
Python|用Python实现一个简单的微信聊天机器人
文章图片

安装完之后,配置一下环境变量,在cmd界面输入“adb” 来判断安装是否成功
Python|用Python实现一个简单的微信聊天机器人
文章图片

Python|用Python实现一个简单的微信聊天机器人
文章图片

这样,SDK就装好了




2. UIAutomator2安装 直接执行以下命令进行安装

pip3 install --pre -U uiautomator2



3. 配置手机环境手机用USB连接电脑,手机端开启usb调试。cmd输入adb devices
Python|用Python实现一个简单的微信聊天机器人
文章图片

如果出现 device,则是授权成功。如果出现 unauthorized 则是未授权,需要手机授权
连接成功之后cmd输入命令,安装atx-agent至手机
python -m uiautomator2 init

出现下图则安装成功,手机端会出现一个ATX的app
Python|用Python实现一个简单的微信聊天机器人
文章图片


由于自带的SDK工具无法输入中文,所以还需要一个插件adbkeyboard.apk进行支持

4. 安装weditor 这个插件可以让我们像定位网页元素那样定位手机端元素,执行以下命令进行安装:
pip3install --pre weditor

安装成功之后,使用以下命令启动:
python -m weditor

启动成功后,效果如下:
Python|用Python实现一个简单的微信聊天机器人
文章图片


环境总算搭好了,接下来万事俱备,只欠东风了

三、程序分析 1. 连接手机 连接手机主要有两种方式,一种是通过USB进行连接,还有一种就是通过WiFi连接
USB连接:
这个比较简单,只要一个数据线,然后手机开启USB调试就行了
WiFi连接:
首先手机和电脑连接同一个WiFi,然后执行以下命令:
adb tcpip 5555

再执行以下命令查看:
adb devices

出现这样既成功了:
Python|用Python实现一个简单的微信聊天机器人
文章图片


2. 启动weditor 直接执行以下命令即可:
python -m weditor

启动成功后如下:
Python|用Python实现一个简单的微信聊天机器人
文章图片


3. 整理思路 开始写代码之前,先来理一下思路,主要分以下几步:
  1. 打开微信
  2. 寻找联系人
  3. 打开对话框
  4. 获取回复内容
  5. 做出应答
先来看下第一步,打开微信,这个比较简单,只要获取到微信的包名就行了,执行以下命令:
adb shell pm list package -f |findstr tencent

结果如下:
Python|用Python实现一个简单的微信聊天机器人
文章图片

拿到包名就好办了,直接在weditor运行代码:
d.app_start("com.tencent.mm")

效果如下:
Python|用Python实现一个简单的微信聊天机器人
文章图片


oh,忘了自己有应用分身了 ̄へ ̄,得多加一步了,如果没有分身的话,应该可以直接打开了。用weditor定位到要打开的微信,双击会自动生成代码:
Python|用Python实现一个简单的微信聊天机器人
文章图片


Python|用Python实现一个简单的微信聊天机器人
文章图片


第一步打开微信,完成后,接下来看如何打开对话框。其他跟上边的也差不多。如法炮制,这里就直接定位第一个联系人了,先定位元素:
Python|用Python实现一个简单的微信聊天机器人
文章图片

在双击:
Python|用Python实现一个简单的微信聊天机器人
文章图片


这样打开聊天框也完成了,接来下就是获取回复内容了,这个比较麻烦一点。主要有两个问题:一个是如何区分是对方的消息,还有一个就是如何获取回复的内容。我们先来看第一个问题
Python|用Python实现一个简单的微信聊天机器人
文章图片

Python|用Python实现一个简单的微信聊天机器人
文章图片

对比了两个,发现只有中间的数字不一样,那这个数字代表什么呢,我们数一下当前屏幕上的聊天记录,正好是10条,所以索性猜测是聊天条数 。
再看下两个节点的坐标,是否可以用坐标进行判断呢?还有个问题,如果遇到超长的怎么办?我们可以取元素的中心坐标,再和手机屏幕中心坐标比较,这样只要不撑满整个宽度,貌似就行了。来做一下实验验证一下:
Python|用Python实现一个简单的微信聊天机器人
文章图片


看下结果貌似可以哦

获取对方回复元素后,就可以准备获取回复内容。我们惊奇的发现一件事,元素的text竟然是空的:
Python|用Python实现一个简单的微信聊天机器人
文章图片


额,这就难办了,获取不到内容咋回复。咦,双击了一下。发现可以放大诶
Python|用Python实现一个简单的微信聊天机器人
文章图片


山穷水复疑无路,柳暗花明又一村。赶紧试试能不能取得到值,如下:
Python|用Python实现一个简单的微信聊天机器人
文章图片


哦耶!获取到内容后,只剩最后一步了,就是回复消息了

首先设置我们之前安装的输入法,如下:
Python|用Python实现一个简单的微信聊天机器人
文章图片

编写代码测试一下:
# 点击对话框 d(resourceId="com.tencent.mm:id/iki").click() # 切换输入法 d.set_fastinput_ime(True) time.sleep(1) # 输入内容 d.send_keys("我打算的") # d.set_fastinput_ime(False) # 发送消息 d(resourceId="com.tencent.mm:id/ay5").click()

效果如下:
Python|用Python实现一个简单的微信聊天机器人
文章图片


好了,终于解决了所有问题,接下来就是实现了( ̄▽ ̄)~*

四、代码实现 这里只是简单的重复一句话,直到获取正确的回答(PS:本来想接入图灵机器人的,结果发现要钱的,就放弃了(╥╯^╰╥))。完整的代码如下:
import timeimport uiautomator2 as u2answer_right_list = ["是", "帅", "帅哥", "对", "yes", "很帅", "宇宙第一帅"]; # USB连接 device = u2.connect(); # WiFi连接 # device = u2.connect_adb_wifi("192.168.1.9"); """ 发送消息 """def auto_answer(message="我帅不帅"): # 点击对话框 device(resourceId="com.tencent.mm:id/iki").click() # 切换输入法 device.set_fastinput_ime(True) time.sleep(1) # 输入内容 device.send_keys(message) # d.set_fastinput_ime(False) # 发送消息 device(resourceId="com.tencent.mm:id/ay5").click()""" 打开微信 """def open_chat_window(): # 根据包名启动微信 device.app_start("com.tencent.mm") # 由于手机存在应用分身,所以多出一步 device.xpath( '//*[@resource-id="vivo:id/resolver_slide"]/android.widget.LinearLayout[2]/android.widget.ImageView[1]').click() time.sleep(3) # d(resourceId="com.tencent.mm:id/dub", text="通讯录").click() # 打开置顶的聊天框 device.xpath( '//*[@resource-id="com.tencent.mm:id/f67"]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]').click()def is_right_answer(context): if context in answer_right_list: return True; return False; """ 获取最新内容 """def get_newest_answer(): # 统计所有的聊天框 count = len(device.xpath('//*[@resource-id="com.tencent.mm:id/awv"]/android.widget.RelativeLayout').all()); # 获取最底下的聊天信息 ele = device.xpath('//*[@resource-id="com.tencent.mm:id/awv"]/android.widget.RelativeLayout[' + str( count) + ']/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]'); x, y = ele.center(); window_x, window_y = device.window_size(); if x == window_x / 2:# 相等则是表情包 ele = device.xpath('//*[@resource-id="com.tencent.mm:id/awv"]/android.widget.RelativeLayout[' + str( count) + "]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]"); if ele.exists: x, y = ele.center(); return x, y; """ 获取恢复内容 """def get_answer_content(): x, y = get_newest_answer(); #这里由于会有偏差,所有再取28像素的中心点 cent_x = (x + (x - 28)) / 2; cent_y = (y + (y - 28)) / 2; device.click(cent_x, cent_y); time.sleep(0.1) device.click(cent_x, cent_y); ele = device(resourceId="com.tencent.mm:id/dc3"); text = ""; if ele.exists: text = str(device(resourceId="com.tencent.mm:id/dc3").get_text()).strip(); # 关闭放大框 device(resourceId="com.tencent.mm:id/dc3").click(); else: # 是不是表情包 ele = device(resourceId="com.tencent.mm:id/ei"); if ele.exists: device(resourceId="com.tencent.mm:id/ei").click(); text = "这" \ "是一个表情包" else: # 图片 device.click(x, y); text = "这是一张图片"return text; """ 判断是否是回复 """def is_answer(): x, y = get_newest_answer(); window_x, window_y = device.window_size(); # 如果在屏幕的左侧则是回复 if x < window_x / 2: return True; return False; def start(): open_chat_window(); auto_answer(); if __name__ == '__main__': start(); while True: if is_answer(): text = get_answer_content(); print(text) if is_right_answer(text): break else: auto_answer(); #过5秒检测一下 time.sleep(5) auto_answer("这就对了") device.set_fastinput_ime(False)

五、效果展示 Python|用Python实现一个简单的微信聊天机器人
文章图片

Python|用Python实现一个简单的微信聊天机器人
文章图片







总结 这里uiautomator2可能存在定位不准和点击过快的问题,这里就要大家自己去试了。
刚开始学Python,写的不对的地方欢迎指正(?ω?)

    推荐阅读