本文链接: 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. [NOI赛前训练]——专项测试3·数学

    由于并不想写T1和T2的题解……所有只有T3的题解了. T3 由于内部题就只写题解了. 好吧,我是一点都不想写…… 说一下这zz题解哪里写错了吧…… ……不想写…… 就说一个吧…… $n-\frac{ ...

  2. jdbc 增删改查以及遇见的 数据库报错Can't get hostname for your address如何解决

    最近开始复习以前学过的JDBC今天肝了一晚上 来睡睡回笼觉,长话短说 我们现在开始. 我们先写一个获取数据库连接的jdbc封装类 以后可以用 如果不是maven环境的话在src文件下新建一个db.pr ...

  3. MYSQL———正则表达式查询!

    在使用select查询的过程中,有时会用到正则表达式对结果进行查询,将学习到的内容进行总结! 一 语法结构如下: 二 常用匹配方式进行示例说明 首先创建表student,表的结构如下: 1·^:查询s ...

  4. 本周新学的 GUI绘图技术

    作者语录:"终于学到绘图了 看到这种有图案的心情美丽多了  希望自己可以越学越多 越学越好" 本次就不用图片展示效果了,纯文字. 1.Graphics类概述 画图时我们都需要拥有一 ...

  5. hystrix服务降级(3)

    Hystrix使用fallback机制很简单,继承HystrixCommand只需重写getFallback(),继承HystrixObservableCommand只需重写resumeWithFal ...

  6. WebGL展示3D房屋内景

      原文地址:WebGL展示3D房屋内景   由于生活和工作上的原因,从年前开始一直到处奔波,没有太多的时间去关注和学习WebGL图形学相关的技术, 不过陆陆续续都有学习使用blender进行3D建模 ...

  7. Javaoop 遇到的问题

    一.java 异常的捕获与处理 (免责声明:本博客里所引用的他人博客链接,只用作我个人的学习,同时非常感谢这些作者!) 1.  https://blog.csdn.net/wei_zhi/articl ...

  8. EIGRP 高级实验

    一.环境准备 1. 软件:GNS3 2. 路由:c7200 二.实验操作 实验要求: 1.掌握EIGRP  的不等价均衡的条件. 2.掌握EIGRP  的metric  值修改方法. 3.掌握 EIG ...

  9. ubuntu中使用docker部署.netcore2.1

     概述    .netcore发布这么久,到现在才在项目中实际运用,之前算是了解一点,一般找工作都会问是否运用过.netcore,软件研发来说,如果这个技术没用过,觉得挺难,其实不难..netcore ...

  10. Mybatis插入数据返回主键ID

    <insert id="add" parameterType="com.dsa.core.base.model.ProductSync">      ...