本文链接: 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. bzoj 2120 数颜色 带修改莫队

    带修改莫队,每次查询前调整修改 #include<cstdio> #include<iostream> #include<cstring> #include< ...

  2. BZOJ_4636_蒟蒻的数列_线段树+动态开点

    BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将 ...

  3. CF_229E_Gift_概率DP+组合数学

    CF_229E_Gift_概率DP+组合数学 题目描述: 很久很久以前,一位老人和他的妻子住在蔚蓝的海边.有一天,这位老人前去捕鱼,他捉到了一条活着的金鱼.鱼说:“噢,老渔人!我祈求你放我回到海里,这 ...

  4. BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组

    BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...

  5. BZOJ_1503_[NOI2004]郁闷的出纳员_权值线段树

    BZOJ_1503_[NOI2004]郁闷的出纳员_权值线段树 Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的 工资. ...

  6. Laravel分页带参数的实现方法

    控制器: $data['type'] = 5;$data['member_list'] = Member::orderBy('id', 'desc')->paginate(10);return ...

  7. Bot Framework 搭建聊天机器人

    这周我来跟大家分享的是在Microsoft Build 2016上发布的微软聊天机器人的框架. 现如今,各种人工智能充斥在我们的生活里.最典型的人工智能产品就是聊天机器人,它既可以陪我们聊天,也可以替 ...

  8. SQL Android

    SQLite是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少. 一般有以下几个关键步骤: 1.创建数据库 2.创建表 3.操作:增删改查 4.关闭数据库 5.删除表(非必选) SQLite ...

  9. RabbitMQ和Kafka到底怎么选(二)?

    前言 前一篇文章<RabbitMQ和Kafka到底怎么选?>,我们在吞吐量方面比较了Kafka和RabbitMQ,知道了Kafka的吞吐量要高于RabbitMQ.本文从可靠性方面继续探讨两 ...

  10. pandas和spark的dataframe互转

    pandas的dataframe转spark的dataframe from pyspark.sql import SparkSession # 初始化spark会话 spark = SparkSess ...