关于xpath定位问题及常用方法

关于xpath定位问题及常用方法

关于类似的帖子好像很多,但是没有找到具体能帮我解决问题的办法。还是自己深究了好久才基本知道app上面的xpath定位和web上的不同点:

先放一个图:

 A,先说说不用xpath的场景,一般是用于存在id或者name。可能没有看到name,别慌,继续看。

     1,app上面定位用的最多的当然是id,也就是上面看到的resource-id,后面就是其所对应的值。所以在定位的时候可以是driver.find_element_by_id('com.wlqq:id/title_left_btn').当然注意一点就是,如果id不是唯一的,那么此办法行不通,可考虑增加下标值[x]来区分(如何加后面的xpath会提到),但是如果很多的话,可能自己都会数错。。。。。顺便说一下,我也在用robotframework+appiumLibrary,这里的使用方式就是 click element | id=com.wlqq:id/title_left_btn。id应该就这样用了吧。

     2,当然第二种常用的办法就是name,而这里的name和web也就是html里面的name不太一样,web里面的name就是标签对应的属性name的值,而这里其实是上面图里的text的值。当然也就是在使用的时候需要用by_name('账单'),或者是 name=账单。

B,以上两点是常用的,但是也是最简单的定位方式,下面就回到正题说一声xpath了。用到xpath的场景主要为没有id或者没有name,或者name是一个不可控的值(或者叫会发生变化的值)。另外不知道xpath是什么的,就自行百度了吧。其实简单点就是按路径定位包括一级或者多级。顺便说一下,其实路径分两种,一种是绝对路径(以第一个标签为参照物),另一种是相对路径(已其他已知的标签为参照物)。

  1,先说说有id或者name的场景使用xpath的情况。(有id或者name为什么不直接用?当然可以像上面那样直接用。当然也可以装逼用xpath。不过当id不唯一也就是多个的时候,这种能解决问题。)

  就比如上面的"账单"和"我要"的id都是com.wlqq:id/title_left_btn,当前页面只有只有这两个id是这个,那么你在用id定位"账单"的时候,就需要写xpath=(//android.widget.TextView[@resource-id="com.wlqq:id/title_left_btn"])[1]  定位"我要"就是xpath=(//android.widget.TextView[@resource-id="com.wlqq:id/title_left_btn"])[2],

     此处注意三点:

         a,下标是从1开始,而不是0;

         b,如果有下标,需要用括号把前面的部分括起来,并且前面需要加xpath=,可能有些人习惯了前面都加xpath=,但是像我这种只习惯写//开头,不写xpath=的就被坑惨了。。。反正不容易发现是因为没有写xpath=,也可能是我个人比较坑吧。

         c,就是和web不一样的就是标签的取值,在这里取的是class的值=android.widget.TextView而不是看到的标签TextView,具体原因没有深究。反正记住用class代替标签就对了。

  当然是用name的情况也是一样的。无非就是//android.widget.TextView[@text="我要"],另外注意下,这里使用的@text,而用@name或报错,原因也没有深究过,本人太low。。和上面的resource-id一样,用xpath的时候就用本身显示的就好了。也好记。

      另外,上面的只是为了说明1个层级的时候xpath的用法,xpath的书写规则基本是越少越好。所以层级也是越少越好。有1层可以唯一定位就不要2层。 可能有点废话了。

     2,卧槽,终于可以进入重点了。就是没有id或者name的场景。   先来一张图:

 

 

      1 ,现在有一个场景就是我需要点击上面那个小人图标,但是他没有id和text属性。能想到的办法就是下面要讲的xpath了。

          a,用绝对路径的写法就是:如果图上的第一个是最顶上的话,就是

 

        这样的,也就是需要7个层级,一次写下来就是:(数字写得有点丑。)

      //android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.RelativeLayout/android.widget.LinearLayout[2]/android.widget.ImageButton

      这种写法注意一下几点:

    1), [2]注意是2而不是3,因为与标签的值有关。只有2个LinearLayout。

           2), 路径长度偏长,而且因为只有class的值,对于一些页面控件较多的,可能不止一个,也就是可能这种写法也都不是唯一。

           3),绝对路径基本很少使用,如果人品太差,遇到页面全是没有id或者name的,那就没办法了。或者考虑一些坐标。(关于坐标存在的换手机存在适配分辨率的问题,在下也有研究对策。不知道你是否有兴趣看看?)

         b,现在就是本文的重点了:使用相对路径的办法来定位。

    1),大家可以看到,这个图里面有一个唯一的中文词汇--"钱包"。我们可以通过这个钱包来定位我们的小人图片。先分析下位置关系。找找关系也就是如图所示,小人图标3是钱包1的弟弟2LinearLayout标签的儿子ImageButton。儿子好理解,xpath的层级关系也就是父子关系用/表示。//android.widget.LinearLayout/android.widget.ImageButton这样就能表示弟弟的儿子了。但是现在问题是怎么表示钱包的弟弟?

    xpath里面有一个轴,简单点可以理解为一个函数吧。我这样认为的。preceding-sibling:: 可以找到节点前面也就是哥哥节点,following-sibling::可以找到节点后面也就是弟弟节点,关于轴的更多用法啊,可以自行百度xpath的语法。这里还有一个用的多的就是parent:: ,可以找到节点的父亲节点。但是父亲节点可以用..表示。下面就来具体说一下怎么用:

    基本知识已经介绍到此了。那么这里的定位方法就是上图中的3个层级://android.widget.TextView[@text="钱包"]/following-sibling::android.widget.LinearLayout/android.widget.ImageButton。 第一级就同前面说的唯一的找到钱包这个位置,后面的一级就是钱包的弟弟,也就是following-sibling::android.widget.LinearLayout。当然注意因为是紧挨着的,所以弟弟没有下班,可想而知如果是第几个弟弟,就加个下标吧。哥哥也是同理。

          2),前面用到了兄弟的关系,下面说一下儿子与父亲的关系。父子关系还是用图来说明。我们的钱包1的父亲2有一个儿子3的儿子4就是我们的小人图标。这就是找关系。关系找到了,那我们就可以用这个关系来写xpath了。也就是钱包(//android.widget.TextView[@text="钱包"])的父亲(/parent::android.widget.RelativeLayout )的第二个class=android.widget.LinearLayout的儿子(/android.widget.LinearLayout[2])的儿子(小人/android.widget.ImageButton),好,我们连起来就是://android.widget.TextView[@text="钱包"]/parent::android.widget.RelativeLayout/android.widget.LinearLayout[2]/android.widget.ImageButton。顺便说一下父亲这个位置可以用..来代替,相比很多人都知道..在路径里面指的就是上级。所以可以用//android.widget.TextView[@text="钱包"]/../android.widget.LinearLayout[2]/android.widget.ImageButton这个来代替上面的写法。

  最后再强调下,关于这个地方,下标为什么是[2],是因为只与class相同的有关。钱包的class不一样。所以它就不算了。

 

   3),关于相对路径的父子关系,已经兄弟关系,相比大家应该有所体会了吧。如果还是没太懂,咱们再来个复杂点的例子。可能只是举例说明下语法。实际下面的可能不会这样复杂的写。先上图:

 

 

 

 

  ,假设我们需要通过加入购物车这个位置来定位我们的立即定位按钮,那么,我们的一种写法就是图上的这个关系7层级。也就是加入购物车7(//android.widget.TextView[@text="加入购物车"])的父亲1(/..)的父亲2(/..)的父亲3(/..)的第二个兄弟4(/following-sibling::android.view.View[2])的儿子5(/android.view.View)的儿子6(也就是我们的立即购买/android.widget.TextView),连起来就是

    //android.widget.TextView[@text="加入购物车"]/../../../following-sibling::android.view.View[2]/android.view.View/android.widget.TextView。

注意:使用text的时候避免使用输入框的默认输入值,因为当你真实输入值之后,就没有这个text了,也就找不到路径了。另外也可以用模糊匹配,xpath有一个contains函数。用法//android.widget.TextView[contains(@text,"购物车")].也能找到“加入购物车”这个位置。自行体会去吧。。。

  最后不知道你是否有看懂?欢迎各位朋友留言指正。在下也喜欢技术交流。

 

 

 

 

 

    

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: XPath 是一种用于在 XML 和 HTML 文档中定位元素的语言。在 Web 自动化测试中,我们可以使用 XPath 定位元素并执行相应的操作。 以下是使用 XPath 定位元素的方法: 1. 使用绝对路径:可以通过使用完整的路径来定位元素。例如,使用 Chrome 浏览器的开发者工具,可以右键单击要定位的元素,然后选择“Copy XPath”选项来获取该元素的 XPath。 2. 使用相对路径:可以使用元素的属性、标签名、文本内容等来定位元素。例如,可以使用以下代码定位一个具有特定文本内容的元素: ``` //div[contains(text(),'some text')] ``` 3. 使用索引:如果页面中有多个相同的元素,可以使用索引来定位元素。例如,以下代码将定位第一个具有特定类名的 div 元素: ``` //div[@class='some-class'][1] ``` 4. 使用轴:可以使用 XPath 轴来定位与当前元素相关的元素。例如,以下代码将定位当前元素的父元素: ``` ../ ``` 以上是 XPath 定位元素的一些常用方法。在实际应用中,我们可以根据具体情况选择最适合的方法来定位元素。 ### 回答2: XPath(XML Path Language)是一种用于在XML文档中定位元素的语言。在编写Web自动化测试脚本时,XPath可以帮助我们快速准确地定位元素,实现自动化测试的目的。 使用XPath定位元素的方法有两种:绝对路径和相对路径。 绝对路径是指从根节点开始一直到目标元素的完整路径。使用绝对路径时,要用斜杠(/)作为分隔符来表示各级元素之间的关系。例如,要定位一个网页上的某个元素,可以使用绝对路径表示如/html/body/div[1]/div[2]/a。 相对路径是指相对于当前节点的路径。使用相对路径时,要用双斜杠(//)来表示各级元素之间的关系。相对路径的好处是不需要完整路径,只需要根据当前节点的层级关系来描述即可。例如,要定位一个网页上的某个元素,可以使用相对路径表示如//div[@class='content']/a。 XPath定位元素时可以结合元素的属性和属性值进行定位。使用[@属性名='属性值']的形式可以根据元素的属性值来定位元素。例如,//input[@id='txtUsername']表示通过元素的id属性来定位元素。 同时,XPath还支持通过元素的文本内容来定位元素。使用[text()='文本内容']的形式可以根据元素的文本内容来定位元素。例如,//a[text()='登录']表示通过元素的文本内容来定位元素。 XPath还可以使用逻辑运算符来定位元素,如and、or和contains等。通过结合多个条件,可以更准确地定位元素。例如,//input[@id='txtUsername' and @type='text']表示通过元素的id属性和type属性来定位元素。 综上所述,XPath定位元素是一种非常强大和灵活的方法,可以通过元素的层级关系、属性值和文本内容来精确定位元素,实现自动化测试的目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值