Appium+python自动化(十一)- 元素定位- 下
1、 List定位
List顾名思义就是一个列表,在python里面也有list这一个说法,如果你不是很理解什么是list,这里暂且理解为一个数组或者说一个集合。首先一个list是一个集合,那么他的个数也就成了不确定性,所以这里需要用复数,所以在我们定位时我们不能够接着用find_element_by_id等等定位方式了,我们需要用他的复数形式find_elements_by_id,所有的定位方式都一样需要采用复数加s。这里我们接着上篇的案例讲,如何使用list定位想定位的元素。首先看一下图片:
我们查看图片可以知道我们能够很轻松的通过id定位到整个祖父节点,我们接下来需要做的是定位这个祖父节点下所有的“android.widget.RelativeLayout”父节点,同样的首先我们看一张图:
这里我们需要直接使用定位复数的方法来操作,直接看代码(祖父节点定位到父节点):
element= driver.find_element_by_id("com.taobao.taobao:id/rv_main_container")
elements = element.find_elements_by_class_name("android.widget.FrameLayout")
通过上面的代码我们直接定位了com.taobao.taobao:id/rv_main_container父节点下的所有android.widget.FrameLayout子节点,但是由于这个android.widget.FrameLayout子节点下边还有许多相同的android.widget.LinearLayout孙节点。
这里我们需要直接使用定位复数的方法来操作,直接看代码(父节点定位到孙节点):
1 elements = element.find_elements_by_class_name("android.widget.FrameLayout")
2 elements1 = elements[1].find_elements_by_class_name("android.widget.LinearLayout")
现在我们需要怎么去操作这个子节点了,这里有两种方法:
1、前面我们讲了List你可以理解为一个数组或者一个集合,这里定位的所有子节点最后就成了个list,如果我们要访问这个list里面的某一个元素我们可以像访问数组中的数据一样通过下标访问。最后的代码就是下面这个样子:
1 element= driver.find_element_by_id("com.taobao.taobao:id/rv_main_container")
2 elements = element.find_elements_by_class_name("android.widget.FrameLayout")
3 elements1 = elements[1].find_elements_by_class_name("android.widget.LinearLayout")
4 elements1[1].click()
上面的代码最后的结果是选择了“聚划算”这个标签页面,然后点击进入。
备注:如果初学者不理解是如何通过下标访问的,这里说一下下标是从0开始,如果要访问list i中的第一个元素结果就是i[0],这部分知识可以看一下python基础。
2、如果你要访问List里面的元素,那么我们是否可以通过for循环语句来依次访问呢?这个在自动化中会经常用到。下面你可以通过这个思路自己去实战一下,看能否达到预期效果。下面看我的代码:
1 element= driver.find_element_by_id("com.taobao.taobao:id/rv_main_container")
2 elements = element.find_elements_by_class_name("android.widget.FrameLayout")
3 elements1 = elements[1].find_elements_by_class_name("android.widget.LinearLayout")
4for ele in elements1:
5 ele.click()
看上面的代码,我们通过循环去访问这个list里面的每一个元素,因为每次循环得到的都是其中一个元素,那么我们只需要在这个元素上加上你想要的操作即可,所以我们这里可以直接点击进去。
如果你动手做到这里会发现一个问题,你进入到第一个标签后没一会儿系统就会报错,为什么呢?你也可以试着去解决这个问题,后面我们会讲解这块儿知识。
2、 内嵌H5定位
2.1 hybrid定位思考
在web自动化中我们会遇见frame的问题,在遇见这些内嵌的标签后我们需要做的就是切换窗口,那么在app自动化测试也有类似的情况就是我们经常看见的内嵌html,在我们原生的app中增加一个由html做成的页面。大家可以思考一下这种情况怎么操作。
2.2 hybrid常见定位问题分析
首先我们看一下下面一张图片:
通过右边的结构图我们能够清晰的看见整个页面就是一个webview,无论从什么角度来定位我们都不能够很好的进行,如果这个时候我们需要操作页面的元素就需要通过切换contexts来完成。但是在讲这个知识点之前大家先按照网上的知识来试一下处理这个页面,看能否成功。下面先说大家会遇见的问题:
1、可能你看到有的文章显示我们不需要通过切换contexts就能够完成定位,这样的情况有,但是那种情况作者只在微博登录、qq登录等第三方登录时遇见过,如果不是这样的情况而像上面的情况就没办法通过类似的方法进行完成,所以我希望读者遇见这种情况时自己动手去操作,看什么方式更加适合自己的项目。
2、需要切换contexts那么就需要获取页面的所有contexts,此时你通过官网或者其他文章的知识通过下面的方法来获取,可能会报错,这种情况关系不大。
1 webview = self.driver.contexts
2 print webview
如果你通过上面的代码来调试但是却报错,但是其他资料却没问题时你也不要着急,这里你需要确定两件事情:
(1)、app打包的时候需要开启webview 的debug属性setWebContentDebuggingEnabled(true),这个直接让开发加上就好。一般情况是开启的,毕竟他们也要调试。
(2)、你用很多手机去调试,发现有一些可以有一些不可以,但是你用模拟器却都可以,根据官方给出的答案是这个时候你需要去将手机root,然后再试。目前作者遇见了这两种情况,第二种我也是调试了很久才找到原因。
2.3 hybrid定位讲解
这两个问题解决后那么定位webview就轻松搞定,直接看代码:
1 webview = driver.contexts
2 driver.switch_to.context(webview[1])
3 driver.find_element_by_link_text('PHP').click()
对于初学者对于上面的代码可能不是很理解,下面我们看一下日志:
大家这里不用管我执行代码和之前的区别(多了一个self),我们看下面控制台的输出,输出的是一个list,前面说过list和数组类似,在这个list里面有两个元素“NATIVE_APP”,“WEBVIEW_cn_com_open_mooc”,第一个元素是我们原生的app的contexts,后面的则是我们的webview的context,所以我们需要获取webview的context时只需要通过这个list的下表来进行访问。
我们获取到webview的context后只需要通过driver.switch_to.context()进行切换就好。当切换后我们就可以像定位web一样进行定位。
看下面一张图片我们通过浏览器将h5页面打开:
通过上面的图片我们就能够很轻松的像web一样进行定位,也就可以使用web的一些定位方式。看到这里是不是觉得解决了一个难题呢?动手去吧。
2.4 hybrid问题实战
通过前面的学习我相信你已经有了一些实战能力,这里给大家提一个问题,我们获取到的contexts每次一定是两个吗?如果不是两个那么我们上面的脚本是不是就没办法用了呢?可以思考一下这里怎么解决,在看我们下面的思路以及解决方案。
无论在什么页面我们去获取contexts时他无论有几个但是他的类型是不是肯定都是一个list呢?既然是list那么我们是否可以取到里面的每一个值,然后把每一个值进行判断,只要找出我们的webview就可以了呢?下面看代码:
1#获取当前页面所有的contexts
2 webview = driver.contexts
3#在获取到的contexts list里面去挨个循环
4for context in webview:
5 #判断循环中单个的context是否是webview,如果是就进行切换,并且跳出循环
6if'WEBVIEW'in context:
7 driver.switch_to.context(context)
8break
9 driver.find_element_by_link_text('PHP').click()
通过上面的代码我们是否完美的解决了内嵌H5的定位问题呢?动手吧
3、 滑动定位
3.1 滑动定位方式
在app自动化中我们经常会遇见一个问题,我们需要查找的元素不在当前可展示的屏幕,至于在什么地方我们不知道,如果这个时候我们一直使用在当前页面查找,那么系统就会报错,为了解决这个问题我们就需要使用滑动查找。
首先的思路是我们在需要查找对象的页面查找一下该元素,判断该元素是否在当前页面,如果该元素不在该页面那么我们就需要去互动屏幕,到我们的下一屏幕,然后再进行查找,依次类推到找到为止。
3.2 滑动定位思路分析
方式我们有了,那么我们就需要知道实现这个功能应该有哪些点。下面跟着我一起来分析一下:
1、需要查找的元素我们是不是需要知道是什么呢?这个需要先确定
2、我们需要找的页面是在我们的当前页面的上方还是下方还是左方还是右方,我们不能确定,那么我们是否需要确定我们需要滑动的方向?
3、元素和方向有了,但是你知道我们每次需要滑动屏幕的多少吗?那么我们是否需要先去获取屏幕的大小,然后针对不同的方向去计算一个滑动的值呢?
万事具备只欠东风,去按照这个思路动手练习一吧。
3.3 滑动定位实战
一、根据上面的思路我们能首先来确定我们需要查找的元素,看下面图片:
我们要找实战推荐后面的“换一换”按钮,然后进行点击。首先我们查看他的定位信息
最后我们查找元素的定位信息代码如下:
1 self.driver.find_element_by_id('cn.com.open.mooc:id/tv_replace').click()
对于有一定基础的人可能会觉得这个很low,但是有没有思考过一个问题,我们可以通过这个代码去执行,在没有这按钮的时候却会报错,也就没有办法执行下去了,那么需要怎么处理呢?所以这个时候我们需要有一些python的容错知识,即使我们的代码执行出错了,那么也要让他按照我们的意思执行下去。try.......except.......,这个就是我们python中的容错处理 ,下面我们看添加后的代码:
1try:
2 self.driver.find_element_by_id('cn.com.open.mooc:id/tv_replace').click()
3except Exception,e:
4 print e
try的意思就是告诉编译器试着去执行他下面这一段代码,如果报错了,那么你就把except里面的错误信息打印出来。
二、有了元素现在我们需要知道的是不是就是该怎么滑动界面了呢?首先我们看一下下面这张图片:
在我们使用app的过程中存在上面几种滑动情况,我们把整个界面看作为一个坐标系(x,y),如果我们需要往上滑动,那么我们是不是就是x轴不动,y轴从下往上动呢?往下就是x轴不动,y轴从上往下呢?同理左右滑动是不是就是应该y轴不动x轴左右滑动呢?可以好好去体会一下,脑海中有个画面。
在appium中滑动我们所需要使用的方法就是swipe函数,至于往哪个方向滑动就是看我们里面的x,y的值,如果我们需要下往上滑动那么我们就应该是:
1 self.driver.swipe(x1,y1,x1,y2,t)
上面的代码x轴的值不变,y轴的值进行了变化,所以是沿着上下进行滑动的,从y2滑动到了y1点。t代表的是多少时间完成这个动作,或者说这个时间持续多久。
备注:这里需要注意的是屏幕的x,y的值是从左上角开始取的,左上角为(0,0),右下角是最大。
三、上面滑动的方法看着是好用,但是我们不可能每次都去填写一个坐标,那样太low,所以我们需要获取屏幕大小,直接看代码:
1 x = self.driver.get_window_size()['width']
2 y = self.driver.get_window_size()['height']
上面的代码就是我们获取到的x,y轴。通过思路我们的代码都有了,下面我们要做的就是对原来的代码进行修改,进行一个封装。下面看代码,这个暂时看不懂没关系,到后面我们学了python'基础就能够看懂了。先思路,然后了解。
1#获取屏幕大小23def getSize(self):4 x = self.driver.get_window_size()['width']5 y = self.driver.get_window_size()['height']6return (x,y)789#向左滑动
10def swipeLeft(self,t):
11 l=self.getSize()
12 x1=int(l[0]*0.9)
13 y1=int(l[1]*0.5)
14 x2=int(l[0]*0.1)
15 self.driver.swipe(x1,y1,x2,y1,t)
16
17#向右滑动
18def swipeRight(self,t):
19 l=self.getSize()
20 x1=int(l[0]*0.25)
21 y1=int(l[1]*0.5)
22 x2=int(l[0]*0.75)
23 self.driver.swipe(x1,y1,x2,y1,t)
24
25#向上滑动
26def swipeUp(self,t):
27 l=self.getSize()
28 x1=int(l[0]*0.5)
29 y1=int(l[1]*0.8)
30 y2=int(l[1]*0.4)
31 self.driver.swipe(x1,y1,x1,y2,t)
32 time.sleep(5)
33
34#向下滑动
35def swipeDown(self,t):
36 l=self.getSize()
37 x1=int(l[0]*0.5)
38 y1=int(l[1]*0.25)
39 y2=int(l[1]*0.75)
40 self.driver.swipe(x1,y1,x1,y2,t)
41
42#查找元素,没找到滑动
43def findLocal(self):
44 x = 1
45while x==1:
46if self.fact() == 1:
47 self.swipeUp(2000)
48 time.sleep(3)
49 self.fact()
50else:
51 print "找到了"
52 x=2
53
54
55
56#递归
57def fact(self):
58 n =1
59try:
60 self.driver.find_element_by_id('cn.com.open.mooc:id/tv_replace').click()
61 except Exception,e:
62return n
通过查看上面代码的整个逻辑就是
1、首先去查找元素,如果找到了我就直接点击。
2、如果没有找到元素那么我就往上滑动(这里可以自己选择),滑动后再次进行查找,如果找到就点击,没有找到继续滑动。动手动手,这里知识点很重要!虽然后面会有一些替代方法,但是思路、算法很重要。
相关文章:

Appium+python自动化(十一)- 元素定位- 下
1、 List定位 List顾名思义就是一个列表,在python里面也有list这一个说法,如果你不是很理解什么是list,这里暂且理解为一个数组或者说一个集合。首先一个list是一个集合,那么他的个数也就成了不确定性,所以这里需要用复…...

免费批量PDF转Word工具
免费批量PDF转Word工具 工具简介 这是一款简单易用的批量PDF转Word工具,支持: 批量转换多个PDF文件保留原始格式和布局快速高效的转换速度完全免费使用 工具地址 下载链接 网盘下载地址:点击下载 提取码:8888 功能特点 ✅…...
OD 算法题 B卷【水果摊小买卖】
文章目录 水果摊小买卖 水果摊小买卖 小王手里有点闲钱,想做点水果买卖,给出两个数组m, n, m[i]表示第i个水果的成本价,n[i]表示第i个水果能卖出的价格;假如现在有本钱k,试问最后最多能赚多少钱࿱…...

Mac/iOS 如何解压 RAR 格式压缩包:常用工具与详细操作步骤
一、Mac 系统解压 RAR 文件之法 Mac 系统上解压 RAR 文件有多种方法,除了系统自带的一些简单功能外,还可以借助特定的软件来实现高效解压。以下将介绍几款常用工具的解压操作。 (一)解压专家解压步骤 解压专家 是一款在 Mac 和 …...
二进制安全-IDA Pro-API
idaapi 是 IDA Pro(Interactive Disassembler Professional) 反汇编工具的 Python API 接口,用于开发自动化脚本、插件和自定义分析工具。通过 idaapi,开发者可以访问 IDA Pro 的核心功能(如反汇编、符号分析、交叉引用…...

机器学习监督学习实战四:九种回归算法对波士顿房价数据进行回归预测和评估方法可视化
本项目代码在个人github链接:https://github.com/KLWU07/Machine-learning-Project-practice/tree/main 处理流程 1.导入波士顿房价数据集并进行预处理。2.使用 GradientBoostingRegressor 模型进行回归分析。3.通过交叉验证评估模型的性能,计算 MAE、…...
1. Web网络基础 - IP地址核心知识解析
深入解析IP地址与ipconfig命令:网络工程师的必备技能 在网络世界中,IP地址是设备通信的基石。本文将全面解析IP地址的核心概念,并通过ipconfig命令实战演示如何获取关键网络配置信息。 一、IP地址核心知识解析 1. IP地址的本质 定义&#x…...

微软重磅发布Magentic UI,交互式AI Agent助手实测!
微软重磅发布Magentic UI,交互式AI Agent助手实测! 何为Magentic UI? Magentic UI 是微软于5.19重磅发布的开源Agent助手,并于24日刚更新了第二个版本0.04版 从官方的介绍来看,目标是打造一款 以人为中心 的智能助手,其底层由多个不同的智能体系统驱动,能够实现网页浏览…...
c# 完成恩尼格玛加密扩展
c# 完成恩尼格玛加密扩展 恩尼格玛扩展为可见字符恩尼格玛的设备原始字符顺序转子的设置反射器的设置连接板的设置 初始数据的设置第一版 C# 代码第二版 C# 代码 总结 恩尼格玛 在之前,我们使用 python 实现了一版恩尼格玛的加密算法,但是这一版&#x…...
华为 “一底双长焦” 专利公布,引领移动影像新变革
6 月 6 日,国家知识产权局公布的一项专利发明申请吸引了众多目光,该专利发明人为华为技术有限公司,名为 “光学镜头、摄像头模组及电子设备” 。从展示的技术图来看,这一光学镜头呈现出独特的 “一底双镜头结构”,其中…...

老年生活照护实训室建设规划:照护质量评估与持续改进实训体系
随着人口老龄化程度的不断加深,老年生活照护需求日益增长,对专业照护人才的培养提出了更高要求。老年生活照护实训室建设方案作为培养高素质照护人才的重要载体,其核心在于构建科学完善的照护质量评估与持续改进实训体系。通过该体系的建设&a…...

【python深度学习】Day 48 PyTorch基本数据类型与操作
知识点: 随机张量的生成:torch.randn函数卷积和池化的计算公式(可以不掌握,模型会自动计算的)pytorch的广播机制:加法和乘法的广播机制 ps:numpy运算也有类似的广播机制,基本一致 作…...
Go深入学习延迟语句
1 延迟语句是什么 编程的时候,经常会需要申请一些资源,比如数据库连接、文件、锁等,这些资源需要再使用后释放掉,否则会造成内存泄露。但是编程人员经常容易忘记释放这些资源,从而造成一些事故。 Go 语言直接在语言层…...

【大模型】【推荐系统】LLM在推荐系统中的应用价值
文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点B.4 两大推荐方法 C 模型结构C.1 知识蒸馏(训练过程)C.2 轻量推理(部署过程) D 实验设计E 个人总结 A 论文出处 论文题目:SLMRec:Distilling…...

uni-app学习笔记二十九--数据缓存
uni.setStorageSync(KEY,DATA) 将 data 存储在本地缓存中指定的 key 中,如果有多个key相同,下面的会覆盖掉原上面的该 key 对应的内容,这是一个同步接口。数据可以是字符串,可以是数组。 <script setup>uni.setStorageSyn…...
csharp基础....
int[][] jaggedArray new int[3][]; jaggedArray[0] new int[] { 1, 2 }; jaggedArray[1] new int[] { 3, 4, 5 }; jaggedArray[2] new int[] { 6, 7, 8, 9 }; 嵌套 反转和排序 List<int> list new List<int> { 1, 2, 3, 4, 5 }; list.Reverse(); Cons…...
【C/C++】EBO空基类优化介绍
空对象优化(Empty Base Optimization,简称 EBO)是 C 编译器的一种 优化技术,用于消除空类作为基类时占用的内存空间,从而避免浪费空间、提升结构体或类的存储效率。 1 什么是“空对象”? 一个**空类&#…...

工作邮箱收到钓鱼邮件,点了链接进去无法访问,会有什么问题吗?
没事的,很可能是被安全网关拦截了。最近做勒索实验,有感而发,不要乱点击邮箱中的附件。 最初我们采用钓鱼邮件投递恶意载荷,发现邮件网关把我们的 exe/bat 程序直接拦截了,换成压缩包也一样拦截了,载荷始终…...

基于安卓的线上考试APP源码数据库文档
摘 要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存…...

【数据结构】顺序表和链表详解(下)
前言:上期我们从顺序表开始讲到了单链表的概念,分类,和实现,而这期我们来将相较于单链表没那么常用的双向链表。 文章目录 一、双向链表二,双向链表的实现一,增1,头插2,尾插3&#x…...

【系统架构设计师】绪论-系统架构概述
目录 绪论 系统架构概述 单选题 绪论 系统架构概述 单选题 1、软件方法学是以软件开发方法为研究对象的学科。其中,()是先对最高居次中的问题进行定义、设计、编程和测试,而将其中未解决的问题作为一个子任务放到下一层次中去…...

SQL-事务(2025.6.6-2025.6.7学习篇)
1、简介 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。 默认MySQL的事务是自动提交的,也就是说࿰…...
OpenCV 图像通道的分离与合并
一、知识点 1、一张彩色图像可以由R、G、B三个通道的灰度图合并而成。 2、void split(InputArray m, OutputArrayOfArrays mv); (1)、将多通道阵列划分为几个单通道阵列。 (2)、参数说明: m: 要分离的多通道阵列。 mv: 输出的vector容器,每个元素都…...

Virtex II 系列FPGA的配置原理
对FPGA 芯片的配置,本质上是将根据设计生成的包含配置命令和配置数据的比特流文件写入到配置存储器中。 1 配置模式 Virtex II 系列FPGA 一共有五种配置模式,配置模式的选择是根据管脚M[2:0]来决定。 (1)串行配置模式 串行配置模…...

蓝桥杯 国赛2024python(b组)题目(1-3)
第一题 试卷答题页 - 蓝桥云课 问题描述 在今年蓝桥杯的决赛中,一共有 1010 道题目,每道题目的分数依次为 55 分,55 分,1010 分,1010 分,1515 分,1515 分,2020 分,2020 分…...
低代码平台前端页面表格字段绑定与后端数据传输交互主要有哪些方式?华为云Astro在这方面有哪些方式?
目录 🔧 一、低代码平台中常见的数据绑定与交互方式 1. 接口绑定(API 调用) 2. 数据源绑定(DataSource) 3. 变量中转(临时变量 / 页面状态) 4. 数据模型绑定(模型驱动) 🌐 二、华为云 Astro 轻应用的实现方式 ✅ 1. 数据源绑定(API服务+API网关) ✅ 2. 变…...
stm32——UART和USART
串口通信协议UART和USART 1. UART与USART协议详解 特性UART (Universal Asynchronous Receiver/Transmitter)USART (Universal Synchronous Asynchronous Receiver/Transmitter)全称通用异步收发器通用同步/异步收发器同步/异步异步:不共享时钟,数据通过…...

算法题(165):汉诺塔问题
审题: 本题需要我们找到最优的汉诺塔搬法然后将移动路径输出 思路: 方法一:递归 我们先分析题目 n为2的情况,我们先将第一个盘子移动到三号柱子上,然后再将二号盘子移动到二号柱子上 n为3的情况,我们先将前…...

玄机——某次行业攻防应急响应(带镜像)
今天给大家带来一次攻防实战演练复现的过程。 文章目录 简介靶机简介1.根据流量包分析首个进行扫描攻击的IP是2.根据流量包分析第二个扫描攻击的IP和漏扫工具,以flag{x.x.x.x&工具名}3.提交频繁爆破密钥的IP及爆破次数,以flag{ip&次数}提交4. 提…...

低代码逻辑引擎配置化实战:三步穿透审批记录查询
在堆积如山的报销单中埋头寻找某笔特殊费用的审批轨迹在跨部门协作时被追问"这个合同到底卡在哪个环节" 在快节奏的办公自动化场景中,这些场景是很常见的,传统OA系统中分散的审批记录查询方式往往太繁琐。 为破解这一痛点,在JVS低…...