使用selenium进行自动化时少不了对元素进行定位,但目前前端大多使用框架vue,angular等,很多元素并没有id,name等这些让我们很容易定位的元素属性,这时候就要用到xpath进行定位了,而利用xpath中的轴可以很轻松的精确定位到你要的元素
一、xpath轴
xpath的基础语法和谓语可看网上的一些文档(http://www.runoob.com/xpath/xpath-syntax.html)
二、实例
具体使用方法示例为:parent::div,即轴名称::标签名,挑上图一些用实例进行分析
- parent 选取当前节点的父节点,也就是当前节点上一级节点
示例://div[contains(text(),'产证地址')]/parent::td
前半段//div[contains(text(),'产证地址')]为找到内容包含产证地址的div节点(圈出来的节点)然后它的上一级节点 parent::td,即黄色部分
- child 选取当前节点的子节点,也就是当前节点的下一级节点
示例://td[@width='50%']//child::div
前半段//td[@width='50%'] 为找到属性width为50%的td节点(红框圈出来的地方),然后它的下一级节点child::div,即黄色部分
- ancestor 选取当前节点的所有上层节点
示例://div[contains(text(),'产证地址')]//ancestor::table
前半段//div[contains(text(),'产证地址')]为找到内容包含产证地址的div节点,然后找到它的上层节点中的table节点
注意:ancestor只能找上层节点,如果是上层节点的兄弟节点是找不到的
//div[contains(text(),'产证地址')]//ancestor::p,像这样是找不到table节点的兄弟节点p的
- descendant 选取当前节点的所有下层节点
实例 ://td[@width='50%']/descendant::p
-
following 选取当前节点之后显示的所有节点
示例://td[@width='50%']/following::div[contains(text(),'行政区域')]
//td[@width='50%']为圈出来的节点,following::div[contains(text(),'行政区域')]找到它之后的所有节点中text内容包含行政区域的节点(黄色部分)
following-sibling 选取当前节点之后所有的兄弟(平级)节点
示例://p[text()='物业信息']/following-sibling::p[@id='ownerPart']
//p[text()='物业信息'] 找到内容为物业信息的节点(圈出来的部分),following-sibling::p[@id='ownerPart'] 然后找到它的兄弟节点中id为ownerPart的节点(黄色部分)
- preceding 选取当前节点前面所有的节点
示例://p[text()='出售方信息']/preceding::div[contains(text(),'拟定网签价')]
//p[text()='出售方信息'],红色框圈出来的部分preceding::div[contains(text(),'拟定网签价')]找到前面所有节点中text内容包含拟定网签价的div节点(黄色部分)
- preceding-sibling 选取当前节点前面所有兄弟(平级)节点
示例://p[text()='出售方信息']/preceding-sibling::p[contains(text(),'物业信息')]
//p[text()='出售方信息'] 红色框圈出来部分
preceding-sibling::p[contains(text(),'物业信息')] 找到它前面的所有兄弟节点中内容包含物业信息的p节点(黄色部分)
三、小tips
- 谓语:
starts-with 顾名思义,匹配一个属性开始位置的关键字
contains 匹配一个属性值中包含的字符串
text() 匹配的是显示文本信息,此处也可以用来做定位用
//input[starts-with(@name,'name1')] 查找name属性中开始位置包含'name1'关键字的页面元素
//input[contains(@name,'na')] 查找name属性中包含na关键字的页面元素
<a href="http://www.baidu.com">百度搜索</a>
xpath写法为 //a[text()='百度搜索']
或者 //a[contains(text(),"百度搜索")] - .// 和//的区别
//是指从全文上下文中搜索//后面的节点
.// 中.表示当前节点,.//表示从当前节点之后的子节点中查找(或指从前面的节点的子节点中进行查找)
例如://div[.//a[text()=’SELENIUM’]] 为从任意div中查找其子节点文本为SELENIUM的a元素 - 凡是用text()的地方均可以直接用.来进行表示,例如a[text()=’SELENIUM’]和a[.=’SELENIUM’]是等价的。
四、个人心得
- 1、定位元素先看改元素在页面中有没有唯一性的属性或内容,有就可以根据这个来定位
例如:
//a[text()='确定']
//input[@placeholder='请输入,若无则无需填写'] - 2、如果没有唯一性的属性就可该元素的上下中有没有唯一性的属性或内容,这样就可以先定位它的上下元素,然后在来找你要定位的元素
例如://span[text()='贷款']/preceding-sibling::span/span
这个是先找到内容为贷款的span节点然后找它上面的平级节点span然后在往下找一层span - 3、总体的思路就是通过节点或它的上下节点的唯一性来入手以保证你定位元素的唯一性,以下是几个自己定位的实例
//table[.//p[text()='拥有房屋产权家庭一:']]//td[./p[text()='产权人二:']]//form//form//input[@placeholder]
.代表当前节点
//table[.//p[text()='拥有房屋产权家庭一:']]//td[./p[text()='产权人三:']]//form//form//li[./label[contains(text(),'购入份额契税')]]//input
//body/div[last()]//span[text()='买卖'] - 4、descendant表示选取当前节点的所有后代元素
凡是使用descendant的地方都可以用//替换,效果一样,都是查找后台元素