一、准备工作
1、下载并安装所需软件。
(1) Python 3.x (本文利用Python写脚本)
(2) Appium
(3) Appium Inspector (便于获取微信App元素ID)
(4) 您还需要Android SDK、ADB、JDK8。
2、通过Windows终端 / CMD 执行pip install appium-python-client,如下图所示。
二、配置环境变量、Appium Server
安装好Appium后运行,出现了下图界面。
这里将Host设置为127.0.0.1,Port设置为4723,并点击红框处Edit Configurations。
点击后设置两个环境变量的位置。这里由于博主没有配置ANDROID_HOME环境变量,需要对该变量设置。而JAVA_HOME已经配置过,所以这里已经自动填写。
三、开启手机的USB安装、USB调试
本文使用真机,对真机而言,需要开启开发者选项中的USB安装、USB调试。
对于MIUI,开发者选项开启的方式为:设置->我的设备->全部参数->连续点击MIUI版本。其它定制UI、(类)原生开启方式类似。
开启开发者选项后,在设置->更多设置->开发者选项中开启如下图中的三个权限。
四、测试能否打开微信App
编写如下Python代码:
from appium import webdriver
desired_caps = {
"platformName": "Android", # 操作系统
"deviceName": "Xiaomi Redmi K30 Pro", # 设备 ID
"platformVersion": "11", # Android版本号
"appPackage": "com.tencent.mm", # app 包名,这里是微信
"appActivity": "com.tencent.mm.ui.LauncherUI", # app 启动时主 Activity
'noReset': True, # 避免每次运行把微信数据重置,实机一定要设置此项!!!否则聊天记录就丢失了
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
开启Appium的Server,用数据线连接手机至电脑,然后执行上述代码。第一次执行时,会在手机上安装Appium的相关应用,对于MIUI,需要在手机亮屏时允许USB安装操作。
如果手机自动打开了微信主界面,说明上述步骤均配置正确。
五、Appium Inspector的使用
1、配置Appium Server与本文第二部分一致。
注意:本文使用的Appium Server是1.x,Remote Path应改为/wd/hub。(参见Appium Inspector文档)
2、配置参数
配置与本文第四部分代码相同的platformName、deviceName等参数。由于博主只连接了一台设备,只在platformName填写了Android。如下图。
填完后点击右下角的Start Session。
注意:如右下角没有Start Session,是窗口显示不全,请最大化窗口后向下滑动鼠标滚轮。
3、使用Appium Inspector抓取元素ID
首先要在确保Appium Server已经启动的基础上打开Appium Inspector,用数据线将手机连接到电脑。手机端设置前文已详细描述。得到了如下图所示的界面。
可以发现,手机屏幕已经在软件界面左半部分出现;可以选择界面中的元素,将鼠标划动到对应位置,其会变为黄色,如上图中标①处。当手机界面有变化时,单击上图②处刷新。
单击要抓取的元素,会在界面右侧显示出对应的ID,如下图所示。
六、向指定微信群发送消息功能的实现
可以用以下思路实现:
(模拟)点击【搜索】按钮 -> (模拟)在【搜索框】输入指定微信群/好友 -> (模拟)点击【搜索结果】 -> (模拟)在【消息文本框】输入要发送的文字 -> (模拟)点击【发送按钮】
思路中方括号部分为需要抓取的ID。
Appium通过ID获取指定元素可用driver.find_element_by_id(),参数为ID字符串,一些早期的教程也调用这个方法。但这是一个被标记过时的方法,如使用会有警告。新的用法如下:
首先需要导入如下包:
from appium.webdriver.common.mobileby import MobileBy as By
调用示例:
driver.find_element(By.ID,'com.tencent.mm:id/j63')
此外,由于手机打开微信、执行每步操作需要时间,在执行每步操作时,sleep一定时间。打开微信的时间较长,可以将时间设置略长些。使用sleep需要导入:
from time import sleep
在本文第四部分的基础上,导入上述两个包,编写代码如下。
#等待微信加载
sleep(10)
#取搜索图标的ID并模拟点击
driver.find_element(By.ID,'com.tencent.mm:id/j63').click()
sleep(2)
#取搜索框的ID并模拟输入,将xxx替换为需要发送的群/好友,确保结果显示在第一行
driver.find_element(By.ID,'com.tencent.mm:id/cd6').send_keys('xxx')
sleep(2)
#取搜索框第一条结果
driver.find_element(By.ID,'com.tencent.mm:id/kpx').click()
sleep(2)
#取文本框的ID并模拟输入,将xxxx替换为需要发送的内容
driver.find_element(By.ID,'com.tencent.mm:id/b4a').send_keys('xxxx')
sleep(2)
#取发送按钮的ID并模拟点击
driver.find_element(By.ID,'com.tencent.mm:id/b8k').click()
#10秒后退出
sleep(10)
driver.quit()
重要提示:您的ID可能并不与上述代码ID相同。请根据您实际抓取的ID作为参数。
在手机未锁屏状态下,执行脚本测试。
七、自动解锁
细心的读者可注意到,上文要求在手机未锁屏状态下操作,而一般情况下无法保证手机一直亮屏。Appium提供了自动解锁的功能,只需要在desired_caps添加如下参数:
"unlockType":"pinWithKeyEvent",
"unlockKey":"1234"
unlockType是密码种类,支持如下五种方式(PIN、密码、图案、指纹、带KeyEvent的PIN):
['pin', 'password', 'pattern', 'fingerprint', 'pinWithKeyEvent']。
unlockKey是密码。
对于指纹,只在Android 6.0以上模拟器可用。对于图案,用1~9分别依次表示9个点(先从左到右,再从上到下。)
对于原生Android,一般用前四种就可以了。但对于MIUI等定制UI,则可能需要使用pinWithKeyEvent解锁。
实测pinWithKeyEvent可用,但也并非一次即可解锁,有时需要尝试三次。
由于Appium还是以适配原生Android为主,通过实际测试,对MIUI来说,pinWithKeyEvent是合适的方法。另外,如果设置了指纹解锁,在Appium自动解锁后会自动把指纹数据删掉,很是无奈。
尽管有些缺憾,仍然可以实现基本的自动解锁功能,从而避免手动操作解锁。
八、设置定时任务
至此,距需求只差“定时”。
首先要创建一个批处理脚本。脚本代码很简单,调用Python执行代码文件,如:
C:/Python310/python.exe c:/Users/xwwyt/wx.py
Windows提供了定时任务功能,打开“任务计划程序”,如下。
然后右击任务计划程序库,选择“新建基本任务”。在弹出的窗口中填写名称和描述,单击下一页,触发器选择每天,并设置定时时间,操作选择运行程序。程序位置填写批处理脚本保存的位置,然后点击完成即可。如下图所示。
至此,实现完成。观察设置的时间是否会向微信发送信息。需要注意的是,由于执行脚本、手机自动解锁、启动App、模拟控制均需要一定的时间,建议将定时设置为早于期望时间30~45秒。