手动签到的流程:准备登录 -> 输入卡密 -> 滑块验证码 -> 登录成功 -> 签到。

res文件夹即resources,资源文件夹。存放了img文件夹(图片)、ui文件夹和其他资源文件。__init.py__是默认的项目入口,build.as文件是项目依赖,你看上图,从第三行看起,是不是就是pip install opencv-contrib-python==4.1.2.30等命令。.as文件目测是AirScript的缩写。
签到自动化 - 常用api的使用
滑块验证码有点高级,需要opencv识别/基于超级鹰等识别api,略过了,但是对于多个账号批量签到自动化,肯定是不能略过,得自学的啦。
打开工具箱
点网页上"工具集"按钮:
或者pycharm的AirScript Console的工具箱按钮:
都能打开工具箱:
我的模拟器不知道哪里没调好,网页端调用不了模拟器的屏幕(老师那边是可以调用模拟器的屏幕。),我选用平板。
点击工具箱里的“控件检索”,然后选中右下方"我的"按钮,可以查看到很多属性,例如是否可点击。控件的类型、路径等:
如果手机上切换了界面,你再点击下“简单模式“ / ”复杂模式”即可刷新投屏:
先通过控件类型粗筛
点击控件属性右边的“+”可以生成 根据该属性查找本页面中 所有/第一个 具有该属性的元素
再通过控件某个地标性属性精确定位
上图的查找结果有多个,我就想精准定位到“我的”按钮,那就再点击"文本:我的"属性右边的"+",优化下查找语句:
这次只查到一个节点。
值得说明的是,例如
Selector().type("View").text("我的").find_all()语句,采用的都是模糊匹配,所以Selector().type("View")会查找到TextView和View类型控件,Selector().text("我的")会匹配到文本为"我的"、“我的钱包”等控件。要想精确定位到只有一个结果,比较常用的地标性属性是路径、控件深度、是否可点击属性等。但是路径例如“/FrameLayout/FrameLayout/TextView”比较长,写出的代码长的出丑,你也不想看
Selector().type("FrameLayout").path("/FrameLayout/FrameLayout/TextView").find_all()这么长的代码吧,所以尽量用其他书写较短的属性替代,Selector().type("FrameLayout").depth(3).find_all()这样就好看多了。
执行动作
我们不仅可以看到节点的属性,AirScript还提供了关系操作、动作操作:
我现在想点击"我的"节点,就点动作 - click右边的"+",优化表达式为
Selector().type("TextView").text("我的").click().find_all()执行上述语句,在手机上,你选中的控件会被点击,从而触发相应后果。不过我这里没有跳转页面,细究原因,发现是选中的控件是不可点击属性。
获取所选控件的父级/孩子/兄弟控件
看上图,绿色小框是我上述代码选中的控件,是不可点击的,绿色大框才是可点击的控件。我已唯一性选中绿色小框,那就查找它的父级控件吧。
为什么填1?:
看图,填1表示选中"我的"控件的一级父辈控件(图中绿色),填2表示选中"我的"控件的二级父辈控件(图中黄色),以此类推。
现在我们得到了想要的
Selector().type("Textview").text("我的").parent(1).click().find_all()语句,复制到pycharm中,同步到手机上,然后执行即可。关系函数的参数
AirScript提供了获取孩子、兄弟、父辈控件的三种关系函数,以兄弟关系函数
Node().brother(*n)为例,演示参数的写法。查看可知:
模拟人的操作,避免被检测
Selector().type("Textview").text("我的").parent(1).click().find_all() # 点击“我的”按钮进入“我的”界面
Selector().type("Textview").text("签到").click().find_all() # 点击“签到”按钮进入“签到”界面
直接执行上述代码,机器刚点完“我的”按钮就立马点“签到”按钮,反人类,正常人不点这么快的,在一些app上会检测你的这些反人类操作(我记得淘宝、王者还有截屏来检测的做法)。所以我们加入点时间间隔:
import time Selector().type("Textview").text("我的").parent(1).click().find_all() # 点击“我的”按钮进入“我的”界面 time.sleep(1) Selector().type("Textview").text("签到").click().find_all() # 点击“签到”按钮进入“签到”界面
判断某控件是否存在
例如"我的"按钮的查找路径是Selector().type("Textview").text("我的").find_all(),当能找到这个按钮,就点击按钮,如果因从app退回到桌面而找不到按钮,就不点击,避免脚本报错而终止运行:
if Selector().type("Textview").text("我的").find_all() == None:
Selector().type("Textview").text("我的").click().find_all()
python获取某控件的某属性值
有个控件能被Selector().type("FrameLayout").depth(3).find_all()唯一地定位到,我们打印下
control = Selector().type("FrameLayout").depth(3).find_all()
print(control)
#打印结果是一个数组,为jarray('Lairscript/node/Node;')([<airscript.node.Node 'Node{id='com.android.systemui:id/wifi_combo', text='null', type='FrameLayout', desc='WLAN 信号满格。', hintText='null', packageName='com.android.systemui', path='/FrameLayout/FrameLayout/FrameLayout', rect=Rect(1430, 7 - 1483, 53), childCount=0, inputType=0, maxTextLength=-1, drawingOrder=33, depth=3, clickable=false, checkable=false, checked=false, editable=false, enabled=true, visible=true, dismissable=false, focusable=false, focused=false, heading=false, longClickable=false, childs=[]}'>])
print(len(control)) # 数组长度1
数组长度为1,其实如果Selector().type("FrameLayout").depth(3).find_all()能定位到两个控件,数组长度则为2,所以数组里每个元素是一个控件你可以用python的数组索引来定位控件。
control = Selector().type("FrameLayout").depth(3).find_all() print(control[0]) # Node{id='com.android.systemui:id/wifi_combo', text='null', type='FrameLayout', desc='WLAN 信号满格。', hintText='null', packageName='com.android.systemui', path='/FrameLayout/FrameLayout/FrameLayout', rect=Rect(1430, 7 - 1483, 53), childCount=0, inputType=0, maxTextLength=-1, drawingOrder=33, depth=3, clickable=false, checkable=false, checked=false, editable=false, enabled=true, visible=true, dismissable=false, focusable=false, focused=false, heading=false, longClickable=false, childs=[]} print(control[0].desc) # 获取到控件的属性值:WLAN 信号满格。
获取find_all()的第N个控件
例如Selector(2).type("LinearLayout").find_all()的查询结果有好几个:

我想要第二个,有没有快速的方法嘞?:
-
没有find_all(2)这种语法,只有find()和find_all()
-
你可以导入到python里,通过python的数组的索引获取。舒服了python代码,但是没舒服在网页上的线上调试。
control = Selector(2).type("LinearLayout").find_all() print(control[1])
-
多加点限制条件,控件深度、路径啥的加上,精确定位。
-
通过目标附近的其他易唯一性定位的元素。例如Selector(2).type("View").find_all()只有一个结果,记为A,你要找的元素记为B,A和B是上下相邻的兄弟关系,于是你可以写代码为A.brother(-0.1)来定位到B。
判断图色
有个需求:

当我们已经勾选单选框时,不再点击,否则点击,而该控件,勾选前后没有任何路径、属性等变化。这时需要借助图色判断。
点击工具箱 -> 图色检索 -> 找图:
如下图,你可以截图、看到已有截图、删除某张截图:
点击多点找色栏,然后把鼠标放在投屏上,直到出现原形放大镜。按下键盘上的1~9九个数字键,例如按下
1键,网页会把鼠标所在点的坐标和色值记录在第一行:
注意到"偏色 : #0505",就是色值偏差。因为不同手机型号的绘图API不一样,都是画红色,画出的红色的RGB值略有不同,一般而言"偏色 : #0505"就够了,色值不会出现太大的偏差。
现在我们有了代码
FindColors('1532,1567,#FB4774|1524,1567,#F75279|1540,1591,#FB2E58').find_all()并且允许"偏色 : #0505",点击”查找全部“
注意到机器找到5个符合条件的点。
找色原理
查阅,我们注意到需要导包
from airscript.screen import FindColors,以FindColors('426,346,#05D395|502,351,#05D015|676,569,#05D294')为例,上述含义:在#05D395这个颜色的相对位置(x=502-426,y=351-346)有一个颜色值 #05D015,并且在#05D395这个颜色的相对位置(x=676-426,y=569-346) 存在一个颜色值 #05D294。 所有的颜色都属于第一个颜色点的定位点.
回归我们的需求,老师对单选框上采样了几个点,然后查找符合要求的点,结果查到了登录框,因为登录框也是橙色:
查阅官方文档,发现找色支持选定查找的范围,
FindColors(colors).rect(x,y,x1,y1),
![]()
在网页上,按住鼠标左键,圈出你要的范围,此刻投屏的右下角就显示你要的范围(1310,2393,1556,2520)。// 前面三个分别是设备分辨率、当前点色值、当前点坐标。
但是在我的设备上,这个单选框可能在(1310,2393,1556,2520)范围里,换个分辨率,这个单选框位置就变了呀。
我们尽量做活的脚本,其实控件是有控件范围这个属性的。
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://www.ink0.cn/index.php/2023/11/26/%e5%ae%9e%e6%88%98-%e8%be%b9%e5%ad%a6%e8%be%b9%e7%94%a8/

















共有 0 条评论