前言

  XPATH即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。既可以用于XML,也可以用于HTML。XPATH其实就是一个path(路径),一个描述页面元素位置信息的路径,相当于元素的坐标。XPATH定位在UI自动化中特别常用,具有“万能定位”的标签,大多数公司编写UI自动化都会使用XPATH去做元素定位。相比较CSS选择器定位,XPATH定位更容易些。

XPATH定位

1、绝对定位

绝对定位通常会从根目录(/)开始,绝对路径以单/号表示,让解析引擎从dom树的根节点开始解析,也就是html这个节点下开始解析,一直往下查找,直到找到对应的元素为止

例如百度输入框的元素:

/html/body/div[2]/div[1]/div[5]/div/div/form/span[1]/input

路径解释:

html -> body -> 第二个div -> 第一个div -> 第5个div -> div -> div -> form -> 第一个span -> input

写法:

driver.findElement(By.xpath("/html/body/div[2]/div[1]/div[5]/div/div/form/span[1]/input"));

使用绝对路径的缺点:

一旦页面结构发生变化,该路径也会随之失效,因此该定位方式极其不稳定,在自动化中也不推荐使用该种定位方式。


2、相对定位

相对定位使用//,不从根节点/开始,一般是从当前元素节点或者附近元素节点开始解析,然后去匹配到我们想要定位的元素为止

例如百度的搜索点击按钮:

//input[@value='百度一下']

路径解释:

  • // 匹配指定节点,不考虑它们位置
  • input是对应标签名,此处可以用替换,是通配符,匹配任意元素标签名
  • @选取属性
  • []属性判断条件表达式

写法:

driver.findElement(By.xpath("//input[@value='百度一下']"));

使用相对路径的优点:

相对路径的xpath表达式更加简洁,使用起来比较方便灵活,耦合性低。如果页面结构发生变化,只要input标签下的value值"百度一下"不变,就不会影响到我们我们的定位结果。


定位方式

1)通过元素名定位

获取页面所有的input元素

//input


2)通过元素名 + 索引定位

定位搜图按钮

//form/span/span[1]


3)通过元素名 + 属性

定位input标签下id属性值为su的元素

//input[@id='su']


4)通过元素名 + 部分属性值

  • contains:

定位input标签下value属性值包含"百度"的元素

//input[contains(@value,'百度')]


  • starts-with:

定位input标签下value属性值以"百度"开头的元素

//input[starts-with(@value,'百度')]


5)通过元素名 + 元素的文本内容

定位span标签下文本内容为"按图片搜索"的元素

//span[text()='按图片搜索']


6)通过元素名 + 部分文本内容

定位span标签下文本内容包含"按图片"的元素

//span[contains(text(),'按图片')]
//span[starts-with(text(),'按图片')]


7)通过元素名 + 下标匹配

  • position()

定位form标签下的第一个input元素

//form/input[position()=1]
//form/input[position()<2]	// 也可以用比较运算去取第一个input元素


  • last()

定位form下的最后一个input元素

//form/input[last()]	// 如果需要取倒数第二个,可以用last()-1


8)轴定位

  • parent

含义:选择当前节点的上一层父节点

查找id的属性值为su的input元素,基于input元素位置查找到它上一级的span元素

//input[@id='su']/parent::span


  • ancestor

含义:选择当前节点所有上层节点

查找到id的属性值为su的input元素,基于input元素位置查找到它上级的所有div元素

//input[@id='su']/ancestor::div


  • ancestor-or-self

含义:选择当前节点所有上层节点及节点本身

查找到id的属性值为su的input元素,基于input元素位置查找到它自己本身节点

//input[@id='su']/ancestor-or-self::input

查找到id的属性值为su的input元素,基于input元素位置查找到它上级的span元素

//input[@id='su']/ancestor-or-self::span


  • child

选择当前节点的下层所有子节点

查找到id的属性值为form的form元素,基于form元素位置查找到它下层子节点所有的input元素

//form[@id='form']/child::input


  • descendant

选择当前节点的所有下层节点(子,孙等)

查找到id的属性值为form的form元素,基于form元素位置查找到它下层所有节点的input元素

//form[@id='form']/descendant::input


  • following

选择当前节点后的所有节点

查找到id的属性值为form的form元素,基于form元素位置查找到它所在节点后的div元素

//form[@id='form']/following::div


  • following-sibing

选择当前节点后的所有兄弟节点

查找到id的属性值为form的form元素,基于form元素位置查找到它后面兄弟节点的div元素

//form[@id='form']/following-sibling::div


  • preceding

选择当前节点前的所有节点

查找到id的属性值为form的form元素,基于form元素位置查找到它所在节点前的div元素

//form[@id='form']/preceding::a


  • preceding-sibling

选择当前节点前的所有兄弟节点

查找到id的属性值为form的form元素,基于form元素位置查找到它所在节点前兄弟节点的第一个div元素

//form[@id='form']/preceding-sibling::div


  • self

选取当前节点

查找到id的属性值为form的form元素,基于form元素位置查找到它本身节点

//form[@id='form']/self::form


  • attribute

选取当前节点的所有属性

查找到id的属性值为form的form元素,基于form元素位置查找到它本身节点的所有属性

//form[@id='form']/attribute::*