Java + Appium + 夜神模拟器实现学习强国积分任务自动化
文章目录
首先,先放源码LitterBaby。
我想装了《学习强国》App的同学都为每天30积分的任务苦恼过。我之前也是因为这30积分非常头疼,不是《学习强国》App不好,而是真的不适合我。我们会学习,但可能不是被迫学习指定内容,为了指标而学习。
GitHub上面有很多Python写的《学习强国》自动化学习项目。我也有在用,但是我想有一个Java编写的,自己改起来顺手的《学习强国》自动学习。
为此,我就写了一个Java的,目前已经实现刷30分。
环境准备
夜神模拟器 6.5.0.3,当然里面还需要安装《学习强国》
(1、5、6我电脑上本来就已经装了,所以我就只用装2、3、4就行了
安装基本都比较顺利,网上教程也挺多。)
上面的环境准备好之后,启动夜神模拟器
后,命令行执行下列命令
|
|
如果List of devices attached
没有显示内容
|
|
那么,需要使用SDK下platform-tools
文件夹的adb.exe覆盖掉夜神模拟器安装目录下bin
目录中的adb.exe和nox_adb.exe
如果做了上面的操作还是不行,试试以下指令。还是不行的话,看看adb的用户指南。
|
|
我这里夜神模拟器的device_ip_address
是127.0.0.1:62001
Appium
LitterBaby的核心就是Appium
了。
Appium是客户端/服务器架构。我们下载的Appium Desktop就是服务器。而LitterBaby做的就是使用Appium的Java客户端库定义一些操作来完成我的目标。
我没有去了解太多关于Appium的知识。感兴趣的可以去官方文档查看详细介绍。
Appium Desktop
打开Appium Desktop之后,显示如下界面,我将Host设置为localhost
了
在Start Server 之前我们需要,先点击下面的按钮配置JDK和Android SDK 的路径
然后启动,显示如下界面
点击放大镜。得到如下界面
然后填入如下信息
|
|
点击Start Session,就能得到如下界面。(在这之前得保证adb devices
能看到你的设备,我这里是夜神模拟器)
这时候我们应该能看到夜神模拟器
中的《学习强国》App也已经打开了。此时Appium
和夜神模拟器
看到的页面是同步的。以上界面对页面元素的操作按钮的所有操作都会反馈到夜神模拟器上的《学习强国》App。同样,在夜神模拟器上的操作也会反馈到上面的页面,点击刷新
按钮就能刷新页面。
到此为止就准备好了,可以开发了。
开始开发
新建工程
用 Sping Tool Suite建一个Spring Boot工程
添加依赖
|
|
主要还是Appium客户端的依赖,其他的都是为了方便完成学习强国的积分任务功能而添加的
上面这些完成了就可以开始写代码了。当然你可以直接clone这个LitterBaby。
添加功能
下面我以《学习强国》里的登录
和阅读文章
为例,讲述怎么使用Appium的Java客户端库。
因为几乎所有的操作都是从AndroidDriver
开始的,所以我们需要构建AndroidDriver
|
|
LitterBaby中的代码如下:
|
|
登录
手机号
和密码
登录就非常简单了。
找到
手机号输入框
。我们在Appium Desktop上用选择元素的按钮选中手机号输入框
。我们可以在右侧的
Selected Element
下看到手机号输入框
的XPath
,Text
,resource-id
等信息。使用
AndroidDriver
的findElementByXPath
方法。(所有的元素我都用的XPath查找,我们可以在网上搜索XPath的教程来学习XPath,这个并不复杂)这里我使用以下XPath查找,意思就是查找所有元素中
resource-id
为cn.xuexi.android:id/et_phone_input
的。1
//*[@resource-id='cn.xuexi.android:id/et_phone_input']
所有的XPath都可以在Appium Desktop的搜索中按XPath搜索尝试能不能搜到元素。
然后调用第2步中
findElementByXPath
返回的AndroidElement
对象的sendKeys
方法,并传入手机号作为参数。同样的操作找到
密码输入框
,并输入密码。找到登录
按钮,然后调用click()
方法点击
到此为止,登录就实现了。
阅读文章
阅读文章不外乎是这些操作
- 找文章
- 进入文章
- 上下滑动阅读文章
- 等待阅读到达指定时间
- 返回
这5步中比较特别的就是上下滑动
和返回
了,其他的就跟登录
差不多,都是先findElementByXPath
找到元素然后调用click()
方法。
那么滑动怎么做呢?
- 我们需要创建一个新的对象
AndroidTouchAction
|
|
- 获取设备的
宽
和高
|
|
- 然后相继调用
AndroidTouchAction
的press
,moveTo
,release
,perform
方法
|
|
返回操作
|
|
常见问题
XPath对了但是找不到元素
这种情况基本就是元素还没加载。我们可以用WebDriverWait对象等待
1 2
wait = new WebDriverWait(androidDriver,30); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xpath)));
滑动的时候报不能在指定元素上执行touch操作
解决办法也是跟上面类似,都是需要等待元素加载完成。
XPath的常用写法
指定属性为<xxx>的元素,例
1 2
//*[@text='<xxxx>'] //*[@resource-id='<xxx>']
指定某个元素的父元素,例
1
//*[@resource-id='cn.xuexi.android:id/general_card_title_id']/parent::*
resource-id
为cn.xuexi.android:id/general_card_title_id
的元素的父元素指定元素之后的同级元素
1
//android.widget.ImageView/following-sibling::android.widget.TextView[ends-with(@text, "学习平台")]
android.widget.ImageView
元素之后的同级元素为android.widget.TextView
的text内容以学习平台
结尾的元素指定元素之前的同级元素
1
//*[@resource-id='cn.xuexi.android:id/action_bar_root']//android.widget.TextView[@text='分享到学习强国']/preceding-sibling::*
倒数第二个元素
1
//android.widget.TextView[@text='欢迎发表你的观点']/following-sibling::*[last()-1]
android.widget.TextView
的text内容为欢迎发表你的观点
的元素之后的同级元素中的倒数第二个元素