元素定位之XPATH
前言
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::*