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

1. 介绍XPath和CssSelector

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. XPath有哪些方式

2.1. 通过XPath语法

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关键字

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

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

2.3. Start-With

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

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

2.4. Or和And关键字

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

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

2.5. Text()

适用于其内的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::input
Xpath=//*[@id='java_technologies']//child::li
Xpath=//*[text()='Enterprise Testing']//ancestor::div
Xpath=//*[@id='rt-feature']//parent::div

2.7. 补充知识点

2.7.1. 绝对路径和相对路径的区别

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

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

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

2.7.2. XPath在不同浏览器上的区别

以下来自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

下面是一个例子:

<input type="text" name="example" />
<INPUT type="text" name="other" />

用代码

List<WebElement> 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. CssSelector有哪些方式

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和CssSelector的选择

根据Microsoft的推荐: 也是推荐CssSelector, 理由如下:

  1. Xpath在不同浏览器中会不同(Xpath engines are different in each browser)
  2. Xpath比较难阅读(XPath can become complex and therefore more difficult to read)
  3. Css selector更快(CSS selectors are faster)
  4. Css是一种基于JQuery的定位策略(CSS is JQuery's locating strategy)
  5. IE没有Xpath引擎(Internet Explorer does not have a native XPath engine)

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<IWebElement> 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. 参考资料

  1. XPath in Selenium WebDriver: Complete Tutorial
  2. 全球化测试中利用 Selenium 定位 Web 元素难点解析
  3. 记一次元素定位优化行动
  4. XPath 语法
  5. XPath 节点
  6. XPath Axes(轴)
  7. selenium官方关于xpath的介绍
  8. 一招让 IOS 自动化化快的飞起

    9/ portaldocs/top-extensions-csharp-test-framework.md at master · Azure/portaldocs · GitHub

XPath和CssSelector定位总结的更多相关文章

  1. 2.7.5 元素定位(主推xpath、cssSelector) ❀❀❀

    定位方式选择: 1. 当页面元素有id属性时,最好尽量用id来定位.但由于现实项目中很多程序员其实写的代码并不规范,会缺少很多标准属性,这时就只有选择其他定位方法. 2. xpath很强悍,但定位性能 ...

  2. cssSelector定位笔记1

    cssSelector定位方法:1.使用class属性定位元素:driver.findElement(By.cssSelector("input.login"));即可以先指定一个 ...

  3. Selenium 中 cssSelector定位

    一.为什么使用cssSelector定位元素? 目前针对一些常规定位方式有:By.id.By.name.By.LinkTest(针对<a>标签).By.ClassName 针对不太好定位的 ...

  4. Selenium自动化中DOM,XPATH,CSS定位Web页面对象的优劣性分析

    加速IE浏览器自动化执行效率:Selenium自动化中DOM,XPATH,CSS定位Web页面对象的优劣性分析 1.技术背景       在Web应用中,用户通过键盘在输入框中输入值和鼠标点击按钮,链 ...

  5. Selenium中如何使用xpath更快定位

    在学习Selenium路上,踩了也不少坑,这是我最近才发现的一个新写法,好吧,"才发现"又说明我做其他事了.对的,我现在还在加班! 开车~~~ 例子:知乎网 标签:Python3. ...

  6. By.cssSelector定位元素一个不足发现

     这个如果用cssSelector定位,代码如下,此时输出的数值是0 System.out.println(driver.findElements(By.cssSelector("div[c ...

  7. selenium+xpath 文本信息定位

    selenium中根据父子.兄弟.相邻节点定位的方法,很多人在实际应用中会遇到想定位的节点无法直接定位,需要通过附近节点来相对定位的问题,但从父节点定位子节点容易,从子节点定位父节点.定位一个节点的哥 ...

  8. xpath与css_selector定位详解

    例题:分别用xPath和css_selector定位下图的img标签 答案:  xpath:.//*[@id='fstscr']/div[3]/div[2]/a/img css_selector: . ...

  9. web中的CSS、Xpath等路径定位方法学习

    今天不到八点就到公司了,来的比较早,趁着有点时间,总结下web中的CSS.Xpath等路径定位定位的方式吧! 简单的介绍下xpath和css的定位 理论知识就不罗列了 还是利用博客园的首页.直接附上代 ...

随机推荐

  1. JSON 数据重复 出现$ref

    JSONArray  类型  如果我们往里面add数据的时候 如果数据相同,那么就会被替换成 $ref:   也就是被简化了 因为数据一样所直接 指向上一条数据 循环引用:当一个对象包含另一个对象时, ...

  2. Python中的turtle初探

    turtle Python自带了一个turtle库,就像名字turtle说的那样,你可以创建一个turtle,然后这个turtle可以前进,后退,左转,这个turtle有一条尾巴,能够放下和抬起,当尾 ...

  3. 计算机17-3,4作业F

    F.complete number problem with formatted output   Description 同题目E Input N Output complete numbers w ...

  4. Spire高效稳定的.NET组件

    年末将至,又到了一年一度的收集发票时间,平时零零碎碎的花钱都是不在意开发票,现在好了,到处找发票来报销,简直头大, 东拼西凑,终于搞定了全部发票,大伙多余的发票,麻烦艾特我一下啊,不限日期,能开发票的 ...

  5. 一文学会Scala

    整体介绍 Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性. 联邦理工学院洛桑(EPFL)的Martin Odersky于2001 ...

  6. .NET Core IdentityServer4实战-开篇介绍与规划

    一.开篇寄语 由于假期的无聊,我决定了一个非常有挑战性的活动,也就是在年假给大家带来一个基于OAuth 2.0的身份授权框架,它就是 IdentityServer4 ,如果没有意外的话,一定可以顺利的 ...

  7. 《前端之路》之 JavaScript 高级技巧、高阶函数(一)

    目录 一.高级函数 1-1 安全的类型检测 1-2 作用域安全的构造函数 1-3 惰性载入函数 1-4 函数绑定 1-5 函数柯里化 1-6 反函数柯里化 一.高级函数 1-1 安全的类型检测 想到类 ...

  8. [Hyperledger] Fabric系统中 peer模块的 gossip服务详解

    最近一直在看fabric系统中的核心模块之一——peer模块.在看peer的配置文件core.yaml的信息时,对其中的gossip配置选项很感兴趣.看了一上午,还是不能明白这个选项到底什么意思呢?表 ...

  9. 『神坑』DotNetty 内存泄漏 解决办法

    背景 近来在用 DotNetty 实现一个文件上传下载的同步服务. 其中:客户端下载服务端的文件,客户端多次请求,从服务端将文件分片下载下来,追加到本地磁盘. —— 非常简单的代码,都写了几十次了,驾 ...

  10. java~springcloud微服务目录索引

    回到占占推荐博客索引 最近写了不过关于java,spring,微服务的相关文章,今天把它整理一下,方便大家学习与参考. java~springcloud微服务~目录索引 springcloud~服务注 ...