初始化代码

App的布局信息就像网页的HTML一样,保存了App上面各个元素的相对位置和各个参数。对于一个App而言,在不同分辨率的手机上,可能相同的元素有着不同的坐标点,但是这个元素的属性参数一般是不会变的。因此,如果使用元素的属性参数来寻找并控制这个元素,就能实现在不同分辨率手机上的精确定位。

App的布局信息的格式与App的开发环境有关。点击F区的下拉菜单,可以看到这里能够指定不同的App开发环境。其中的UnityCocos-*等等一般是做游戏用的,Android是安卓原生App,iOS是苹果的App……如下图所示。

以手机版知乎为例,由于它是Android原生的App,所以在F区下拉菜单选择Android,此时注意B区弹出提示,询问你是否要插入poco初始代码到当前输入光标的位置,点击Yes,如下图所示。

此时,B区自动插入了一段代码,如下图所示。

定位并点击

现在,点击E区的锁形图标,如下图所示。

锁形图标激活以后,你再操作D区的屏幕,点击知乎App下面的知乎两个字,会发现屏幕上被点击的App并不会打开。但E区和C区却发生了变化,如下图所示。

其中E区显示的树状结构就是当前屏幕的布局信息,这与Chrome开发者工具里面显示的HTML结构如出一辙。C区显示的是当前被我点中的元素的信息。

请注意在这些元素信息中,有一个text属性,它的值为知乎。那么,这个属性就可以作为一个定位元素,于是可以在B区编写代码:

poco(text="知乎").click()

写完代码以后运行程序,可以看到知乎App被打开了。如下图所示。

注意,如果你发现手机真机显示的界面与Airtest屏幕显示的手机界面不一致,可能是因为Airtest的屏幕被你锁定了。在F区点一下锁形图标,取消锁定,Airtest中的手机屏幕就会更新了。

定位并输入

打开知乎以后,我想使用知乎的搜索功能,那么继续,把锁形图标激活,然后点击知乎顶部的搜索框,如下图所示:

继续看C区显示的搜索框属性,可以看到这里有一个name属性,它的值是com.zhihu.android:id/input,还有一个text属性,它的值为蔡徐坤任 NBA 新春贺岁大使。能不能像前面打开知乎一样,使用text这个属性呢?也行,也不行。说它行,是因为你这么做确实现在能工作;说它不行,因为这是知乎的热门搜索关键词,随时会改变。你今天使用这一句话成功了,明天热门关键词变化了,那么你的代码就无法使用了。所以此时需要使用name这个属性。

常见的基本上不会变化的属性包含但不限于:name type resourceId package

另外还有一点,知乎首页的这个搜索框,实际上是不能输入内容的,当你点击以后,会跳转到另一个页面,如下图所示。

因此你需要先点击一下这个输入框,跳转到真正的搜索界面:

poco(name="com.zhihu.android:id/input").click()

在真正的搜索界面如下图所示。

可以看到,name属性的值依然是com.zhihu.android:id/input,此时就可以输入内容了。

输入内容使用的方法为set_text,用法为:

poco(name="com.zhihu.android:id/input").set_text('古剑奇谭三')

定位并筛选

输入了搜索关键词以后,再来看看当前页面,搜索出现了三个结果:

通过对比这三个结果的属性信息,发现他们的name属性都是相同的,而text不同。如果像下面这样写点击动作:

poco(name='com.zhihu.android:id/magi_title').click()

那么默认就会点击第一个搜索结果。

如果我想点击第二个搜索结果怎么办呢?可以这样写代码:

poco(name='com.zhihu.android:id/magi_title', text='古剑奇谭(电视剧)').click()

或者你也可以像列表一样使用索引定位:

poco(name='com.zhihu.android:id/magi_title')[1].click()

这两种写法的前提,都是我们已经知道了每个结果分别是什么。假设现在我就想搜索古剑奇谭三,但我不知道搜索结果是第几项,又应该怎么办呢?此时还可以使用正则表达式:

poco(name='com.zhihu.android:id/magi_title', textMatches='^古剑奇谭三.*$').click()

滑动屏幕

进入搜索结果以后,需要查看下面的各种问题,此时就需要不断向上滑动屏幕。这里有一点需要特别注意,Airtest只能获取当前屏幕上的元素布局信息,不在屏幕上的内容是无法获取的。这一点和Selenium是不一样的。

滑动屏幕使用的命令为swipe,滑动屏幕需要使用坐标信息。但这种坐标和屏幕分辨率无关。这里的坐标定义为:(x, y),其中x为横坐标,y为纵坐标。屏幕左上角为(0, 0),屏幕右下角为(1, 1),从左向右,横坐标从0逐渐增大到1,从上到下,纵坐标从0逐渐增大到1。

现在我要把屏幕向上滑动,那么在真机上面,我是先按住屏幕下方,然后把屏幕向上滑动,所以代码可以这样写:

# poco.swipe(起点坐标,终点左边)
poco.swipe([0.5, 0.8], [0.5, 0.2])

方向示意图如下图所示:

在一般情况下:

  • 向上滑动,只需要改动纵坐标,且起点值大于终点值
  • 向下滑动,只需要改动纵坐标,且起点值小于终点值
  • 向左滑动,只需要改动横坐标,且起点值大于终点值
  • 向右滑动,只需要改动横坐标,且起点值小于终点值

在爬虫开发中,涉及到的Airtest操作基本上已经介绍完毕。

单独使用Python控制手机

在Airtest操作手机虽然方便,但是不可能在每一台电脑上都安装Airtest吧。所以需要想办法把代码从Airtest这个程序中分离出来。

Airtest基于Python的一个开源库Poco开发,而在Airtest的B区写的Python代码,实际上就是Poco的代码。所以只要安装Poco库,就可以在Python中直接控制手机。

安装Poco库的命令为:

pip install pocoui

这个库依赖的东西有点多,安装稍稍慢一些。安装完成以后,我们把代码复制到PyCharm中,如下图所示。

运行这段代码,如果是Linux或者macOS的用户,请注意看运行结果是不是有报错,提示adb没有运行权限。这是因为随Poco安装的adb没有运行权限,需要给它添加权限,在终端执行命令:

# chmod +x 报错信息中给出的adb地址

chmod +x /Users/kingname/.local/share/virtualenvs/ZhihuSpider/lib/python3.7/site-packages/airtest/core/android/static/adb/mac/adb(实际执行时请换成你的地址)

命令运行完成以后再次执行代码,可以看到代码运行成功,手机被成功控制了,如下图所示。

如何获取屏幕文字

由于Airtest的编辑器中的代码运行后无法正常打印出中文,因此后面的代码都直接在PyCharm中执行。

既然要做爬虫,就需要获取手机上的文字内容。回到搜索页面,我想知道“古剑奇谭”三这个关键字能搜索出多少条结果,每条结果有多少个讨论,如下图所示:

此时我们需要做两件事情:

  1. 分别查看每一个搜索结果
  2. 获取屏幕上的文字

E区的树状结构如下图所示:

每一个搜索结果的标题作为text属性的值,在name='com.zhihu.android:id/magi_title'对应的元素中;每一个搜索结果的讨论数作为text属性的值,在name='com.zhihu.android:id/magi_count'对应的元素中。

最直接的做法就是分别获取三个标题和三个讨论数,然后把它们合并在一起:

title_obj_list = poco(name='com.zhihu.android:id/magi_title')
title_list = [title.get_text() for title in title_obj_list]discuss_obj_list = poco(name='com.zhihu.android:id/magi_count')
discuss_list = [discuss.get_text() for discuss in discuss_obj_list]for title, discuss in zip(title_list, discuss_list):print(title, discuss)

运行效果如下图所示:

但是这种做法实际上是很危险的,假设会有某一个很生僻的搜索结果,只有标题没有讨论数,那么这样分开抓取再组合的做法,就会导致最后匹配错位。所以合理的做法是先抓大再抓小。每一组标题和讨论数,他们都有自己的父节点,如下图箭头所指向的三个android.widget.LinearLayout:

那么现在,使用先抓大再抓小的技巧,先把每一组结果的父节点抓下来,再到每一个结果里面分别获取标题和讨论数。

然而这个父节点又怎么获取呢?如下图所示,这个父节点每一个属性值都没有什么特殊的,写任何一个都有可能与别的节点撞上。

此时,最简单的办法,就是在E区,双击父节点。定位代码就会自动添加,如下图所示。

这个定位代码看起来非常复杂,但实际上它的内在逻辑非常简单,就是从顶层一层一层往下找而已。

自动生成的定位代码如下:

poco("android.widget.LinearLayout").offspring("com.zhihu.android:id/action_bar_root").offspring("com.zhihu.android:id/parent_fragment_content_id").offspring("android.support.v7.widget.RecyclerView").child("android.widget.LinearLayout")[0]

在这个自动生成的定位代码中,我们看到了offspringchild这两种方法。其中child代表子节点,offspring代表孙节点、孙节点的子节点、孙节点的孙节点……。简言之,使用child只会在子节点中搜索需要的内容,而使用offspring会像文件夹递归一样把里面的所有节点都遍历一次,直到找到符合条件的属性为止。显然,offspring速度会比child慢。

实际上,我们可以对这个定位代码做一些精简:

poco("com.zhihu.android:id/parent_fragment_content_id").offspring("android.support.v7.widget.RecyclerView").child("android.widget.LinearLayout")[0]

这个精简的方法,与从Chrome复制的XPath中进行精简是一样的逻辑,根本原则就是找到“独一无二”的属性值,然后用这个属性值来进行定位。

由于我点击的是第一个搜索结果,所以定位代码的最后有一个[0]。现在由于需要获得所有搜索结果的内容,所以应该去掉[0]而使用for循环展开,然后获取里面的内容:

result_obj = poco("com.zhihu.android:id/parent_fragment_content_id").offspring("android.support.v7.widget.RecyclerView").child("android.widget.LinearLayout")
for result in result_obj:title = result.child(name='com.zhihu.android:id/magi_title').get_text()count = result.child(name='com.zhihu.android:id/magi_count').get_text()print(title, count)

运行效果如下图所示。

控制多台手机

当我们在电脑上插入多个Android手机时,执行命令:

adb devices -l

 

运行效果如下图所示。

每个手机都会被列出来。在最左边的编号就是手机串号。使用这个串号可以指定多个手机:

from airtest.core.api import auto_setup
from airtest.core.android import Android
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
auto_setup(__file__)device_1 = Android('76efadf3a7ce4')
device_2 = Android('adfasdfasf23')
device_3 = Android('adifu39ernla')poco_1 = AndroidUiautomationPoco(device_1, use_airtest_input=True, screenshot_each_action=False)
poco_2 = AndroidUiautomationPoco(device_2, use_airtest_input=True, screenshot_each_action=False)
poco_3 = AndroidUiautomationPoco(device_3, use_airtest_input=True, screenshot_each_action=False)

通过这种方式,在一台电脑上使用USBHub,连上二三十台手机是完全没有问题的。

无线模式

Airtest支持无线模式,不需要USB,只要电脑和手机连接同一个WIFI就能控制:

原文来自:https://juejin.im/post/5c42fd6251882525153c325a

转载于:https://www.cnblogs.com/542684416-qq/p/10916743.html

续上节,,基于App布局信息操作手机相关推荐

  1. 【STM32+cubemx】0028 HAL库开发:MPU6050官方DMP的移植和使用(续上节)

    上一节我们使I2C总线获取了MPU6050的三轴加速度.三轴角速度,并且介绍了一种简单的初始状态校准方法:这一节我们继续,在已有的底层驱动基础上,移植MPU6050芯片官方的DMP库,来获取角度信息. ...

  2. 史上最简单Robotium跨进程操作实践——基于ADB框架

    楼主原创,分享不易,转载请注明出处,谢谢. 2015年2月3日更新: 有些朋友在用真机尝试本方法时,抛出了InputStream cannot be null的异常.该异常是由于adb运行在robot ...

  3. 《移动App测试的22条军规》—App测试综合案例分析23.4节测试微信App的手势操作...

    本节书摘来自异步社区<移动App测试的22条军规>一书中的App测试综合案例分析,第23.4节测试微信App的手势操作,作者黄勇,更多章节内容可以访问云栖社区"异步社区" ...

  4. Spark数据挖掘-基于 LSA 隐层语义分析理解APP描述信息(1)

    Spark数据挖掘-基于 LSA 隐层语义分析理解APP描述信息(1) 1 前言 结构化数据处理比较直接,然而非结构化数据(比如:文本.语音)处理就比较具有挑战.对于文本现在比较成熟的技术是搜索引擎, ...

  5. Unity程序在VR一体机(Android)上卡死(闪退)后怎么办?——用adb查看android上某Unity app的debug信息

    一.之前面临的困境 Unity的程序build到android一体机后,仿佛进入了一个黑箱子,你既看不到脚本的debug报错信息,也看不到任务管理器里的内存和CPU使用情况?如果黑屏.闪屏.花屏怎么办 ...

  6. 移动端通用元件库+app通用元件库+数据展示+操作反馈+通用模板+数据录入+列表页+表单页+详情页+通用版布局+移动端手机模板+业务组件+反馈组件+展示组件+表单组件+导航组件

    移动端通用元件库+app通用元件库+数据展示+操作反馈+通用模板+数据录入+列表页+表单页+详情页+通用版布局+移动端手机模板+业务组件+反馈组件+展示组件+表单组件+导航组件 原型展示及下载地址:h ...

  7. 【毕业设计之微信小程序系列】基于APP的微信点餐小程序的设计与实现

    基于APP的微信点餐小程序的设计与实现 摘 要 本文介绍了一种基于APP的微信点餐小程序的设计与实现方法.该系统利用微信公众号作为用户入口,用户可以通过微信扫码进入点餐系统,选择菜品.下单.支付等操作 ...

  8. 【android免root脚本制作】基于控件的操作——auto.js进阶

    在[android免root脚本制作]自动坐标操作手机--京东金融程序金果摇钱树自动收金果 之后,想要做进一步优化,因为基于坐标点击如何屏幕被移动之类就会点击错位,不同手机还需去适配坐标,甚是麻烦,所 ...

  9. 观察者模式之四:基于知识库的信息推荐系统(本科毕业论文,学术道德问题,严禁抄袭)...

    基于知识库的信息推荐系统 Knowledge lib based information recommendation system 姓    名:谢    松 学    院:数学科学学院 专     ...

  10. 史上最全 App功能测试点分析

    1.2测试周期 测试周期可按项目的开发周期来确定测试时间,一般测试时间为两三周(即 15个工作日),根据项目情况以及版本质量可适当缩短或延长测试时间.正式测试前先向主管确认项目排期. 1.3测试资源 ...

最新文章

  1. 浅谈Redis和Hbase
  2. C++读写EXCEL文件方式比较 .
  3. andorid 通过包名启动应用
  4. vc6.0出现无法解析错误
  5. 10-Flutter移动电商实战-使用FlutterSwiper制作轮播效果
  6. css过渡transition
  7. GDB怎么调试使用.sh(shell脚本)启动的程序?(未完成,待测试)
  8. (原)用pixi.js 实现 方块阵点击后原地自转效果
  9. 手把手教学:Nginx的安装
  10. 这款耳机性价比值得你看一下
  11. 智能传感器产业三年行动指南
  12. oracle创建表空间语句分解
  13. EasyUI 1.5.1 美化主题大包 Insdep Theme 1.0.3 已发布,开源下载
  14. java碰碰球历险记下载_幼儿园玩球教案碰碰球.doc
  15. 国家AAAAA级旅游景区数量统计
  16. python导入mysqldb_Python导入MySQLdb库
  17. Kill Demodogs——c++——pow_na的博客
  18. 【爬虫】关于企业信用信息公示系统-加速乐最新反爬虫机制
  19. Unity的Dots技术入门
  20. 鑫光芒教程进阶篇微信公众号推广方法大公开

热门文章

  1. 基础服务系列-Hyper-V 安装centos7
  2. Hibernate配置文件
  3. 最简单的DX窗口程序
  4. 4 基于优化的攻击——CW
  5. 2019东南大学研究生课程计算机网络安全
  6. Lesson 002 —— 网络七层模型
  7. JAVA多线程----用--取钱问题1
  8. iframe 自适应内容高度
  9. 获取地址栏的最后一个文件
  10. [转]ASP.NET网页请求以及处理全过程(反编译工具查看源代码)