当前位置: 首页 > news >正文

App爬虫之强大的Airtest的操作总结

App爬虫之强大的Airtest的操作总结

App爬虫之强大的Airtest的操作总结

# Python使用该框架需要安装的依赖库
pip install airtest
pip install poco
pip install pocoui
from airtest.core.api import *
from airtest.cli.parser import cli_setup
from poco.drivers.android.uiautomation import AndroidUiautomationPoco"""
自动配置运行环境, 如果没有连接设备, 默认连接安卓设备
参数:basedir - 设置当前脚本所在路径,也可以直接传_file_变量进来devices - 一个内容为connect_device url 字符串的列表logdir - 可设置脚本运行是log保存路径,默认值为None则不保存log,如果设置为True则自动保存在<basedir>/log目录中project_root - 用于设置PROJECT_ROOT变量,方便using接口调用
"""
if not cli_setup():auto_setup(__file__, logdir=True, devices=["android://127.0.0.1:5037/10.2.145.168:5555?cap_method=MINICAP&&ori_method=MINICAPORI&&touch_method=MAXTOUCH"])# 连接本机默认端口连的设备号为123和456的两台手机
# auto_setup(__file__,devices=["Android://127.0.0.1:5037/123","Androd://127.0.0.1:5037/456"])poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)# script content
print("start...")# 唤醒并解锁目标设备
wake()# 启动APP
start_app("com.bonade.xxp")# home键操作
# home()# 若是设置的APP开着,则关闭APP
# stop_app("com.bonade.xxp")# 安装待测软件apk,路径信息。
# install("path/to/your/apk")# 卸载安装
# uninstall("package_name_of_your_apk")

一、 定位方式

child:获取当前节点下的子节点,
如果是多个获取多个,用for循环获取,不使用循环提取的默认提取第一个节点

def child(self, name=None, **attrs): 

示例:

menuList1=poco("com.aa.bb:ide_bottom_navigator").child("android.widget.LinearLayout")
for i in range(0,len(menuList1)):  #同列表方式一致,节点序号从0开始print ("第 %d 次用child获取menuList底部全部菜单=====%s"%(i,menuList1[i]))

children:获取子节点
获取字节点,如果是多个获取多个,用for循环获取,不使用循环提取的默认提取第一个节点

def children(self): 

示例:

menuList2=poco("com.tencent.nbagametime:ide_bottom_navigator").child("android.widget.LinearLayout").children()
for i in range(0,len(menuList2)):print ("第 %d 次用children获取menuList底部菜单名=====%s"%(i,menuList2[i]))

offspring:孙节点
获取当前节点下的孙节点,如果是多个获取多个,用for循环获取,不使用循环提取的默认提取第一个节点

def offspring(self, name=None, **attrs): 

offspring查找孙节点的顺序:树结构自底往上,同一层从中间右边左边的顺序
sibling:兄弟节点
获取当前节点的兄弟节点

def sibling(self, name=None, **attrs):  

parent:父节点
获取当前节点的父节点,如果获取的当前节点是多个(用children获取的),则获取列表第一个节点的父节点

def parent(self): 

注意:此方法在Android上可用,在Ios上不可用,会报错:AttributeError: ‘UIObjectProxy’ object has no attribute ‘parent’ attr(‘type’):提取属性值
示例:

poco('ssion').attr('type') #提取指定元素属性为type的值

get_text():提取文本内容
示例:

poco('ssion').get_text() #提取指定元素的文本内容

exists():判断元素是否存在
示例:

poco('ssion').exists() #判断指定元素是否在当前屏幕上存在,返回True

元素文本正则匹配:

poco(textMatches='^测试.*$', type='Button', enable=True)

二、 元素操作

click():点击操作

def click(self, focus=None, sleep_interval=None): 

focus:值为:(x,y)或“anchor”或“center”。(x,y)意思是距元素左上角的偏移点,值必须在0~1范围内。
center是指点击ui元素边界框的中心。 anchor”是指监视器中UI包围盒的小红点。
sleep_interval:点击操作后等待的秒数。默认值为无,这里默认睡眠间隔。这个值可以通过POCO初始化进行配置。
示例:

poco('home_bottom_navigator').click() #无参数默认点中间位置无间隔时间
poco('home_bottom_navigator').click([0.5, 0.5]) #相当于点中间位置
poco('home_bottom_navigator').click([0.5, 0.5],3) #传参,点击元素中间红点后等待3秒

rclick():右键点击

def rclick(self, focus=None, sleep_interval=None): 

focus:同click方法
sleep_interval:同click方法

double_click():双击操作

def double_click(self, focus=None, sleep_interval=None): 

focus:同click方法
sleep_interval:同click方法

long_click():长按操作

def long_click(self, duration=2.0): 

duration:整个动作持续时间

swipe():滑动操作

def swipe(self, direction, focus=None, duration=0.5): 

direction:坐标,可以是(x,y)格式坐标,也可以是’up’, 'down’, 'left’, 'right’ (up=[0, -0.1],down=[0, 0.1],left=[-0.1, 0],right=[0, 0.1])
focus:同click方法 duration:间隔时间,float类型,默认0.5秒
示例:

node= poco('home_bottom_navigator').child('point_img')
node.swipe('up') #向上滑动
node.swipe([0.2, -0.2])  # 以45度角向上和向右滑动sqrt(0.08)单位距离

说明:swipe操作以 锚点anchor为起点,如果想改变起点可用 focus 方法,然后朝给定方向滑动,距离就是向量的长度。

drag_to:拖拽

def drag_to(self, target, duration=2.0): 

target:拖动后的目标元素
duration:间隔时间,float类型,默认2秒 备注:

区别:
darg 是从一个UI拖到另一个UI,
而 swipe 是将一个UI朝某个方向拖动。

示例: .

poco(text='比赛').drag_to(poco(text='开始')) #把比赛元素拖动到开始元素上

scroll:卷动效果

就是从一个方向一点一点的显示出来
一种特效,就是下拉页面啊,或者其他移动的时候,眼睛会比较舒适,其实区别不大。

def scroll(self, direction='vertical', percent=0.6, duration=2.0): 

direction:滚动方向。”垂直“或水平”,默认垂直 percent:在指定元素上按高或宽的滚动百分比
duration:间隔时间,float类型,默认2秒

pinch:捏合操作
双指捏合是一个比较常见的手势操作了,我们经常打开相册时用这个手势去放大、缩小图片,以便查看。

def pinch(self, direction='in', percent=0.6, duration=2.0, dead_zone=0.1): 

direction:滚动方向。”垂直“或水平”,默认垂直
percent:在指定元素上按高或宽的滚动百分比
duration:间隔时间,float类型,默认2秒 dead_zone:

focus:局部定位

def focus(self, f): 

f:同click()方法
示例:

poco('比赛').focus('center').click()  #定位到元素中间点,进行点击
poco('比赛').focus([0.5,1]).click()  #定位到元素最下边缘的中间点,进行点击

将 focus 和 drag_to 结合使用还能产生卷动(scroll)的效果,下面例子展示了如何将一个列表向上卷动半页。
第9点中的scroll实现方式就是这样的 示例:

poco(“元素”).focus([0.5, 0.8]).drag_to(poco(“元素”).focus([0.5, 0.2])) #从指定节点的中下方拖拽到中上方,比如手机端的从下往上滑动  

start_gesture():移动设备手势分解方法,
返回用于生成序列化手势操作的对象。
示例:

ui1=poco("ui1")
ui2=poco("ui2")
ui1.start_gesture().hold(1).to(ui2).hold(1).up() #在ui1元素上按下,等待1秒,拖拽到ui2元素上再等1秒,最后抬起释放

get_position():获取元素位置坐标,
返回(x, y)坐标

def get_position(self, focus=None) 

focus:同click()方法,默认空 wait():等待,直到超过timeout的时间,超时后返回元素对象 def wait(self, timeout=3)
说明: 在给定时间内等待一个UI出现并返回这个元素,如果已经存在了那就返回这个元素。如果超时还没出现,同样也会返回,但是调用这个UI的操作时会报错。

经验:结合exists()方法可以判断元素是否出现,比如: poco(“元素”).wait(4).exists() #如果结果是True则元素存在,如果False则元素不存在
wait_for_appearance():等待出现,

若超时返回

PocoTargetTimeout def wait_for_appearance(self, timeout=120) 

备注: wait_for_appearance()同wait()的区别:前者超时没找到元素直接返回异常PocoTargetTimeout,后者超时后还返回元素当调用时会报错。
wait_for_disappearance():等待未出现,
若超时返回

PocoTargetTimeout def wait_for_disappearance(self, timeout=120):  

attr():获取属性 def attr(self, name):
name:属性名 示例:

poco("节点").attr('text')

说明:通过给定的属性名检索ui元素的属性。如果属性不存在,则返回none。
属性名可以是以下类型之一,也可以是由SDK实现的任何其他自定义类型: -

- visible: whether or not it is visible to user
- text: string value of the UI element
- type: the type name of UI element from remote runtime
- pos: the position of the UI element
- size: the percentage size [width, height] in range of 0~1 according to the screen
- name: the name of UI element
- ...: other sdk implemented attributes

setattr():设置属性值,
更改ui元素的属性值。

def setattr(self, name, val) 

name:属性名
val:属性值
说明:并非所有属性都可以转换为文本。如果改变不可变的属性或不存在的属性,将引发InvalidOperationException异常
exists():判断是否存在,
返回True/False

def exists(self)  

get_text():获取UI元素的文本属性,
如果没有此类属性,则返回None

def get_text(self)  

set_text():设置文本值

def set_text(self, text) 

text:文本值

get_name():获取元素名,
即属性是name的值,
attr('name’)

def get_name(self)  

get_size():获取元素size,
即属性中的size(attr('size’)),
值:size : [1, 0.76328125]

def get_size(self):  

get_bounds():获取UI元素边界框的参数

def get_bounds(self) 

说明:返回列表形式,如 (top, right, bottom, left)形式的,与标准坐标系中屏幕边缘相关的坐标。

nodes:在远程运行时中访问UI元素的只读属性。
def nodes(self) 调用方式:

poco("节点").nodes

invalidate():重新获取元素标识

def invalidate(self) 

说明:清除标志以指示重新查询或从层次结构中重新选择UI元素 等待时间:强制等待\全局隐式等待\显示等待时间
全局隐式等待:

ST.FIND_TIMEOUT=60 #设置隐式等待60秒

隐式等待
是一种智能等待,他可以规定在查找元素时,在指定时间内不断查找元素

  • 如果找到则代码继续执行,直到超时没找到元素才会报错,也就是说如果在第三秒找到元素,则剩下的7秒不会被等待
    显式等待:wait()
  • 1、显示等待也是一种智能等待,在指定超时时间范围内只要满足操作的条件就会继续执行后续代码

  • 如果不满足条件则会一直等到超时
    强制等待:sleep()

  • 隐式等待和显示等待的区别:

  • 1、隐式等待是全局的,可以随时更改的,显示等待是针对单一元素或者一组元素的

  • 2、隐式等待只能针对元素查找方法,显示等待可以自定义等待条件

相关文章:

App爬虫之强大的Airtest的操作总结

App爬虫之强大的Airtest的操作总结 App爬虫之强大的Airtest的操作总结 # Python使用该框架需要安装的依赖库 pip install airtest pip install poco pip install pocouifrom airtest.core.api import * from airtest.cli.parser import cli_setup from poco.drivers.android.…...

MODBUS-TCP转MODBUS-RTU通信应用(S7-1200和串口服务器通信)

在学习本博客之前,大家需要熟悉MODBUS-TCP和MODBUS-RTU通信,这2个通信的编程应用,大家可以查看下面文章链接: MODBUS-RTU通信 MODBUS-RTU通信协议功能码+数据帧解读(博途PLC梯形图代码)-CSDN博客MODBUS通信详细代码编写,请查看下面相关链接,这篇博客主要和大家介绍MODB…...

开源贡献难吗?

本文整理自字节跳动 Flink SQL 技术负责人李本超在 CommunityOverCode Asia 2023 上的 Keynote 演讲&#xff0c;李本超根据自己在开源社区的贡献经历&#xff0c;基于他在贡献开源社区过程中的一些小故事和思考&#xff0c;如何克服困难&#xff0c;在开源社区取得突破&#x…...

seata的TCC模式分析

TCC是 Try- Confirm-Cancel 这3个名词的首字母简称&#xff0c;是一个2阶段提交的变体思路。 Try&#xff1a;对资源的检查和预留&#xff1b; Confirm: 确认对预留资源的消耗&#xff0c;执行业务操作&#xff1b; Cancel&#xff1a;预留资源的释放&#xff1b; TCC的事务…...

常用linux命令【主要用于日志查询,目录切换】

Xshell设置登录 &#xff1a;主机&#xff0c;端口号 用户身份验证&#xff1a;账号/密码登录脚本&#xff1a;等待-[hcuserserver02 ]$ 发送-cd /data/logs/pl-capital-processer-server/$(date “%Y-%m-%d”) 下方-添加按钮/编辑 发送文本&#xff0c;追加 grep --color de…...

Python学习基础笔记七十六——Python装饰器2

装饰器&#xff0c;英文名字decorator。 我们开发Python代码的时候&#xff0c;经常碰到装饰器。 通常被装饰后的函数&#xff0c;会在原来的函数的基础上&#xff0c;增加一些功能。 通常装饰器本事也是一个函数&#xff0c;那么装饰器是怎么装饰另外一个函数的呢&#xff1f…...

生产环境解决用户登录问题的实践

目录 1 前言2 问题提出3 问题分析和解决4 技术分析和改进5 结语 1 前言 在开发管理软件平台为美术馆时&#xff0c;我们致力于提供一个多系统集成平台&#xff0c;其中包括艺术品管理、志愿者管理和数字资产管理等子系统。为了确保用户享有流畅的体验&#xff0c;我们采用了一…...

通讯协议学习之路:QSPI协议理论

通讯协议之路主要分为两部分&#xff0c;第一部分从理论上面讲解各类协议的通讯原理以及通讯格式&#xff0c;第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN&#xff1b;视频会发布在bilibili(UID:399951374) 一、…...

pip安装修改镜像源

使用pip安装报错时&#xff0c;例如 raise ReadTimeoutError(self._pool, None, “Read timed out.”) pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host‘download.pytorch.org’, port443): Read timed out 可以选择国内的镜像源&#xff0c;如下…...

QCC51XX-QCC30XX系列开发教程(实战篇) 之 12.4-空间音频手机侧和耳机侧接口设计时序图

查看全部教程开发请点击:全网最全-QCC51xx-QCC30xx(TWS)系列从入门到精通开发教程汇总(持续更新中) ==================================================================== 版权归作者所有,未经允许,请勿转载。 ==========================================...

Mysql创建视图中文乱码修改docker里的配置

问题现象&#xff1a; 创建的视图查询无数据&#xff0c;查看创建语句得知&#xff0c;where条件里的中文变成了“???”。 在客户端里查询字符编码&#xff1a; show VARIABLES like %char%;就是character_set_server导致的&#xff0c;它配置的竟然不是utf8&#xff0c;…...

uniapp checkbox样式失效,选中框选中按钮不显示

找了很多方法 最后网上一个博主找到了解决方法 在项目的main.css里面 如果你不知道你的css样式在哪个文件夹 直接全局搜索‘ 找到注释两个地方 第一个 checkbox::before 找到这一行 注释箭头指的地方就可以 第二个 checkbox .uni-checkbox-input::before, 注释这两个地方…...

机器学习-最小二乘法

概况 最小二乘法其实就是为数据(二维)拟合出一条直线&#xff0c;为(三维)数据拟合出一个面。来最大程度的是我们的样本点落在该直线上。 使得我们找到一条直线使所以的样本点尽可能靠近该直线&#xff0c;即每个样本点到直线的距离最短。 YWXB&#xff0c;W是权重&#xff0…...

Linux文件管理与用户管理

一、查看文件内容 1、回顾之前的命令 cat命令、tac命令、head命令、tail命令、扩展&#xff1a;tail -f动态查看一个文件的内容 2、more分屏显示文件内容&#xff08;了解&#xff09; 基本语法&#xff1a; # more 文件名称 特别注意&#xff1a;more命令在加载文件时并不…...

java中什么是不可变类

什么是不可变类 不可变类是指一旦创建对象后&#xff0c;其状态(属性值)就不能被修改的类。 一个不可变类具有以下特征&#xff1a; 类的实例变量声明为私有的&#xff0c;并且没有提供修改这些变量值的公共方法。类是final的&#xff0c;防止被继承。类的实例变量声明为fin…...

使用Perl和WWW::Mechanize库编写

以下是一个使用Perl和WWW::Mechanize库编写的网络爬虫程序的内容。代码必须使用以下代码&#xff1a;jshk.com.cn/get_proxy 首先&#xff0c;确保已经安装了Perl和WWW::Mechanize库。如果没有&#xff0c;请使用以下命令安装&#xff1a; cpan WWW::Mechanize创建一个新的Pe…...

智荟雄安,创想未来 | 竹云董事长受邀出席雄安新区2023软件和信息技术服务业创新发展论坛并作主题演讲

10月18日&#xff0c;以“智荟雄安 创想未来”为主题的雄安新区2023软件和信息技术服务业创新发展论坛在雄安新区国际酒店会议中心召开。河北省委常委&#xff0c;雄安新区党工委书记、管委会主任张国华出席活动。 中国科学院院士朱鲁华现场致辞&#xff0c;中国工程院院士邬贺…...

【设计模式-1】UML和设计原则

说明&#xff1a;设计模式&#xff08;Design Pattern&#xff09;对于软件开发&#xff0c;简单来说&#xff0c;就是软件开发的套路&#xff0c;固定模板。在学习设计模式之前&#xff0c;需要首先学习UML&#xff08;Unified Modeling Language&#xff0c;统一建模语言&…...

【数据结构】——二叉树的基础知识

数概念及结构 数的分类 二叉树、多叉树 数的概念 树是一种非线性的数据结构&#xff0c;它是由n(n>0)个有限节点组成一个具有层次关系的集合。把它叫做树的原因是它看起来像一颗倒挂的树&#xff0c;也就是说它是跟朝上&#xff0c;而叶朝下的。 有一个特殊的节点&…...

日常bug汇总

1.constraintlayout NestedScrollView 可能会导致NestedScrollView 不滑动 2.截屏 open class SecureFragment : LogLifecycleFragment() {override fun onResume() {super.onResume()if (!BuildConfig.DEV) {requireActivity().window.setFlags(WindowManager.LayoutParam…...

C#使用PPT组件的CreateVideo方法生成视频

目录 需求 实现 CreateVideo方法 关键代码 CreateVideoStatus 其它 需求 我们在使用PowerPoint文档时&#xff0c;经常会使用其导出功能以创建视频&#xff0c;如下图&#xff1a; 手工操作下&#xff0c;在制作好PPT文件后&#xff0c;点击文件 -> 导出 -> 创建视…...

数字化体系如何帮助企业拓展裂变增长渠道?数字化营销体系构建?

在当前的商业环境中&#xff0c;数字不仅仅是数据&#xff0c;还代表着技术和资产。企业数字化正是将数据转化为资产的过程。从信息化时代到数字化时代&#xff0c;企业逐渐将业务和组织、管理和创收都朝着在线化和数据化的方向发展&#xff0c;特别是企业的业务板块。数字化营…...

关于vant 的tabbar功能

1、想要实现tabbar页面A&#xff0c;其他的页面B&#xff08;非tabbar页面&#xff09;。 从A页面进入B页面&#xff0c;底部的active选中效果应该被取消掉&#xff0c;但是还是选中A。 按照官网的说法有两个方法 一、根据path路径 二、自定义的model 但是&#xff01;但是…...

:style动态绑定,但只要页面发生变化就会执行一次方法

1、问题 开发过程中有个需求是遍历列表绘制div,div的样式是后端接口传来的&#xff0c;一开始这种写法&#xff0c;&#xff1a;style“formatStyle(item)”&#xff0c;写在了模板中 这样写发现一个问题&#xff0c;只要页面发生重绘&#xff0c;比如页面输入框输入数字&…...

文件的逻辑结构(顺序文件,索引文件)

所谓的“逻辑结构”&#xff0c;就是指在用户看来&#xff0c;文件内部的数据应该是如何组织起来的。 而“物理结构”指的是在操作系统看来&#xff0c;文件的数据是如何存放在外存中的。 1.无结构文件 无结构文件:文件内部的数据就是一系列二进制流或字符流组成。无明显的逻…...

suricata匹配从入门到精通(五)----二次开发保护规则库

0x00 背景 开源的suricata资源包是没有做加密处理,如果想要保护资源包,需要二次开发修改suricata源码。 本文基于suricata6.0.1 版本https://github.com/OISF/suricata/archive/refs/tags/suricata-6.0.1.zip二开。 0x01 实践 通过debug,跟规则处理相关需要修改2个地方。…...

软件测试肖sir__python之ui自动化定位方法(2)

Selenium中元素定位方法 一、定位方法 要实现UI自动化&#xff0c;就必须学会定位web页面元素&#xff0c;Selenium核心 webdriver模块提供了9种定位元素方法&#xff1a; 定位方式 提供方法 id定位 find_element_by_id() name定位 find_element_by_name() class定位 find_elem…...

【JVM面试题】JVM分代年龄为何是15次?能设置为16吗?

系列文章目录 【JVM系列】第一章 运行时数据区 【JVM面试题】第二章 从JDK7 到 JDK8, JVM为啥用元空间替换永久代&#xff1f; 【JVM面试题】第三章 JVM分代年龄为何是15次&#xff1f;能设置为16吗&#xff1f; 大家好&#xff0c;我是青花。拥有多项发明专利&#xff08;都是…...

java三层架构/表现层-业务层-持久层

三层架构 什么是 Java 三层架构 三层架构是指&#xff1a;视图层view&#xff08;表现层&#xff09;&#xff0c;服务层service&#xff08;业务逻辑层&#xff09;&#xff0c;持久层Dao&#xff08;数据访问层&#xff09;&#xff0c; Java的三层架构是指将Java程序分为三…...

视频监控这样做,简单又高效!

随着技术的不断进步&#xff0c;视频监控系统已经变得更加高效和智能&#xff0c;可以提供更全面的监控和分析功能&#xff0c;有助于提高安全性、管理效率和决策支持。 客户案例 超市连锁店 福建某全国性超市连锁店面临高额商品损失、偷窃问题&#xff0c;以及对客户安全和员工…...