对于很多测试工程师做UI自动化时,都只会简单的copy xpath/copy full xpath,并不会灵活的使用元素定位。这篇文章来介绍八大元素定位,并详细介绍Xpath定位方式。
至于为什么要学习元素定位,因为UI自动化(Selenium/Appium等)都是通过模拟人来完成的操作,人工来完成操作时,能够通过肉眼来识别元素的具体位置并完成点击和输入等操作,但是机器是不知道元素的具体位置的,所以需要学习元素定位,来让机器知道元素的具体位置。
1、八大元素定位
WebDriver提供了八大元素定位,如下图所示
方法 | 用法 | 特性 |
---|---|---|
id | driver.find_element_by_id() | 唯一:HTML文档中id必须唯一 |
Name | driver.find_element_by_name() | 元素名称,可以不唯一 |
class Name | driver.find_element_by_class_name() | 元素的类名,用法与id、name类似,通过class属性来定位 |
tag Name | driver.find_element_by_tag_name() | 标签名 |
link text | driver.find_element_by_link_text() | 专门用来定位文本链接,一般为href = 'www.baidu.com’这种类型 |
partial link text | driver.find_element_by_partial_link_text() | 取文本链接其中的一部分(唯一标识:只要这部分信息可唯一标识这个链接即可) |
xpath | driver.find_element_by_xpath() | 主要用标签名的层级定位关系来定位 |
css | driver.find_element_by_css_selector() | 通过class属性定位 、通过id属性定位(父子关系、属性、组合定位等等) |
2、详细介绍Xpath定位
其实八大元素定位,大家可以从Xpath和Css中选择一种进行精通就好了。与其都会一点,不如精通一种定位方式。笔者所了解的是,基本上Xpath定位可以定位到所有的元素,并且大部分企业实际工作中都使用的是Xpath定位。
2.1 绝对路径(full xpath)
- 1、绝对路径定位 locator = ‘/html/body/div/div/div/div/div[3]/div[2]/form/div[1]/div/div/div/div/input’;
- 2、合法的绝对路径一定是以/html开头;
- 3、使用绝对路径定位时,就是从最/html级开始一层一层往下面定位,直到定位到需要的元素所在层级为止;
2.2 相对路径(xpath)
- 1、相对路径定位 locator_1 = ”//input[@place=‘账号登录’]” 表示input标签下有place属性值等于‘账号登录’,中括号里面代表筛选条件;
- 2、‘//’ 两斜杠代表下面所有的节点
- 3、xpath相对路径定位详细用法如下图
使用符 | 用法 | 含义 |
---|---|---|
and | locator= “//input[@place=“账号登录” and @class=‘ant-input’]” | 一个属性定位不到时,可以使用该标签的两个属性进行定位 |
/. | locator= ‘//input[@place=“账号登录”]/.’ | /后面一个点,代表当前定位层级 |
/… | locator= ‘//input[@place=“账号登录”]/…’ | /后面两个点,代表当前定位层级的上一级 |
* | locator = '//*[@place=“账号登录”] | * 通配符,表示任意标签匹配 |
contains() | //input[contains(@place,‘登录’)] | 表示包含,可以进行模糊匹配,只需要place属性含有‘登录’字样即可定位到,一般用于属性有一部分容易发生改变时,常用于text文本的定位 |
2.3 总结
- 1、@符号只能用于属性前,不能用于标签等其他地方
- 2、不推荐使用绝对定位,推荐使用相对定位,因为路径层级容易发生改变
3、element和elements定位的区别以及用法?
同样以xpath为例
3.1 element定位
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
# xpath定位百度输入框
element = driver.find_element_by_xpath("//input[@id='kw']")
# 打印对象的类型
print(type(element))
输出---------
<class 'selenium.webdriver.remote.webelement.WebElement'>
- 1 、element 定位得到的是一个element对象
- 2、只适用于查找一个符合要求的元素,返回一个对象,并可完成对象的操作。比如clink(),send_key()等等
3.2 elements定位
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
# xpath定位百度输入框
elements = driver.find_elements_by_xpath("//input[@id='kw']")
# 打印对象的类型
print(type(elements))
输出-----------
<class 'list'>
- 1、elements定位得到是一个列表
- 2、如果查找在网页中有多个满足条件的节点,find_element就只能得到第一个节点,所以查找多个节点,就需要使用find_elements
4、By类定位元素
用By定位元素(WebDriver统一调用find_element()方法),通过By来声明定位方法,并且传入对应定位方法的定位参数。
# 导入By包
from selenium.webdriver.common.by import By
driver.find_element(By.id,"kw")
driver.find_element(By.name,"wd")
driver.find_element(By.class_name,"s_ipt")
driver.find_element(By.tag_name,"input")
driver.find_element(By.link_text,"新闻")
driver.find_element(By.partial_link_text,"新")
driver.find_element(By.xpath,"//*[@class='bg s_btn'")
driver.find_element(By.css_selector,"span.bg s_btn_wr>input#su")
注意:大家是不是发现通过By来定位元素方便很多,也很简单
1、find_element() 方法要传入两个参数,第一个参数是参数的定位类型,由By类提供,第二个参数是参数定位的具体方式
2、通过By定位,在项目实战过程中,往往元素定位与元素操作代码是分离的,往往每个页面所有的元素定位都集中管理,那么每当元素定位需要改动时,那我们无需改动element里面的代码。
locator = (By.xpath,"//*[@class='bg s_btn'")
# 使用ele来接收这个返回的对象,*号代表拆包,将locator元组,拆成两个参数传进去即可
ele = driver.find_elemet(*locator)
所以项目实战中一般推荐大家使用By来定位,可以很方便的管理以及分离元素定位以及元素操作相关的代码,方便后续维护。
好了!今天的博客就分享到这,谢谢大家!
有什么问题,欢迎大家评论区评论交流!谢谢大家!
后续博客会继续分享元素操作以及driver的操作,以及js操作等等内容—