Appium(十):元素定位(加强版)
1. 元素定位
写完上一篇元素定位的博客,发现实用性基本为零。这几天真的烦死我了,一直在找资料,还去看了一遍appium官网文档。最后结合着selenium的定位方法,测试出几种可行的元素定位方法。
1.1 层级定位
什么是层级定位呢?
在很多的自动化中如果只是靠简单的定位是没有办法完成自动化的。有的元素的id、name、className都是一样的,xpath定位效率低下,并且在appium中,可以使用的属性非常少,这个时候我们就需要使用层级定位了。


我们可以看到,QQ天气和微视的class都是相同的, 接下来我们用代码试一试。
# coding:utf-
from appium import webdriver
from time import sleep # 初始化
desired_caps = {}
# 使用哪种移动平台
desired_caps['platformName'] = 'Android'
# Android版本
desired_caps['platformVersion'] = '5.1.1'
#使用adb devices -l 查询,当有多台设备时,需要声明
desired_caps['deviceName'] = '127.0.0.1:62001'
#包名
desired_caps['appPackage'] = 'com.tencent.mobileqq'
#界面名
desired_caps['appActivity'] = '.activity.SplashActivity'
#不清除数据
desired_caps['noReset'] = 'True'
# 启动服务
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) driver.find_element_by_id('com.tencent.mobileqq:id/recent_chat_list')
driver.find_element_by_class_name('android.widget.LinearLayout').click() #退出driver
driver.quit()
运行后,我们会发现代码执行了,也没有报错,但是也不会点击,这是为什么呢。这就牵扯到另外一个定位问题,就是下面要说的List定位。
1.2 List定位
list顾名思义就是一个列表。当我们想要获取一个元素,但是却发现符合条件的元素有很多个的时候,我们就可以选择List定位了。因为元素的个数的不确定性,所以我们的方法也需要变成复数,所以这里需要用复数,所以在我们定位时我们不能够接着用find_element_by_class_name等等定位方式了,我们需要用他的复数形式find_elements_by_class_name,所有的定位方式都一样需要采用复数加s。
driver.find_element_by_id('com.tencent.mobileqq:id/recent_chat_list')
driver.find_elements_by_class_name('android.widget.LinearLayout')
上面的代码最后选择的是com.tencent.mobileqq:id/recent_chat_list父节点下所有android.widget.LinearLayout子节点,现在我们如何去操作这些子节点呢,有两种方法:
1、List是一个集合,这里定位的所有子节点最后就成了个list,如果我们要访问这个list里面的某一个元素我们可以像访问数组中的数据一样通过下标访问。最后的代码就是下面这个样子:
driver.find_element_by_id('com.tencent.mobileqq:id/recent_chat_list')
elements = driver.find_elements_by_class_name('android.widget.LinearLayout')
elements[0].click()
#让我们更好的观看效果
sleep(5)
2、如果你要访问List里面的元素,那么我们是否可以通过for循环语句来依次访问呢?这个在自动化中会经常用到。下面你可以通过这个思路自己去实战一下,看能否达到预期效果。下面看我的代码:
for element in elements:
sleep(2)
element.click()
看上面的代码,我们通过循环去访问这个list里面的每一个元素,因为每次循环得到的都是其中一个元素,那么我们只需要在这个元素上加上你想要的操作即可,所以我们这里可以直接点击进去。
但是我们会发现,在进入到第一个标签后,系统就会报错,为什么呢?因为界面跳转到微视里面了,而里面没有android.widget.LinearLayout元素,所以就会因为找不到元素而报错。
所以这种方法的使用有限制,只能在那种不需要界面跳转的情况下使用。
1.3 xpath定位(补充)
xpath定位可以分为两种,绝对定位和相对定位。
但是我们会发现,绝对定位的路径非常的长,后期代码也比较麻烦,开发中几乎不可能使用。(老大看到了就叼你)
相对路径就是非常好用的一种了,不断简短,后期维护代码也方便。
以下就是相对路径的使用了:
我使用的是taptap软件来进行测试,大家可以换成其他软件。
(1) 如果当前class内存在唯一text可以定位元素,直接用当前class+text,例如:
# coding:utf-8
from appium import webdriver
from time import sleep
from appium.webdriver.common.touch_action import TouchAction # 初始化
desired_caps = {}
# 使用哪种移动平台
desired_caps['platformName'] = 'Android'
# Android版本
desired_caps['platformVersion'] = '5.1.1'
#使用adb devices -l 查询,当有多台设备时,需要声明
desired_caps['deviceName'] = '127.0.0.1:62001'
#包名
desired_caps['appPackage'] = 'com.taptap'
#界面名
desired_caps['appActivity'] = 'com.play.taptap.ui.MainAct'
#不清除数据
desired_caps['noReset'] = 'True'
#启动服务
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) element = driver.find_element_by_xpath('//android.widget.TextView[@text="排行"]')
TouchAction(driver).tap(element).perform() sleep(5) #退出driver
driver.quit()
(2) 如果当前class内,resource-id、text两者能唯一定位元素,直接用当前class+两者并列,例如:
element1 = driver.find_element_by_xpath('//android.widget.TextView[@text="我的游戏"]')
TouchAction(driver).tap(element1).perform()
sleep(2)
element2 = driver.find_element_by_xpath('//android.widget.TextView[@resource-id="com.taptap:id/app_title" and @text="第五人格T"]')
TouchAction(driver).tap(element2).perform()
sleep(5)
(3) 如果当前class内,text中的文本内容不是完全符合,但能匹配部分内容,可用当前class+模糊定位contains,例如:
element = driver.find_element_by_xpath('//android.widget.TextView[contains(@text,"我的")]')
TouchAction(driver).tap(element).perform()
sleep(2)
还有很多类似的定位方法,可以查看我找到的一个大佬写的博客:https://blog.csdn.net/Dome_/article/details/80638245
总体上就这样了,以后如果找到更好的方法,就再更新一章。
Appium(十):元素定位(加强版)的更多相关文章
- 初探appium之元素定位(1)
无论是selenium还是appium,元素定位都是我们开始实现自动化面临的第一个问题.selenium还好,我们可以在浏览器的调试页面进行元素定位还是蛮方便的.那么appium怎么做呢? 我看到很多 ...
- Appium Android 元素定位方法 原生+H5
APPIUM Android 定位方式 1.定位元素应用元素 1.1通过id定位元素 Android里面定位的id一般为resrouce-id: 代码可以这样写: WebElement eleme ...
- Appium Desktop 元素定位和脚本录制功能
Appium Desktop除了可以做Server之外还可以进行元素定位和脚本录制功能,点击放大镜按钮,进入页面设置.开始配置Desired Capabilities. 配置Desired Capab ...
- Appium自动化(10) - appium高级元素定位方式之 UI Automator API 的详解
如果你还想从头学起Appium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1693896.html 前言 前面介绍过根据id,clas ...
- Appium + Python -------------元素定位
说在前面 1.https://github.com/appium/python-client/tree/master/test 里面有一些test ,可以看看,研究研究 2.学会使用 uiautom ...
- appium xpath元素定位
1.id定位 写法:driver.find_element_by_id("这里是resource-id") 2.name定位 name定位就是通过UI Automator工具查看的 ...
- Appium+Python 自动化-appium常用元素定位方法
https://www.cnblogs.com/rabbit-testing/p/8042733.html 大牛 https://blog.csdn.net/kaka1121/article/deta ...
- 【APP自动化】Appium Android 元素定位方法 原生+H5
参考资料: http://blog.csdn.net/vivian_ljx/article/details/54410024
- Appium学习笔记4_元素定位方法
Appium之元素定位,如果对Android上如何使用工具获取页面元素有问题的,请转战到这:http://www.cnblogs.com/taoSir/p/4816382.html. 下面主要是针对自 ...
随机推荐
- Java方法的可变参数
class Demo { public static int sum(int ... data) { //此处可以传递一个数组,也可以是多个参数 int sum = 0; for (int i : d ...
- 个人收藏--未整理—C# 上传下载文件
Winform下载文件 /// <summary> /// 下载文件 /// </summary> /// <param name="URL"> ...
- 对Java单例模式 volatile关键字作用的理解
单例模式是程序设计中经常用到的,简单便捷的设计模式,也是很多程序猿对设计模式入门的第一节课.其中最经典的一种写法是: class Singleton { private volatile static ...
- SpringBoot日志处理之Logback
日志处理是一个正式项目必备的功能,日志要能够根据时间.类型等要素,根据指定格式来保存指定的日志,方便我们观察程序运行情况.定位程序bug. SpringBoot中推荐使用Logback日志框架. 本节 ...
- ThinkPHP5——模型(model)的使用
在使用ThinkPHP5的过程中,我经常使用db进行数据库操作的,后来接触到了模型(model),刚使用时感觉跟db没啥区别,后来查官网知道模型基类中还提供了较多的其他的方法可以方便使用例如获取器.修 ...
- 鲲鹏云实验-Python+Jupyter机器学习基础环境
[摘要] 介绍Ubuntu 18.04环境下Python3常用科学计算和数据分析包(numpy, scipy, matplotlib, sklearn, pandas)的安装,以及Jupyter No ...
- 用生动的案例一步步带你学会python多线程模块
鱼和熊掌不可兼得 鱼,我所欲也,熊掌,亦我所欲也,二者不可得兼,舍鱼而取熊掌者也. 从6月开始写公众号,连着四个月一直尽量保证一周五更,结果整天熬夜搞的身体素质骤降.十一休假决定暂时将公众号放放,好好 ...
- obs命令行工具obsutil的使用测试
test1 批量复制,目标文件夹ggggg-zyx0809/data/tmp/a0文件夹已存在,不使用flat命令,目标路径包含a0文件夹 操作 从ggggg-zyx0809/data/g_cageg ...
- 洛谷 题解 P1684 考验
本蒟蒻又来发题解啦! 这个题的正解应该是贪心 直接找题目的关键: 韵脚只可能是 "AABB", "ABAB", "ABBA" 和" ...
- [译]C#8.0中一个使接口更加灵活的新特性-默认接口实现
9月份的时候,微软宣布正式发布C#8.0,作为.NET Core 3.0发行版的一部分.C#8.0的新特性之一就是默认接口实现.在本文中,我们将一起来聊聊默认接口实现. 众所周知,对现有应用程序的接口 ...