在前面的文章中,已经写过在 selenium webdriver中常见的8种元素定位方式,其中就包括一部分的xpath的使用,但内容不是很全面,此文算是作为补充,如查看其他定位方式,请移步到:
捉虫布道人:ALLEN老师自动化测试小课堂 | WebDriver API之常见元素定位方法zhuanlan.zhihu.comXpath作为一个万桶油的技术,在web自动化测试种也得到了很好的体现,他丰富的使用方式可以实现99%的元素定位,可以说掌握了他,就可以横着走啦。
一、Xpath简介
XPath是一门在 XML 文档中查找信息的语言,XPath 用于在 XML 文档中通过元素和属性进行导航。又由于xml的编写格式几乎与html一致,我们也可以使用Xath去定位HTML页面的标签和元素。
Xpath应用在web自动化测试的元素定位上,常见的用法又如下几种
- /:从根节点选取开始查找元素,即从/html开始,也成为绝对路径定位
- //:从非根节点(任意节点)选取,结合属性和层级关系定位
- *:通配符,表示任意节点标签
- @:后面可以跟标签属性,即根据属性定位
- text():根据链接文本定位元素
- and/or:逻辑运算符,可以关联多个属性或链接文本,以备一个属性不能正常定位
- []:可以放置下标、属性和链接文本
- .:选取当前节点
- ..:选取当前节点的父节点
- contains:包含,用于模糊匹配
二、Xpath使用
本文中的案例主要采用百度首页的相关要素进行设计。
1、 Xpath的绝对路径用法
以/开头,从HTML标签开始,依次遍历HTML结构树的节点,直到找到要定位的页面元素,一般万不得已不使用。如百度文本框的绝对路径为,随着百度版本的变化,路径可能会变化:
/html/body/div/div/div[3]/div/div/form/span/input
- 父子节点是使用/连接,从上往下依次遍历
- 兄弟节点是[]表示兄弟的排行,比如同一级别上有2个以上的input标签,input[2]就是排在第二位的,排行老大可以写为:input或者是input[1]
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#使用绝对路径定位
# driver.find_element_by_xpath("/html/body/div/div/div[3]/div/div/form/span/input").send_keys("selenium")
# time.sleep(2)
# driver.find_element_by_xpath("/html/body/div/div/div[3]/div/div/form/span[2]/input").click()
# time.sleep(2)
driver.quit()
2、通过单一属性定位(相对路径)
一般以//开头,使用属性id、name、class结合xpath进行定位,如百度文本框的定位:
- //input[@id='kw']
- //input[@name='wd']
- //input[@class='bg s_btn']
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#利用元素单一属性定位
# driver.find_element_by_xpath("//input[@id='kw']").send_keys("selenium")
# time.sleep(2)
# driver.find_element_by_xpath("//input[@id='su']").click()
# time.sleep(2)
driver.quit()
3、通过多个属性定位(相对路径)
在一个属性不能定位到元素的时候,可以逻辑运算符and、or:
- 元素a : id = 1,name = a
- 元素b : id = 1 , name = b
- 元素c : id = 2 ,name = a
- and:表示多个条件要同时成立才行
- or:多个条件,有一个成立就可以
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#使用逻辑and或者or运算符
driver.find_element_by_xpath("//input[@id='kw' or @name = 'wd']").send_keys("selenium")
time.sleep(2)
driver.find_element_by_xpath("//input[@id='su']").click()
time.sleep(2)
driver.quit()
4、通过父子关系和属性定位
在HTML问答结构树中,如果两个节点有所属关系,则上层节点为父节点,下层节点为子节点,在调用时候使用/连接父子节点。
假设某个标签就一个标签名,其他属性一概没有(或者有一个class,而且是重复的)。
- 使用绝对路径没问题,就是复杂点
- 使用属性定位,就不靠谱了,定位不到
- //form[@id='form']/span/input
- //form[@id='form']/span[2]/input
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# 利用父子关系以及属性定位:
# driver.find_element_by_xpath("//form[@id='form']/span/input").send_keys("selenium")
# time.sleep(2)
# driver.find_element_by_xpath("//form[@id='form']/span[2]/input").click()
# time.sleep(2)
driver.quit()
5、通过下标定位[]
在HTML问答结构树中,如果两个相同标签处于同一级别,则为兄弟节点,兄弟节点间是按照序号排列的:
- 同名的第一个节点序号为1,默认可以不写或[1]
- 从第二个同名节点开始必须写,序号为2,写为[2]
- 往后依次类推
下图的同名节点共6个,圈出来的是老二(排序第二,可以使用[2]表示),如果直接使用class属性进行定位的话,这六个节点的class属性都一样,是没办法定位的,但是如果我们给其指定序号就可以啦。
from time import sleep
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.baidu.com/')
#使用下标的方式定位第二个相同属性的兄弟标签
driver.find_element_by_xpath("//a[@class='mnav c-font-normal c-color-t'][2]").click()
sleep(1)
driver.quit()
6、通过.和..选取当前节点或者父节点定位
- /.:表示当前节点的标签元素
- /..:表示上一级节点的标签元素
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.baidu.com/')
#使用下标的方式定位第二个相同属性的兄弟标签
#并且使用/.表示当前节点,仍然点hao123的页面
#driver.find_element_by_xpath("//a[@class='mnav c-font-normal c-color-t'][2]/.").click()
#并且使用/..表示链接的上一层标签,但其默认使用了百度视频的链接
driver.find_element_by_xpath("//a[@class='mnav c-font-normal c-color-t'][2]/..").click()
linkText = driver.find_element_by_xpath("//a[@class='mnav c-font-normal c-color-t'][2]/..").text
#新闻hao123地图视频贴吧学术更多
print(linkText)
time.sleep(5)
driver.quit()
7、通过链接文本定位
对于链接或者按钮上显示的文本信息,是可以通过text()进行定位的。
//a[text()='hao123']:表示该页面下文本信息为hao123的链接
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.baidu.com/')
#使用文本信息定位
driver.find_element_by_xpath("//a[text()='hao123']").click()
time.sleep(3)
driver.quit()
8、通过模糊定位
对于链接或者按钮上显示的文本信息的局部信息,是可以通过contains()结合其他属性进行定位的。
//a[contains(@name,'hao')]:表示该页面下name属性包括hao的链接
//a[contains(text(),'hao')]:表示该页面下文本信息属性包括hao的链接
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.baidu.com/')
#模糊定位方式
# driver.find_element_by_xpath("//a[contains(@name,'hao')]").click()
driver.find_element_by_xpath("//a[contains(text(),'hao')]").click()
time.sleep(3)
driver.quit()
9、直接浏览器复制
在Chrome浏览器中的百度页面,鼠标右键选择“检查”,在element页面使用定位功能,点击页面上某元素,然后在element中就会定位到相应的标签行上,选中该行右键鼠标,选择copy->copy xpath。
复制出来的xpath表达式如下:
- //input[@id="kw"]
- //*[@id="u1"]/a[2]
大家要是觉得对自己有帮助的话,就点赞、喜欢、收藏下该文,鼓励一下作者!!!
关注作者、专栏,可方便查阅后续整理的测试相关文章,您的关注是我持续创作的动力!!!
【原创文章 全文手打 转载请联系作者】