Selenium的元素八大定位详解
老鸟有兴趣可以移步Selenium元素定位神器工具谷歌浏览器插件-SelectorsHub介绍、安装和使用
目录
Selenium的元素八大定位详解1.id定位2.name定位3.tagname定位4.css定位,目前用的不多,建议直接浏览器鼠标右键copy5.classname定位6.linkText定位,即使用超链接的文本内容定位7.partialLinkText定位,即使用超链接的部分文本内容定位8.xpath定位,即路径定位.可以定位到99%的元素方法一:直接copy相对路径方法二:copy绝对路径方法三:根据文本信息定位方法四:部分信息匹配contains写法-匹配包含xxx信息的元素 方法五:元素属性定位方法六:根据元素的多个属性定位.引用属性值 方法七:根据父子/相邻节点定位(在同一大层级下)父子定位相邻定位 xpath轴定位写法parent:选取当前节点的父节点child:选取当前节点的所有子元素ancestor:选取当前节点的所有先辈(父、祖父等)descendant:选取当前节点的所有后代元素(子、孙等)following:选取文档中当前节点的结束标签之后的所有节点following-sibling:选取文档中当前节点的结束标签之后的所有同级节点preceding:选取文档中当前节点的开始标签之前的所有节点preceding-sibling:选取当前节点之前的所有同级节点 Xpath函数contains()-包含关系text()-获取元素文本值starts-with()-匹配xxx内容开头的元素ends-with()-匹配xxx内容结尾的元素substring()-截取部分内容来匹配not()-否定关系or()-或者关系normalize-space()-去掉前后的空格 更多Xpath教程(函数,轴...)信息看这里 提高元素定位复用率/降低定位维护率的办法.1.id定位
例如
java写法是
driver.findElement(By.id("su")});
浏览器中的定位写法是#开头直接输入id值,一般而言id值是唯一的.
#header_index
2.name定位
java写法是
driver.findElement(By.name("loginnum"))
浏览器中的定位写法同下面的xpath写法
3.tagname定位
例如
java写法是
driver.findElement(By.tagName("s_top_wrap"));
浏览器中的定位写法同下面的xpath写法
4.css定位,目前用的不多,建议直接浏览器鼠标右键copy
5.classname定位
例如
java的写法是
driver.findElement(By.className("btn self-btn bg s_btn"));
浏览器中的定位写法同下面的xpath写法
6.linkText定位,即使用超链接的文本内容定位
例如
java的写法是
driver.findElement(By.linkText("设为首页"));
浏览器中的定位写法同下面的xpath写法
7.partialLinkText定位,即使用超链接的部分文本内容定位
例如
driver.findElement(By.partialLinkText("为首页"));
8.xpath定位,即路径定位.可以定位到99%的元素
所有的定位的写法也支持单引号,比如//*[text()='基础信息'and@class='text']
方法一:直接copy相对路径
这种简单省事但是有时候定位不准,因为有的路径的属性是动态的…
例如
driver.findElement(By.xpath("//*[@id=\"su\"]"));
方法二:copy绝对路径
省事,但是路径很长,且容易受前端页面改动影响
例如
driver.findElement(By.xpath("/html/body/div[1]/div[1]/div[5]/div/div/form/span[2]/input"));
方法三:根据文本信息定位
写法是
//*[text()="设置"]
*代表模糊匹配; //代表相对定位
也可以这样写
//span[text()="设置"]
例如
driver.findElement(By.xpath("//span[text()=\"设置\"]"));
方法四:部分信息匹配
contains写法-匹配包含xxx信息的元素
//a[contains(text(),"123")]
或者
//*[contains(text(),"o123")]
关于contains的用法这里多写几个例子供参考
//div[contains(@class,'s_form_wrapper soutu-env-nomac')]
//form[contains(@id,'for')]
//a[contains(text(),'使用百度前')]
方法五:元素属性定位
//*[@id="su"]
或者
//input[@id="su"]
方法六:根据元素的多个属性定位.
//input[@id="su" and @value="百度一下"]
或者这样写,这种写法较为通用;
//并且关系
//input[@id="su"][@value="百度一下"]
一些其他的写法
//或者关系//input[@id="su" or @value="百度一下"]//模糊和或者关系//*[@id="su" or @value="百度一下"]//input[@*="su" or @*="百度一下"]//取反关系//input[@id="su"][not(@value="百度三下")]
引用属性值
//引用属性值//div[@id='order_BomVersionmain']//ul[@class='pagination em-pagination']//a[@pagenum][text()=@pagenum]
方法七:根据父子/相邻节点定位(在同一大层级下)
此方法适合解决难定位的元素;
<<<<<<<<<<<<<<<<<<<<<-12-18-更新-开始<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
也是实际项目中常用的,建议优先找到唯一的父亲分区然后在通过父子定位;唯一的父亲分区是指例如下图所示;所以在开始写定位时最好先熟悉下当前被测项目的前端页面的dom结构;这点之前没有提及现在补充
这种定位是比较可靠的定位方式;不易受前端改动的影响;
<<<<<<<<<<<<<<<<<<<<<-12-18-更新-结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
存在路径的层级关系的可以使用相邻节点定位
父子定位
//*[@class="bg s_btn_wr"]/input
或者
//span[@class="bg s_btn_wr"]/input
或者
//span[@class="bg s_btn_wr"]/input[@class="bg s_btn"]
如何有儿子元素定位到父亲元素
//div[@class='tbody-body']/../../..
或者
通过儿子tr匹配到父亲tr在匹配到孙子th,使用父子定位仍然可以加属性.
相邻定位
//div[@class="s-bottom-layer-left"]//a[text()="使用百度前必读"]
或者
//div[@class="s-bottom-layer-left"]//a[contains(text(),"度前必读")]
或者
//*[@class="s-bottom-layer-left"]//*[contains(text(),"度前必读")]
或者
//form[@id='signin-N']//button[@class='btn']
或者多个元素组合,下图演示的是三个元素相邻定位
//div//p//a[contains(text(),'使用百度前')]
xpath轴定位写法
轴定位写法有以下关键字:
parent,child,ancestor,descendant,following,following-sibling,preceding,preceding-sibling
parent:选取当前节点的父节点
//div[@id='header_index']/parent::div
child:选取当前节点的所有子元素
//div[@id='wrapper']/child::div
拓展写法
//div[@id='wrapper']/child::div[@id='sidebar']
ancestor:选取当前节点的所有先辈(父、祖父等)
//a[@title="HTML 参考手册"]/ancestor::div
拓展写法
//a[@title="HTML 参考手册"]/ancestor::div[@id='wrapper']
descendant:选取当前节点的所有后代元素(子、孙等)
//div[@id='wrapper']/descendant::div
等同于 xpath中的//
following:选取文档中当前节点的结束标签之后的所有节点
//div[@id='header_index']/following::a
following-sibling:选取文档中当前节点的结束标签之后的所有同级节点
//meta[@name='author']/following-sibling::link
拓展写法
//meta[@name='author']/following-sibling::link[@rel='apple-touch-icon-precomposed']
preceding:选取文档中当前节点的开始标签之前的所有节点
//meta[@name='author']/preceding::script
拓展写法
//meta[@name='author']/preceding::script[@type="text/javascript"]
preceding-sibling:选取当前节点之前的所有同级节点
//input[@value='Go']/preceding-sibling::input
拓展写法
//input[@value='Go']/preceding-sibling::input[@type="hidden"]
Xpath函数
contains()-包含关系
//input[contains(@value,'百度')]
text()-获取元素文本值
//a[contains(text(),'hao1')]
starts-with()-匹配xxx内容开头的元素
//a[starts-with(text(),'hao1')]
//a[starts-with(@title,'w3sch')]
ends-with()-匹配xxx内容结尾的元素
//a[ends-with(@title, '在线教程')]
但是由于这个写法是xpath2.0写法,有些浏览器不支持.截止到9月2日 edge和chrome不支持
substring()-截取部分内容来匹配
索引是从0开始索引长度-3即可;
//a[substring(@title, string-length(@title) - 3) = '在线教程']
高级一点的写法,条件是:截取部分内容包含xxx
//td[contains(substring(@class, string-length(@class) - 7) ,'mwnums') ]
not()-否定关系
//div[@class='hgbeOc']//span[not(text()='文档')]
or()-或者关系
//div[@class='hgbeOc']//span[not(text()='文档') or @jsname='j' ]
normalize-space()-去掉前后的空格
这里清除文本的前后的空格也可以清楚其他属性的值的前后空格
//div[@class='hgbeOc']//span[normalize-space(text())='文字']
更多Xpath教程(函数,轴…)信息看这里
点我查看-XPath函数
提高元素定位复用率/降低定位维护率的办法.
以下图为例:
如图所示,直接用name貌似就可以了,但是如果稍作修改例如此时增加一个元素和此元素的name相同.或者其他的一些情况导致同一网页下有多个此同name的元素.
为了提前防止此类事件的影响,我们在写定位的时候建议优先使用xpath定位,并且使用相对路径定位这样的元素组合定位.比如此时稍作更改上图的定位.
这里使用父节点和子节点的相对路径定位,就能较大程度的避免元素定位被重复进而提高其可靠性.