本文链接: 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. vue iview UPload,但文件上传是,clearFiles的使用方法

    <template> <div> <button @click="clearUploadedImage">重新上传</button> ...

  2. RocketMQ源码 — 十一、 RocketMQ事务消息

    分布式事务是一个复杂的问题,rmq实现了事务的最终一致性,rmq保证本地事务成功消息一定会发送成功并被成功消费,如果本地事务失败了,消息不会被发送. rmq事务消息的实现过程为: producer发送 ...

  3. JDBC知识详解

    一.相关概念 1.什么是JDBC JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它 ...

  4. Python练习:关于递归的经典实例设计

    (一)裴波拉契数列 利用递归算法获得裴波拉契数列前N个值的结果: #裴波拉契数列,通过递归计算 def fb(n): if n <=0: res = 0 elif n ==1: res = 1 ...

  5. python3的socket使用

    如果需要设置两台机器的端口,请查看博文 centos7开放端口和防火墙设置 需要实现两台机器的信息交互,使用 socket 进行调度.其中服务端为: #!/usr/bin/env python # - ...

  6. Java的自定义注解使用实例

    概念 Java有五个元注解,自动继承java.lang.annotation.Annotation. 什么是元注解,可以理解为其他普通注解进行解释说明 @Target  该注解的使用范围,限定应用场景 ...

  7. Redis 缓存失效和回收机制续

    二.Redis Key失效机制 Redis的Key失效机制,主要借助借助EXPIRE命令: EXPIRE key 30 上面的命令即为key设置30秒的过期时间,超过这个时间,我们应该就访问不到这个值 ...

  8. 学习 JavaScript (五)核心概念:语句

    语句 语句被称作是流控制语句,通常有标志性的一个或者多个关键字,if . do-while. while.for. for-in. label. break.continue.with.switch. ...

  9. .net core 杂记:日记记录

    ASP.NET Core 有内置的log组件,遗憾的是看了微软官方文档,貌似无法直接将日志存于文件或数据库,只能由自己实现或引用第三方日志组件. 以下为Nlog和log4net的使用记录 Nlog使用 ...

  10. HTML阻止iframe跳转页面并使用iframe在页面内嵌微信网页版

    昨天看到这篇文章[置顶]开源组件NanUI一周年 - 使用HTML/CSS/JS来构建.Net Winform应用程序界面 就想弄一个winform结合html5的一个小东西,突有兴致,想在里面嵌套一 ...