前面发的一篇文章《薅羊毛!如何让趣头条自动阅读挣钱》中,我用c++实现趣头条的自动阅读,挣钱拿去买瓜吃了。最近刚好发现薅羊毛的大户很多都被封号做不下去了,我想这不就刚好是我们
散户
薅羊毛的大好时机吗?今天我也找了个用脚本编写的方法,比之前用c++写要更通用,更简单,一起了解下。
感兴趣的欢迎关注我公微信众号,回复“autojs”获取示例代码。
我之前一篇文章《薅羊毛!如何让趣头条自动阅读挣钱》中的自动化方案,有几个明显的问题:
UIAutomator
目前做自动化测试用的很多的框架,是google出品,代码用java编写。感觉搭建环境很麻烦,java语言编译执行一次也很慢。
按键精灵
在官方论坛看到的教程,似乎是通过图色查找来定位UI控件的,不像UIAutomator那么随心所欲。例如要点一个按钮,你先给这个按钮截个图,然后用你截图的像素特征去定位这个控件。脚本语言长得有点丑,个人不喜欢。
auto.js
这个是国人写的,可以用javascript写脚本,环境搭建简单,也可以那样UIAutomator像操控手机界面,而且开发调试很方便。
经过以上对比,我选择了auto.js。
使用auto.js,最终我们只需要在手机上装一个apk,然后用这个apk加载并执行我们写好的脚本。
在开发和测试阶段,auto.js也提供了vs code的插件支持,只要手机和PC网络互通,就可以用vs code编写和调试脚本,非常方便。
auto.js是基于安卓系统的AccessibilityService实现的。应用通过AccessibilityService,可以感知当前手机的各种事件,例如:焦点改变,按键被按下等,同时提供查询当前界面内容的功能。这个服务设计初衷是用于帮助残障用户使用android设备的,但现在广泛被用来写作自动化测试,各种外挂脚本。
安装auto.js应用
在设置界面开启auto.js访问AccessibilityService的权限
安装vs code,然后安装Auto.js-VSCodeExt
扩展插件
按CTRL + SHIFT + P
打开命令面板,输入Auto.j
命令即可看到插件提供的功能:
我们选择Start Server
,即可开启一个http server与手机端调试代码,点击后vs code会有如下提示:
在手机上打开auto.js,点左上角那个菜单按钮:
然后点击"连接电脑",然后输入电脑的IP
在vs code的代码界面按F5
键即可运行代码。
按SHIFT+ F5
即可停止运行。
auto.js可以使用console.log("xxxx");
来打印调试日志。
打开 VS Code上面菜单的"帮助"->“切换开发人员工具”->"Console"即可在代码运行是查看日志信息。
将脚本导入到手机内,然后点击手机上的auto.js应用的脚本
菜单,然后点那个+
号导入你编写好的脚本,然后点击脚本旁边的运行图标即可。
定位元素在界面中的位置,必须了解界面的布局情况,我们使用android sdk\tools\bin\下的中的uiautomatorviewer来获取应用界面布局。
adb连接手机后,打开uiautomatorviewer,然后点击下图中的按钮对手机当前界面进行截屏并分析出布局信息。
成功获取后,界面如下:
可以看到,即使不是自己开发的应用,界面的布局也都完全暴露出来了。根据获取的布局信息,auto.js可以精确找到界面中的元素。例如我点击右上角那个120金币,可以拿到几个关键信息:
- text 元素的文本。上图例子文本为空
- resource-id 元素的唯一id。 上图例子为w0
- content-desc 元素的描述。 上图例子为空
拿到这些信息后怎么用auto.js去查找元素呢?接下来我们看auto.js元素查找部分。
auto.js的作者未开发者提供了比较全的API使用文档,元素查找部分的相关API为:
https://hyb1996.github.io/AutoJs-Docs/#/widgetsBasedAutomation?id=uiselector
text("xxxx").find();
desc("xxxx").find();
id("xxxx").find();
className("xxxx").find();
上边介绍文本查找都用find()接口,其实auto.js还提供了其他接口:
UiSelector.findOnce()
- 返回 UiObject
UiSelector.findOnce(i)
- i {number} 索引
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,并返回第 i + 1 个符合条件的控件;UiSelector.find()
- 返回 UiCollection
返回一个搜索条件的集合,经验证,如果找不到会阻塞UiSelector.findOne()
- 返回 UiObject
在界面中找,找不到就一直等
UiSelector.findOne(timeout)
- timeout {number} 搜索的超时时间,单位毫秒
返回 UiObject
在界面中找,如果超时没找到就返回null
API没啥说的,要注意的是除了UiSelector.findOne(timeout)
,其他的操作找不到元素时,都会阻塞!所以我的脚本里,查找元素都用UiSelector.findOne(timeout)
例如我要在脚本里依次选中"推荐",“生活”…这些不同的内容栏目,防止重复阅读同样的文章。
这里我们不能直接通过text("生活").findOne()
来查找,因为不同的人显示的是不一样的,所以要用列表遍历的方式来做。
第一步,先用uiautomatorviewer分析。可以看到这一排菜单是一个HorizontalScrollView,下边有好几个TextView;HorizontalScrollView的id为xc
。
于是我们的代码类似下面这样:
//查找HorizontalScrollView
var ls = id ("xc").findOne(2000);
/*找出查找HorizontalScrollView的子控件
也就是 "推荐 生活 历史" 这些*/
var titles = ls.find(className("TextView"));
//假如我要点第二个:“生活”
var index = 1;
//选择点击一个
btn = titles.child(index);
//下次阅读下一专栏
index = index + 1 % titles.length
auto.js提供了如下接口
setScreenMetrics(width, height)
- width {number} 屏幕宽度,单位像素
- height {number} 屏幕高度,单位像素
设置脚本坐标点击所适合的屏幕宽高。如果脚本运行时,屏幕宽度不一致会自动放缩坐标。
随着android版本的更新,一般的应用目前已经没法通过ActivityManager获取顶端的Activity了。auto.js使用了AccessibilityService这个服务渠道来获取。对于我们的脚本,使用以下的接口:
/*currentPackage()是auto.js提供的接口*/
var topPackage = currentPackage();
/*currentActivity()是auto.js提供的接口*/
var topActivity = currentActivity();
找到界面元素后,可以通过auto.js提供的接口操控这些元素。
var btn = id("xxx").findOne(2000);
if(null != btn)
btn.click();//点击
我们用到的,发送back键:
back();
可以找到待滑动的UI元素,然后滑动,也可以直接通过全局函数swipe来完成。我觉得后面一种好用:
swipe(starx, starty, endx, endy, timeduration);
程序的整体流程,请看之前发的公众号文章:
现在对于我们来说只需知道如何实现几个功能就行:
通过上一节知识,我们已经可以用auto.js写自动化阅读了。代码就差不多像下面这样:
通过试用auto.js,我觉得它是款非常不错的自动化测试工具,推荐android开发者在软件测试时使用。只要google不取消AccessibilityService这个功能,应该auto.js就一直能用。关于自动化阅读的功能对auto.js来说太简单了,完全可以用来开发你想要的更强大的功能,例如自动抢红包,自动收蚂蚁森林能量,自动收拼多多果园的金币。。。
自动化工具auto.js因为可以用javascript编写,非常简单易学。目前像趣头条这样的软件一搜一大把,都可以拿来练练手。
本文趣头条自动阅读的例子,如果要源码的欢迎关注我的微信公众号,就是下面图片这个,回复"autojs"获取下载地址。如果回复的人多的话我在闲暇时间更新一下脚本,支持多个app的自动阅读脚本,推送给回复过的朋友。