博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
XPath和CssSelector定位总结
阅读量:5278 次
发布时间:2019-06-14

本文共 3918 字,大约阅读时间需要 13 分钟。


本文链接: https://www.cnblogs.com/hchengmx/p/10755116.html

1.

XPath: XPath 最初是用来在 XML 文档中定位 DOM 节点的语言,由于 HTML 也可以算作 XML 的一种实现,所以 Selenium 也可以利用 XPath 这一强大的语言来定位 Web 元素。XPath 在传统属性定位之外扩展了诸如“定位第三个多选框”等定位能力,以便应对没有 ID 或 name 属性的情况。

CSS (Cascading Style Sheets) 是一种用于渲染 HTML 或者 XML 文档的语言,CSS 利用其选择器可以将样式属性绑定到文档中的指定元素,即前端开发人员可以利用 CSS 设定页面上每一个元素的样式。所以理论上说无论一个元素定位有多复杂,既然开发人员能够定位到并设置样式,那么测试人员同样应该也能定位继而操作该元素。

多个 CSS 选择器还可以用逗号拼接为一个组合选择器,满足任意其中一个选择器的元素都会被该组合选择器选中,逗号的前后允许出现空白。

所以 从工作机制来讲:XPath使用路径标记在XML文档层次结构中进行导航,简单说就是遍历文档路径。Selector则是一种匹配模式,速度上优化于XPath。

2.

2.1.

XPath = //tagname[@attribute='value']
  • // 目前的节点
  • tagname:想要选的节点的tag,input,div,img等, 但也经常被替换为*
  • Attribute: 想要选择节点的属性
  • Value: 属性的值

用XPath选择的其他例子:

Xpath=//input[@type='text']             Xpath=  //label[@id='message23']Xpath=  //input[@value='RESET']Xpath=//*[@class='barone']Xpath=//a[@href='http://demo.guru99.com/']Xpath= //img[@src='//cdn.guru99.com/images/home/java.png']

补充知识点2: 如何用XPath获取该元素的父亲:

public static IWebElement GetParent(this IWebElement element){    return element.FindElement(By.XPath(".."));}

2.2.

适用于某个属性动态的值变化, 但是其值总是包含什么特定的字符串。

//*[contains(@id,'message')]

2.3.

可以理解为contains的延申, 选择某元素的值总是以XXX开头

Xpath=//label[starts-with(@id,'message')]

2.4.

用Or的话, 两个条件其中之一为真则为真, 用And的话, 两个条件均为真则真(个人用And多一点, 用来筛选元素)。

Xpath=//input[@type='submit' and @name='btnLogin']

2.5.

适用于其内的text在页面唯一的情况, 书写起来也最简单;

XPath-Text()示例

2.6.

轴名称 结果
ancestor 选取当前节点的所有先辈(父、祖父等)。
ancestor-or-self 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。
attribute 选取当前节点的所有属性。
child 选取当前节点的所有子元素。
descendant 选取当前节点的所有后代元素(子、孙等)。
descendant-or-self 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。
following 选取文档中当前节点的结束标签之后的所有节点。
namespace 选取当前节点的所有命名空间节点。
parent 选取当前节点的父节点。
preceding 选取文档中当前节点的开始标签之前的所有节点。
preceding-sibling 选取当前节点之前的所有同级节点。
self 选取当前节点。

eg:

Xpath=//*[@type='text']//following::inputXpath=//*[@id='java_technologies']//child::liXpath=//*[text()='Enterprise Testing']//ancestor::divXpath=//*[@id='rt-feature']//parent::div

2.7.

2.7.1.

绝对路径:以单斜杠 / 开头, 表示选择当前节点, 一般从根节点来选取元素, 通过这样的XPath表达式特别长:

html/body/div[3]/div/div[2]

用绝对路径选择元素

相对路径:以双斜杠 // 开头,可以选择页面上的任何元素

用相对路径选择元素

2.7.2.

以下来自selenium官方文档, 原文可以看。

从原理上来讲, 每个浏览器都应该有自己的原生xpath方法,要是没有的话,才会用selenium提供的方法。

具体区别如下:

Driver Tag and Attribute Name Native XPath Support
HtmlUnit Driver Lower-cased Yes
Internet Explorer Driver Lower-cased No
Firefox Driver Case insensitive Yes

下面是一个例子:

用代码

List
inputs = driver.findElements(By.xpath("//input"));

用几个driver分别会找到下面几个元素

XPath expression HtmlUnit Driver Firefox Driver(同chrome) Internet Explorer Driver
//input 1 (“example”) 2 2
//INPUT 0 2 0

3.

3.1

语法: tag.class

eg:

div.ibm-alternate-rule

3.2

语法: css=tag[attribute=value], 更多包括通配符的例子可以看。

eg:

ul[role='tablist']

3.3

详细介绍可以看

语法:

tag1 tag2   //tag1的所有后代中的tag为tag2的

eg:

div.sidebar a //结合类选择器使用, 找到属性为div且class为sidebar的所有tag为a的后代

3.4

详细介绍可以看

语义: 如果您不希望选择任意的后代元素,而是希望缩小范围,只选择某个元素的子元素,请使用子元素选择器

eg:

table.company td > p

上面的选择器会选择作为 td 元素子元素的所有 p 元素,这个 td 元素本身从 table 元素继承,该 table 元素有一个包含 company 的 class 属性。

3.4

动态伪类: 未被访问/已被访问/活动/获得焦点

UI元素状态伪类: 第n个孩子;
CSS3的:nth选择器: element 状态(禁用/启用/被选中)

可以在 查看详情。

4.

XPath的劣势:

  1. 不同的浏览器 XPath 引擎不同甚至没有自己的 Xpath 引擎,这就导致了 XPath 定位速度较慢
  2. Xpath往往变得复杂,因此在我看来很难阅读

CssSelector的劣势:

  1. 无法找到某元素的父亲元素(当然这种也很难遇到)

所以个人定位经验总结:

  1. 首先考虑这个元素有无唯一的属性, 比如id/name;
  2. 查看改元素有无唯一的text, 用CssSelector的text()定位;
  3. 这个元素是否为多个属性, 多个属性用And连接起来是否可能唯一, 用CssSelector的And关键字;
  4. 首选从这个元素的父亲元素/祖宗元素, 有无唯一属性, 善用CssSelector的后代选择器和子元素选择器;
  5. 使用约束, 用findelements(By.CssSelector("")).first(ele => ele.Text == "");
  6. 再复杂的我目前还没见过;

5.

  1. 尽可能的不要用findelements
List
elements = driver.findelements(By.CssSelector(""));element = elements.first()
  1. 尽量减少和服务的通信:
if(driver.findelements(By.CssSelector("li[role='radio']").Count() != 0){    driver.findelement(By.CssSelector("li[role='radio']")).click();}

上面需要和driver通信两次, 查找元素两次, 可以考虑替换为下面的代码。

var element = driver.findelement(By.CssSelector("li[role='radio']"))if(element!=null){    element.click();}

6.


本文希望对您有所帮助,如何问题可联系我的个人微信

个人号

转载于:https://www.cnblogs.com/hchengmx/p/10755116.html

你可能感兴趣的文章
ACdream 1068
查看>>
2018/6/6 Python今日收获
查看>>
pandas越来越难学,只能自己找趣味了,你该这么学,No.11
查看>>
python模块—pickle shelve
查看>>
Windows Azure AppFabric (一) 平台简介
查看>>
批量修改文件扩展名(批处理)
查看>>
Matlab求解线性方程组Ax=b的几种常见方法Matlab求解线性方程组Ax=b的几种常见方法...
查看>>
喜欢的电影
查看>>
会声会影毛玻璃制作
查看>>
HDU 2665 Kth number
查看>>
CodeChef DGCD Dynamic GCD
查看>>
记叙在人生路上对你影响最大的三位老师
查看>>
002.大数据第二天
查看>>
python装饰器
查看>>
树上的路径
查看>>
【转载】TCP好文
查看>>
系统平均负载
查看>>
【并发】实现内存可见的两种方法比较:加锁和volatile变量
查看>>
[线段树]/[水法] Jzoj P100036 随机
查看>>
问题总结
查看>>