CSS Selector和Xpath均可以用来表示XML文档中的位置。CSS (Cascading Style Sheets)是一种样式表语言,是全部浏览器内置的,用于描述以HTML或XML编写的文档的外观和样式。CSS Selector用于选择样式化的元素,因此理论上前端人员能够定位 DOM 节点并设置样式,那么对于测试人员这些元素也能够定位到。css
XPath是XML路径语言,是一种查询语言,使用路径表达式浏览XML文档中的元素和属性。XPath标准语法以下:html
Xpath=//tagname[@attribute='value']前端
XPath有绝对定位和相对定位两种,绝对定位使用绝对路径,缺点是路径太长,只要一个节点变更就没法定位。以单斜杠(/)开始,表示从根节点开始选择元素。下面是页面https://www.baidu.com/上“百度一下”按钮的绝对路径:python
/html/body/div[1]/div[1]/div[5]/div[1]/div/form/span[2]/input
相对路径以双斜杠(//)开始,能够从HTML文档的任何位置开始,“百度一下”按钮的相对路径能够表示以下git
//input[@id="su"]
CSS Selector和Xpath几乎能够定位到全部Web元素(HTML和XML文档元素,Android应用的层级结构使用xml编写),它们的主要差别包括:web
接下来对比一下这两种方法的语法差别,节点的定义咱们规定以下:浏览器
xpath使用‘/’,CSS Selector使用‘>’post
Xpath | CSS Selector | |
---|---|---|
语法 | //element/element | element>element |
示例 | //div/a | div > a |
描述 | 选择父元素为 <div> 元素的全部 <a> 元素。 |
还可使用XPath Axes(轴)child 来定位子元素性能
XPATH:测试
//div/child::* # 选择父元素为 <div> 元素的全部儿子元素 //div/child::a # 选择父元素为 <div> 元素的全部<a>元素
CSS Selector:
div > a:nth-child(2) # 选择父元素为 <div> 元素的第二个<a>元素 div > a:nth-last-child(2) # 选择父元素为 <div> 元素的倒数第二个<a>元素 div > a:last-child # 选择父元素为 <div> 元素的最后一个<a>元素 div > a:first-child # 选择父元素为 <div> 元素的第一个<a>元素
xpath使用‘//’,CSS Selector使用空格
Xpath | CSS Selector | |
---|---|---|
语法 | //element//element | element element |
示例 | //div//a | div a |
描述 | 选择 <div> 元素内部的全部 <a> 元素。 |
还可使用XPath Axes(轴)descendant 来定位子孙元素
XPATH:
//div/descendant::* # 选择祖先元素为 <div> 元素的全部子孙元素 //div/descendant::a # 选择祖先元素为 <div> 元素的全部<a>元素
CSS Selector使用空格定位子孙元素后进行选择:
div a:nth-child(2) # 选择祖先元素为 <div> 元素的第二个<a>元素 div a:nth-last-child(2) # 选择祖先元素为 <div> 元素的倒数第二个<a>元素 div a:last-child # 选择祖先元素为 <div> 元素的最后一个<a>元素 div a:first-child # 选择祖先元素为 <div> 元素的第一个<a>元素
在同一个父节点下,定位下一个相邻节点
Xpath | CSS Selector | |
---|---|---|
语法 | //element/following-sibling::element | element + element |
示例 | //div/following-sibling::a | div + a |
描述 | 选择紧接在 <div> 元素以后的全部 <p> 元素。 |
Xpath能够定位当前节点前面的邻居节点,CSS Selector不能
//*element/preceding-sibling::element
CSS Selector是前向的,不能利用子节点定位父节点
方法 | 描述 |
---|---|
.. | 一个点”.“表示选取当前节点,两个点”..“表示选取当前节点的父节点。 |
ancestor | 当前节点祖先元素(父、祖父...) |
parent | 当前节点的父节点 |
Xpath | CSS Selector | |
---|---|---|
语法 | //*[@id='example'] | #example |
示例 | //*[@id='uesrname'] | #uesrname |
描述 | 选择id='uesrname'的元素。 |
Xpath | CSS Selector | |
---|---|---|
语法 | //*[@class='example'] | .example |
示例 | //*[@class='uesrname'] | .uesrname |
描述 | 选择class='uesrname'的元素。 |
没有Id和Class的状况下,可使用其它属性值定位,好比name、type等。
Xpath | CSS Selector | |
---|---|---|
语法 | //*[@attribute='value'] | [attribute=value] |
示例 | //*[@name='uesrname'] | [name='username'] |
描述 | 选择属性值name='uesrname'的元素。 |
xpath可使用 ‘and’ 或者 ‘or’ 链接两个属性:
XPATH:
//input[@name='login'and @type='submit']
CSS Selector:
input[name='login'][type='submit']
CSS Selector能够进行子字符串匹配进行定位:
^= 匹配前缀
[id^='id_prefix_'] # id前缀为‘id_prefix_’的元素
$= 匹配后缀
[id$='_id_sufix'] # id后缀为‘_id_sufix’的元素
*= 包含某个字符串
[id*='id_pattern'] # id包含‘id_pattern’的元素
Contains()方法也许经过部分文原本定位查找元素,CSS Selector不支持这种用法。
Xpath = //*[contains(@type,'partial_text')] Xpath = //*[contains(@name,'partial_text')] Xpath = //*[contains(@class,'partial_text')] Xpath = //*[contains(@id,'partial_text')] Xpath = //*[contains(text(),'partial_text')] Xpath = //*[contains(@href,'partial_text')]
查找属性值以特定文本开始的元素
Xpath = //*[starts-with(@type,'start_text')] Xpath = //*[starts-with(@name,'start_text')] Xpath = //*[starts-with(@class,'start_text')] Xpath = //*[starts-with(@id,'start_text')] Xpath = //*[starts-with(text(),'start_text')] Xpath = //*[starts-with(@href,'start_text')]
Text()方法基于web元素文原本进行定位
Xpath = //*[text()='text_value']
百度一下”text“,点击”资讯“
Xpath:
//*[@id="s_tab"]/descendant::a[1] //*[@id="s_tab"]/child::*[1]/a[1]
CSS selector:
#s_tab a:nth-child(2) #s_tab a:nth-last-child(9)
python测试代码:
def test_css(self): self.driver.get("https://www.baidu.com/") self.driver.find_element_by_id("kw").send_keys("test") self.driver.find_element_by_id("su").click() # element = self.driver.find_element_by_css_selector("#s_tab a:nth-child(2)") # element = self.driver.find_element_by_css_selector('#s_tab a:nth-last-child(9)') element = self.driver.find_element_by_xpath('//*[@id="s_tab"]/descendant::a[1]') element.click() sleep(2)
点击”资讯“下一个邻居节点”视频“
xpath
//*[@id="s_tab"]/descendant::a[1]/following-sibling::a[1] //*[@id="s_tab"]/child::*[1]/a[1]/following-sibling::a[1]
CSS selector:
#s_tab a:nth-child(2) + a #s_tab a:nth-last-child(9) + a
python测试代码:
def test_css2(self): self.driver.get("https://www.baidu.com/") self.driver.find_element_by_id("kw").send_keys("test") self.driver.find_element_by_id("su").click() # element = self.driver.find_element_by_css_selector('#s_tab a:nth-child(2) + a') element = self.driver.find_element_by_xpath('//*@id="s_tab"]/descendant::a[1]/following-sibling::a[1]') element.click() sleep(2)
测试页面:http://sahitest.com/demo/linkTest.htm
点击”linkByContent“
xpath语法:
//*[contains(@href,"Content")] //*[starts-with(@href,"linkByC")] //*[contains(text(),"Content")] //*[text()="linkByContent"]
python测试代码:
def test_css2(self): self.driver.get("http://sahitest.com/demo/linkTest.htm") # element = self.driver.find_element_by_xpath('//*[contains(@href,"Content")]') # element = self.driver.find_element_by_xpath('//*[starts-with(@href,"linkByC")]') # element = self.driver.find_element_by_xpath('//*[contains(text(),"Content")]') element = self.driver.find_element_by_xpath('//*[text()="linkByContent"]') element.click()
Xpath几乎能够定位到因此Web元素,CSS Selector效率更高,且代码简洁,但有些元素可能没法定位,特别是须要经过子元素来定位的父元素,或者须要经过文本定位的元素。
在实际使用中,按照本身的实际状况来选择便可,CSS Selector理论上执行效率更高,但他们的性能差别不是很大,在几毫秒或者几十毫秒级别。这两种定位方法除了本文介绍的之外,还有更多其它高级语法,能够参考官方文档。
文章标题:Web自动化测试:xpath & CSS Selector定位
本文做者:hiyo
本文连接:https://hiyong.gitee.io/posts/selenium-xpath-and-CSS-Selector-locator/ 欢迎关注公众号:「测试开发小记」及时接收最新技术文章!