Appium 🔥Appium+python 自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)

北京-宏哥 · 2025年01月15日 · 245 次阅读

1.简介

  你有道灵光从天灵盖喷出来你知道吗,年纪轻轻就有一身横练的筋骨,简直百年一见的练武奇才啊,如果有一天让你打通任督二脉,那还不飞龙上天啊。正所谓我不入地狱谁入地狱,警恶惩奸维护世界和平这个任务就交个你了,好吗。这本如来神掌秘籍是无价之宝,我看与你有缘,收你十块钱传授给你吧。想必这段经典台词给为都可以的耳熟能详吧,宏哥,没这么牛叉呼啦带闪电,就是希望对你有帮助就可以了。

  上一篇宏哥给小伙伴们介绍完定位工具这两个异性兄弟,这篇就给小伙伴们介绍一下定位方法。早就有小伙伴问,这个这个怎么定位,那个那个怎么定位?那么宏哥今天就告诉你,怎么怎么定位。其实定位前边也有所涉及,只不过是一笔带过的。这篇宏哥就给小伙伴们详细的介绍一下。

2.常用定位方法讲解

  对象定位是自动化测试中很关键的一步,也可以说是最关键的一步,毕竟你对象都没定位那么你想操作也不行。所以本章节的知识宏哥希望小伙伴们多动手去操作和实战,不要仅仅只是书本上的知识,毕竟这个我只能够举例说明。下面我们来看我们常用的一些定位方式。

2.1 ID 定位

  无论是在 web 自动化还是 app 自动化中 id 都是唯一的,可能有的小伙伴看到这里会有疑问,因为有的资料说是通过 name 定位是唯一的,为什么你这里是 id 呢,其实这个在之前是不冲突的,但是如果你用的是 appium 较新版本是不行的,在新版本中 name 定位被去掉了,所以在以后的定位中不会有 name 定位了,通常情况下我们也更喜欢用 id 进行定位。这里可能刚学的小伙伴会有疑问,有的时候你的应用为什么没有 id,或者说在这个手机上有但是另外的手机上没有。1、开发没有添加。2、android版本是 4.4 以下的。

我们直接看下面这张图片吧

上面图片中左边部分用红色圈出来的对象的 id 我们在右边的属性中可以看到,它的 id 宏哥同样是用红色圈出,如果我们需要对 “请输入淘宝账户” 这个输入框进行输入信息,我们只需操作右边的 id 就行,下面我们直接看代码。

代码语言:javascript

复制

1 driver.find_element_by_id("com.taobao.taobao:id/aliuser_login_account_et").send_keys("北京宏哥")

通过上面的代码我们能够直接在账户信息输入框中输入账户信息北京宏哥。可能对于无基础的人来说这里会又点儿迷糊,这个 driver 是哪里来的,driver 在我们配置启动的时就已经初始化,我们只需要调用他的方法 find_element_by_id。如果你的 ide 有自动补全功能,那么你在输入后面的方法时会发现一个问题,为什么还有一个 find_elements_by_id 呢?这个在后面宏哥会讲解,有兴趣的小伙伴可以思考一下。

2.2 className 定位

在实际工作中 className 定位用得相对而言会比较少。当你经常去看 class 时你会发现很多的 className 是一样的,你没有办法对其进行唯一定位,下面我们看下面两张图片

我们可以仔细看一下这两张图片中淘宝账号、密码两个输入框中的 className 都是一样的,如果在这种情况下你使用下边这种方式去定位,你会发现你永远定位不了密码栏,这是为什么呢?因为在设计的时候如果你查找的元素在页面有多个,系统会自动给你选择第一个,所以你永远操作不了后面的,那么在实际工作或者实战的时候如果遇到此类问题如何解决这种问题呢?宏哥后面会讲解。

代码语言:javascript

复制

driver.find_element_by_class_name("android.widget.EditText").send_keys("北京宏哥")

2.3 xpath 定位

xpath 定位在 web 自动化中是最常见的,而且也是最有效的,使用 xpath 定位避免了找不到元素导致报错的问题,但是在 app 中使用 xpath 定位是一件很 low 的事情。为什么这么说呢?因为在宏哥过来人的经历中只要遇见使用 xpath 定位元素他的反应就会比较慢,自动化的目的是为了提高效率,但是使用 xpath 后会降低效率,所以这里说很 low。但很多时候我们不得不去了解,下面我们大概讲解一下。首先我们要熟悉一下 web 的 xpath 定位。

1)讲 web 的 xpath 之前大家先装一下 fireFox 浏览器,再在浏览器中安装 fireBug 以及 FirePath 两个插件。如下图:

在自动化或者学习 xpath 时这两个插件是必不可少的,这里我们直接讲 xpath,我们来看下面一张图片理解一下

用红色圈出有虚线的输入框我们看一下 xFirePath 给我们的定位,在定位的 xpath 中显示的是 “.//[@id='kw']”,这个是什么意思呢?我们来一步一步讲解。1、// 选取文档中的所有元素 。2、@id='kw'] 匹配属性为 id 且值为 kw 的节点。这里有的小伙伴可能不是很理解,说这里直接使用 id 进行定位就行。其实也是,但是当没有这个属性的时候呢?我们看下面这张图片

  name 定位无效的情况下,当你看到这张图片的时候如果你不用 xpath 怎么定位呢?有一些抓狂的感觉吧。小伙伴可以尝试着自己使用 xpath 进行定位,可能有一些人发现 xpath 中定位不是很明白了,为什么呢?.//*[@id='u1']/a[4] 在这个 xpath 中我们没有像之前那样思路清晰了他多了一些层级关系,这个后面我们会仔细讲。这个 xpath 中首先第一步 1、@id='u1'和之前的一样匹配属性为 id 值为 ul 的节点,然后再在他的下面进行定位第二步 2、/a[4] 意思就是从根节点下选取第四个 a 元素。这样一步一步解析是否更加容易理解了呢?下面我们看一下在 xpath 定位中经常用到的一些语法,下来大家多多练习。

这个是我们经常用到的,而且是最基础的知识,只有这些没有办法完成很多古怪的需求,那么就有更难的,下面我们看下面的列表

上面这些知识都是在http://www.w3school.com.cn/xpath/xpath_examples.asp 里面,大家可以多看看,多练习。

下面我们直接看在 app 中 xpath 的使用

在上面两张图片中我们能够清除的看见他们的 id、className 都是一样的,这样的情况下不用层级定位方式我们只能够采用 xpath 来进行定位,首先根据前面 web 的学习大家可以思考一下该怎么定位。我们直接看代码

代码语言:javascript

复制

1 driver.find_element_by_xpath("//android.widget.TextView[@text='聚划算']").click()

在 xpath 里面我们的语法是这样 “//android.widget.TextView[@text='JavaScript']”,这个和我们之前 web 的 xpath 一样,意思是查找所有节点中节点为 android.widget.TextView(这里使用的是 className,也可以使用 id,系统会依次去找)并且他的 text 属性值为 JavaScript,这样是否更容易理解呢?下来多练习。这样的定位方式不推荐,效率很慢。

3.层级定位

3.1 什么是层级定位

  在前面的章节中我们已经提到了层级定位,只是不知道具体怎么操作而已。在很多的自动化中如果只是靠简单的定位是没有办法完成自动化的,就像刚 xpath 定位一样,有的元素的 id、name、className 都是一样的,xpath 定位效率低下,这个时候我们大多数都会采用层级定位。

3.2 项目中层级定位如何运用

下面我们举一个简单的例子来理解层级定位。

从上面的图片我们可以看出 id 为 com.taobao.taobao:id/rv_main_container 的节点下面包含了很多的 android.widget.FrameLayout

从下面的图片我们可以看出 id 为 android.widget.FrameLayout 的节点下面包含了很多的 android.widget.LinearLayout

从这张图片我们不难看出,如果我们要定位这个元素我们是没办法去定位的,这种情况我们大多数使用的是层级定位以及 xpath,这里我们来看如何使用层级定位。

首先我们可以看出三幅图的结构上的区别,第三幅图的元素它是在第二幅图里面的,第二幅图元素它是在第一幅图里面的,这里我们称第一幅图 id(com.taobao.taobao:id/rv_main_container)为 android.widget.FrameLayout 的节点为第二幅图元素的父节点,第二幅图 id(android.widget.FrameLayout)为 android.widget.FrameLayout 的节点为第三幅图元素的父节点,第一幅图 id(com.taobao.taobao:id/rv_main_container)为 android.widget.LinearLayout 的节点为第三幅图元素的祖父节点;我们只需要先通过 id 定位到祖父节点,然后再从祖父节点往下面依次进行定位就好。现在你可以练习一下,看和我的结果一样吗?看代码:

代码语言:javascript

复制

1 element= driver.find_element_by_id("com.taobao.taobao:id/rv_main_container")
2 element1 = element.driver.find_elements_by_class_name("android.widget.FrameLayout")
3 element2 = element1[1].find_element_by_class_name("android.widget.LinearLayout")
4 element2.click()

按照思维我们的代码会是上面的结果,但是你去运行会发现不报错,可也不会点击,这个是为什么呢?我们看下面的图片 (宏哥亲测,它会点击第一个天猫,可能是默认点击第一个吧)

在祖父节点下的所有子节点他的 className 都是 “android.widget.FrameLayout”,在父节点下的所有子节点他的 className 都是 “android.widget.LinearLayout”,这种情况下他怎么去点击操作呢?所以在这种情况下会引发一个新的定位问题,就是宏哥在接下来要讲的 List 定位。

2.3 参考代码

代码语言:javascript

复制

1 # coding=utf-8
 2 # 1.先设置编码utf-8可支持中英文如上一般放在第一行
 3 
 4 # 2.注释包括记录创建时间创建人项目名称
 5 '''
 6 Created on 2019-7-01
 7 @author: 北京-宏哥   QQ交流群:707699217
 8 Project:学习和使用定位元素
 9 '''
10 # 3.导入模块
11 from appium import webdriver
12 import time
13 desired_caps = {}
14 desired_caps['platformName'] = 'Android'   #android的apk还是IOS的ipa
15 desired_caps['platformVersion'] = '8.0'  #android系统的版本号
16 desired_caps['deviceName'] = '127.0.0.1:62001'    #手机设备名称通过adb devices  查看
17 desired_caps['appPackage'] = 'com.taobao.taobao'  #apk的包名
18 desired_caps['appActivity'] = 'com.taobao.tao.welcome.Welcome'  #apk的launcherActivity
19 #desired_caps['unicodeKeyboard'] = True   #使用unicodeKeyboard的编码方式来发送字符串
20 #desired_caps['resetKeyboard'] = True   #将键盘给隐藏起来
21 driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) #启动服务器地址后面跟的是手机信息
22 # 休眠五秒等待页面加载完成
23 time.sleep(5)
24 
25 element= driver.find_element_by_id("com.taobao.taobao:id/rv_main_container")
26 element1 = element.find_elements_by_class_name("android.widget.FrameLayout")
27 element2 = element1[1].find_element_by_class_name("android.widget.LinearLayout")
28 element2.click()
29 
30 # driver.quit()

4.小结

1、前边介绍了一下火狐浏览器,这里宏哥再给小伙伴们总结一下谷歌浏览器如何用 xpath 定位,当然了,大神和大佬可以忽略不看,因为可以直接手写 xpath 定位。其实看看他们的语法也很简单,自己后期也可以尝试手写,看看和工具的有哪些区别,这样可以有助于自己的提高和提升。

2、谷歌浏览器 xpath 插件下载地址https://image.baidu.com/search/down?url=https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl

3、安装方法,用谷歌浏览器直接访问上边的地址,添加以后即可。

4、看一下如何使用和其效果

(1)谷歌浏览器,F12,不可以的话,可以打开 “开发者工具

(2)点击左边的 “箭头”,查找到要定位的元素

(3)选中控制台的元素,鼠标右键,在 copy 里,选中 “Copy XPath”

(4)copy 的内容:(//*[@id="kw"])

5、注意 find_element 和 find_elements 的区别!!!

好了,时间不多了,天也很晚了,大致就这些吧,今天就给小伙伴们就说到这里吧。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册