节约"阳寿"——某电商春节炸年兽自动化

4,088 阅读11分钟

PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛

0x1、引言

日常生活中,我每天都要从宝贵的 阳寿(时间) 里划出一小撮来完成各种 "日常",比如下面这些:

  • APP → 签到、浏览、关注、点赞、活动参加,比如阿🐱阿🐶的农场、牧场、金币等;
  • 游戏 → 单机游戏看视频广告30s,免费白嫖角色、装备等,联网游戏每日任务;

资本家 设计这些 "日常",有的是想保持用户日活,有的是想提高广告点击的收益。

一点蝇头小利,就想让我死心塌地给他们打零工,不能忍,翻身农奴把哥唱,这种浪费阳寿的日常 狗都不做

汪汪汪,咳咳,我的家庭条件你又不是不知道,不是氪金大佬,也不是欧皇,非洲人只能靠肝了...

今年央视官宣某电商成为2020年春晚独家红包互动合作伙伴,邀请全面瓜分15亿红包和好物。

2021年中国人口14.13亿,人均分"一个亿",2333。

当然这 "一个亿" 可不是天上掉下来的,你得积极参加活动,多劳多得,比如炸年兽的活动每天必做:

任务列表是这样的:

为了让参与门槛尽量低一些,所以任务都设计得比较简单,就是费阳寿,可以大概分成这几类:

  • 邀请好友助力 (一般不做,容易没朋友)
  • 点击跳转其他页面(店铺、其他网页、自带小程序、微信小程序等)
  • 点击跳转后浏览8s以上
  • 点击跳转后浏览或加购4件商品

一开始傻乎乎地做了两天,后面就发觉不对劲了,至少得花上20分钟,虽说可以边摸鱼边点,但这种频繁切换注意力的感觉,让我很不适。

这是羊毛群里有人发自动炸年兽的快捷指令,巧了,刚从老婆那里继承旧的iPhone,立马安排上:

虽然不知道什么原理,但是自动做任务是真香啊,不过好景不长,没过几天就被和谐了:

无奈又回归 手动档,我恨啊!!!

手动了两天,实在受不了,开发仔怎能受这样的委屈,便琢磨着自己写一个自动做任务的脚本。

本身是Android仔,所以第一时间想到了Android的 无障碍服务(AccessibilityService) 自动点,但实际上不可行,因为它只适合Android原生页面元素的模拟操作,像这种webview加载H5的页面,他是无能为力的。(开发者模式 → 显示边界 就可以知道哪是原生,哪里不是原生):

接着我又想到使用adb命令直接点击坐标啥的,看似简单,写起来却非常繁琐,显示得封装,然后区域判定啥的,还得想办法实现。

前些天摸鱼逛掘金,一篇《网易UI自动化测试探索:Airtest+Poco》 映入眼帘,这不是我写爬虫总结文时提到的自动化测试工具吗?

当时大概了解了一下,因为没有应用场景,所以并没有去试试,这个工具的核心就是:两库一IDE

  • Airtest库 → 图像识别,截图然后匹配对应位置就是在这里实现的,还有一些adb操作封装;
  • Poco库 → 控件搜索,支持Android、iOS原生、大部分游戏引擎、微信小程序等;
  • AirtestIDE → 专用编辑器,通过简易的操作即可快速产出自动化脚本。

用法啥的就不具体介绍了,直接看上述文章、官方文档、视频教程即可快速上手,有问题可以进答疑群问,娟姐还是非常有耐心的哈~

花了半天粗略看完,就忍不住动手尝试了~

Tips:风控原因,自动化操作可能会导致黑号,表现为秒杀秒不了,有些券领不到等,感兴趣想尝试的读者 风险自担 哈。至于笔者,黑不黑号无所谓,茅台啥的也没抢到过,也就平时薅薅羊毛,2333。


0x2、粗暴地面向过程——菜鸡脚本

见招拆招直接干,打开下载好的 Airtest IDE,接上安卓手机:

刷新ADB,看到设备后点下connect,右侧设备窗口出现手机界面,说明连接成功。

接着左侧 Poco辅助窗,下拉选中Android:

这些就是UI层级,然后想下大概的流程:

  • 初始化:干掉APP → 打开APP → 找到游戏入口 → 点击入口
  • 进入活动页:稍等片刻后 → 检查是否有弹窗,有关掉 → 检查爆竹是否已满,是领取
  • 打开任务栏:判断任务栏是否打开,没有点击打开
  • 完成任务:获取未完成任务,点击进入 → 进入后依次判断任务具体做啥 → 执行对应操作

啧啧,开始jio本的编写~

① 初始化

Airtest内部对常用的ADB操作进行了封装,通过简单的API调用即可与设备进行交互,具体可参见文档:《五、Airtest封装的ADB操作》,这里需要的是重启电商APP,不过好像没找到API,只找到了停止和启动:

参数传递的应用包名,所以得先拿到包名,IDE支持直接获取,点击设备窗:

点击 显示Android助手,打开电商App,接着Current App点击刷新:

拿到包名,然后就是定位到入口点击了,点击Poco辅助窗的小锁头:

接着点击设备窗口的入口元素:

Log查看窗就可以看到元素的信息:

然后就调下poco的API了,等待结点出现,然后点击,初始化部分的大概代码就是这样:

② 进入活动页

进入活动页后,有时会弹窗,需要关掉,然后炮竹满了的话收一下:

满的时候,这只憨憨年兽有一帧是这样的,点击Airtest辅助窗口的截屏按钮:

然后拖拉,抠出脸,代码会自动填充这个截图,是这样的:

有时会有弹窗,还得关下,同样是这样:

③ 打开任务栏

跟上面一样,都是抠图,然后点击,这里领任务位置是固定的,直接传入坐标点~

点击后会弹出任务栏:

④ 去完成

然后同样是抠图,点击去完成,进去后是各种子任务的依次执行了,先是8s的耗时任务:

接着是浏览加购4件商品和互动种草城:

好货特卖,城城分现金,还有跳转其他APP然后回来:

就这样简单粗暴地把自动化脚本写完了,虽然勉强能用(BUG巨多),但有两点必须优化下:

  • 运行效率太低 → 点击去完成,打开页面后,还要执行各种判断,才知道具体执行什么操作,8s阳寿任务还好,那种点开就可以直接返回的,属实没必要等那么久。而且做什么任务,在点去完成的时候就知道了,没必要每次都判断;
  • 代码改动繁琐 → 面向过程流水线,没有考虑扩展,改了页面或任务类型,代码改动起来太麻烦了。

0x3、优雅地面向对象——进阶脚本

重启APP,进活动页,打开任务栏这些步骤只执行一次,没太大必要做自动化,代码测试的时候也不好测,所以还是自己手动点击活动页,打开任务列表。

① 任务类型判定策略

先是第一个难点:任务类型的判定,比如 浏览并关注8s可得8000爆竹,人一看就知道该干嘛,进去没关注点下关注,等8s,然后把页面一关,就算完成任务了,但脚本不知道 啊。

一种解法是:人看完配置一个策略文件,脚本直接按照策略解析,比如:

{
    "bt_1": { "task_type": "邀请" },
    "bt_2": { "task_type": "点完就返回" },
    "bt_3": { "task_type": "8s阳寿" },
    "bt_4": { "task_type": "8s阳寿" },
    "bt_5": { "task_type": "浏览4个商品" },
}

先不说每天都要折腾下配个策略,这些任务每完成一个,都会产生一个新任务,而且是随机的,谁顶得住啊?

所以想到另一种解法:OCR,生成截图,然后任务描述区域裁剪,接着文字识别,匹配关键字,执行对应任务。

考虑到OCR识别中文不一定准确,所以只判断任务描述中是否有关键字,比如8s、4个、关注等,也可以进行两串文本的匹配对判断,高于多少百分比认定为同一个任务。

差不多就可以开始敲码了,用到一些其他的第三方模块,AirtestIDE用起来可能不大顺手,所以还是用PyCharm吧,然后这两个库得pip装一下,顺带把百度OCR也装上:

pip install airtest
pip install pocoui
pip install baidu-aip

略去申请百度OCR服务的步骤,未实名认证一个月可白嫖200次,实名认证一个月可白嫖1000次,一天可能就用几十次,实名一次够了。当然,不够也没关系,可以多申请几家,弄一个白嫖OCR池,一个服务商份额用完就用另一个,也可以每次执行OCR操作时,随机用其中一家的OCR服务,跟代理IP池的玩法类似,代码也得写的灵活写,雏形示例如下:

② 任务定义

抽象出一个任务的父类:

然后就是各种任务的具体实现了:

  1. 阳寿任务 → 休眠15s,然后返回

  1. 浏览/加购任务 → 点击四个特定坐标点

  1. 关注任务 → 没关注点关注,然后返回

  1. 品牌墙 → 点击三个品牌,返回,滑动到顶部,重新点开任务栏

  1. 点完就返回 → 这里要注意互动种草城的处理

任务就这些,接着来写任务类型判定的逻辑~

③ 任务类型判定实现

流程就是,对应文字区域截图,然后根据Airtest定位到的去完成任务来判定具体执行哪个任务,先定义一些变量:

然后是初始化和截图:

再接着是去完成的核心代码,需要注意图片匹配总是命中去下单的问题:

然后就是匹配文字,然后调对应Task执行任务了~

而后调用处:

最后运行下看看效果:

啧啧啧,自动挡,就是爽~


0x4、小结

重写后的脚本清爽了不少,扩展起来也方便了一些,但还存在这些问题:

  • 有些地方代码还不够优雅,比如截图部分,其实Airtest里就有这个API了,我还另外用PIL生成;
  • 坐标写死,没有根据屏幕密度自适应,切换到其他手机上,会有问题,比如截图区域不对;
  • 没必要频繁调用的OCR的API,描述文字部分其实来来去去就那些,可以保存图片识别结果,然后图片在执行OCR前,先于本地图片进行相似度的脚本,超过多少认定为同一图片,直接用之前的识别结果即可;
  • 没做异常情况的处理,比如有时抽风弹对话框,得回退两次,有时自己回退等,得提供异常状态重置回复;
  • 得再优化封装下,不止是这个脚本,还有其他APP的脚本,写尽可能少的代码就能轻松实现自动化;

大概就这些,想想每天到公司手机一插,就自动做各种浪费阳寿的日常,真香啊!!!

最后祝大家新春快乐~