自动化测试工具selenium常规元素定位方式、特殊元素定位方式、3种等待时间使用

113 阅读8分钟

一、标签元素的定位和操作

1、元素的定位

•⼋种策略、两套⽅法(单/多)、⻓款和短款⽅法名⻛格

1.1 单元素定位 —— find_element

•单元素定位的特点

。单元素定位的⽅法的返回值是 WebElement 类型的,代表找到的⻚⾯上的标签元素对象。
。如果⻚⾯上没有匹配条件的元素,会因为没有找到元素⽽报错(NoSuchElementException)
。如果⻚⾯上有多个匹配条件的标签元素,只返回第1个标签元素
。尽量根据标签上的唯⼀特征进⾏定位

•单元素定位的⽅法

。dr.find_element_by_id("id属性值") —— 根据标签上的id属性
。dr.find_element_by_name("name属性值") —— 根据标签上的name属性
。dr.find_element_by_class_name("class属性值") —— 根据标签上的class属性
。dr.find_element_by_tag_name("标签名") —— 根据标签名
。dr.find_element_by_link_text("链接⽂本") —— 根据超链接标签的⽂本
。dr.find_element_by_partial_link_text("部分链接⽂本") —— 根据部分超链接⽂本
。dr.find_element_by_css_selector("CSS选择器表达式") —— 根据CSS选择器
。dr.find_element_by_xpath("XPATH表达式") —— 根据XPATH表达式

1.2 多元素定位(使⽤场景⽐单元素定位少得多)—— find_elements

•多元素定位的特点

。多元素定位的⽅法的返回值是 list 列表类型的,代表找到⻚⾯上的⼀组标签元素的容器,列表中每个元素的类型是 WebElement 。
。如果⻚⾯上没有匹配条件的元素,不会报错,只是列表的⻓度为0,列表为空 [] 。

•多元素定位的⽅法

。dr.find_elements_by_id("id属性值") —— 根据标签上的id属性
。dr.find_elements_by_name("name属性值") —— 根据标签上的name属性
。dr.find_elements_by_class_name("class属性值") —— 根据标签上的class属性
。dr.find_elements_by_tag_name("标签名") —— 根据标签名
。dr.find_elements_by_link_text("链接⽂本") —— 根据超链接标签的⽂本
。dr.find_elements_by_partial_link_text("部分链接⽂本") —— 根据部分超链接
⽂本
。dr.find_elements_by_css_selector("CSS选择器表达式") —— 根据CSS选择器
。dr.find_elements_by_xpath("XPATH表达式") —— 根据XPATH表达式

1.3 使⽤By类和短款⽅法名⻛格的元素定位⽅法

•在selenium4的版本开始,不推荐使⽤⻓款的⽅法名⻛格定位元素

•推荐使⽤By类(元素定位的策略类)结合短款的⽅法名⻛格定位元素

。By.ID 、 By.NAME 、 By.CLASS_NAME 、 By.TAG_NAME 、 By.LINK_TEXT
。By.PARTIAL_LINK_TEXT 、 By.CSS_SELECTOR 、 By.XPATH
。注意:By类是selenium定义的类,需要导⼊: from selenium.webdriver.common.byimport By

•短款⽅法名⻛格的元素定位⽅法

。dr.find_element(By.XXX, "值")
。dr.find_elements(By.XXX, "值")

2、元素的操作

2.1 对标签元素的理解

•⻚⾯上的标签元素,在selenium体系下,被封装定义成了 WebElement 类—— 标签元素类

•⻚⾯上的每⼀个标签元素都是 WebElement 类的对象实例

2.2 标签元素的常⽤操作

•标签元素.send_keys("⽂本") —— 向标签元素中输⼊⽂本内容

•标签元素.click() —— 单击标签元素

•标签元素.clear() —— 清空⽂本框中的⽂本

•标签元素.get_attribute("标签属性名") —— 获取标签上指定属性的值

•标签元素.text —— 获取标签元素的⽂本(双标签之间的⽂本)

二、PATH表达式

1. 对xpath表达式的理解

•selenium只是借助了xpath表达式来定位元素

•xpath最早是应⽤于XML⽂件中定位标签元素的⼀套表达式,使⽤路径⻛格的分隔符表示标签的层级。

。XML和HTML的区别
□XML(extensible markup language)的标签是编写者⾃定义的,HTML的标签是预定义好的。
□XML的标签不是为了让浏览器渲染的,也不是为了展示数据,⽽是传输、存储数据的。
□HTML的标签是为了让浏览器选择展示数据的。
。XML的实例⽂件代码
<company>
<name>成都中⼼</name>
<address>成都市锦江区东⼤街</address>
<classes>
<class id="c073434">
<name>169期</name>
<master>小明</master>
<open>2022-3-5</open>
</class>
<class id="c073430">
<name>170期</name>
<master>小红</master>
<open>2022-3-14</open>
</class>
</classes>
</company>

•完全可以将HTML看作⼀个XML的特定实例,让XPATH去定位HTML⽂件中的标签

2. xpath的路径

•xpath表达式的路径永远从整个⽂档的“根”(根标签之前)开始计算的

•xpath表达式必须要有节点路径

•xpath中的路径分隔符

。/ —— 进⼊到当前节点的下⼀级
。// —— 进⼊到当前节点的下任意多级
。.. —— 进⼊到当前节点的上⼀级

3. xpath的谓语(筛选条件)

•谓语:对满⾜路径节点的标签元素进⼀步筛选的条件,谓语不能单独作为xpath表达式,必须要有路径节点

•语法: /xxx[谓语] 、 //xxx[谓语]、//✲[谓语]

3.1 可以在谓语中使⽤标签属性

•语法: @属性名

//p[@class="zz"] 匹配任意节点下的p标签,但p标签上必须有class="zz"属性 

3.2 可以在谓语中使⽤⼦标签在其⽗标签下的排⾏顺序(是从1开始计数的,不⽀持负数)

•语法: N

//p[2] 匹配任意节点下的p标签,但它必须是其⽗标签下的所有p标签中的第2个

3.3 可以在谓语中使⽤丰富的XPATH的内置函数

•last() —— 匹配最后⼀个⼦元素

•position() —— 返回⼦标签在其⽗标签下的排⾏顺序(是从1开始计数的)

•text() —— 获取标签元素的内部⽂本(开始标签跟结束标签之间的⽂本)

•contains(A, B) —— 匹配A包含B的的元素

//p[last()] 匹配任意节点下的p标签,但它必须是其⽗标签下的所有p标签中的最后1个
//p[position()=2] 匹配任意节点下的p标签,但它在其⽗标签下所有的p标签中的排⾏必须等于2
//p[position()!=1] 匹配任意节点下的p标签,但它在其⽗标签下所有的p标签中的排⾏必须不等于1
//a[text()='帮助'] 匹配任意节点下的a标签,但它的内部⽂本必须等于“帮助”
//a[contains(text(), 'Pow')] 匹配任意节点下的a标签,但它的内部⽂本必须包含“Pow”

3.4 可以使⽤丰富的运算符

•关系运算符 —— = != > >= < <=

•算术运算符 —— + - * div mod

•逻辑运算符 —— and or not()

4. xpath中的“轴”

•当我们很难直接定位到⽬标元素时,我们可以先定位到跟⽬标元素相近的相关元素,再以这个相关元素为轴,进⾏某种⽅向的偏移,偏移到⽬标元素。本质上轴就是⼀种偏移关系。

•具体的轴实例

。preceding-sibling:: —— 同级之前轴
。parent:: —— ⽗级(上⼀级)轴
。following-sibling:: —— 同级之后轴
。……

三、使⽤Select 类操作⻚⾯上的下拉选择框

1. 对Select类的理解

•Selenium定义了Select类,代表⻚⾯上的select标签元素(下拉选择框)。

•创建Select类对象实例,调⽤⽅法,来选中下拉框中的选项。

•在创建Select类的对象实例时,需要传⼊定位到的⻚⾯上的select标签元素对象。

2. 选中选项的三个⽅法

# 选中⽂本为“硕⼠”的选项
Select(dr.find_element(By.ID, "edu")).select_by_visible_text("硕⼠")

# 选中value为“xx”的选项
Select(dr.find_element(By.ID, "edu")).select_by_value("xx")

# 选中索引为3(第4个)的选项
Select(dr.find_element(By.NAME, "edu")).select_by_index(3)

四、调⽤ dr.switch_to.alert.xxx 来操作⻚⾯上的JS对话框

1. 使⽤场景

•当⻚⾯上弹出了JS对话框,因为它不是标签元素,所以⽆法定位。

2. ⼀个属性和三个⽅法

dr.switch_to.alert.text # 获取对话框上的提示⽂本
dr.switch_to.alert.accept() # 点击对话框上的“确定”按钮
dr.switch_to.alert.dismiss() # 点击对话框上的“取消”按钮
dr.switch_to.alert.send_keys("⽂本")  # 向对话框上的输⼊框中输⼊⽂本

五、调⽤dr.switch_to.frame(XX) 将驱动对象切换到指定框架内

1. 使⽤场景

•当要定位的元素在 frame 或 iframe 标签(这些就是框架标签)⾥,我们⽆法直接定位到框架内部的元素,因此需要先将驱动对象(dr)切换进⼊到指定的框架内部,再定位元素

2.将驱动对象切换到框架内部

•dr.switch_to.frame(框架特征)

•框架特征:

。可以传⼊框架标签的id或name属性(这跟元素定位⽆关,切换框架的特征,只能⽤id和name)
。可以传⼊框架标签的索引(在外部⻚⾯所有框架标签中的排⾏顺序,从0开始编号)

•注意点:

。firefox浏览器切换框架有bug,请使⽤Chrome浏览器。

3. 将驱动对象切换到外部⻚⾯

•dr.switch_to.default_content() —— 切换到最外部⻚⾯

•dr.switch_to.parent_frame() —— 切换到上⼀级⻚⾯

六、使⽤ ActionChains 完成⼀些特殊的⿏标操作

1. 代码的套路

from selenium.webdriver import ActionChains
ActionChains(驱动).操作1(元素).操作2(元素).操作N(元素).perform()

2. ⿏标操作的⽅法

•double_click(元素) —— 双击元素

•move_to_element(元素) —— 移动到元素上

•context_click(元素) —— 右键点击元素

•click_and_hold(元素) —— 点住元素不放

•release() —— 放开⿏标

•……

七、三种等待

1. 强制等待

•调⽤ sleep 函数,让程序休眠指定的时⻓

•sleep函数使⽤的场景最多,但有⼀个确定是必须事先确定⼀个固定的休眠时⻓。

2. 隐式等待(智能等待 —— 等待到元素出现就不等了)

•调⽤驱动对象的 implicitly_wait ⽅法,事先设定⼀个最⼤的等待时⻓(秒),调⽤这个⽅法的时候,程序不会暂停,这只是⼀个设置。

•影响的是使⽤该驱动对象在后续定位元素时,可能因为元素不存在,⽽等待元素的出现。

。如果元素出现了,就结束等待,直接返回这个元素。
。如果元素⼀直不出现,超过了实现设定的最⼤等待时⻓,程序会报错。

•隐式等待只需要设置⼀次,后续⽤该驱动对象定位元素的所有⽅法都会受影响。

dr.implicitly_wait(10)  # 设置隐式等待的最⼤时⻓为10秒

3. 显式等待(智能等待—— 等待到元素出现就不等了)

•如果使⽤显式等待定位元素的⽅法,就不使⽤传统定位元素的⽅法(find_element)

•使⽤WebDriverWait类对象的until⽅法,等待元素的出现

•想等待哪个元素,才对哪个元素调⽤显式等待定位的⽅法

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.expected_conditions import
presence_of_element_located
# 定位元素了,以等待的⽅式 —— 显式等待
element = WebDriverWait(dr, 10).until(presence_of_element_located((By.ID,"cont")))
print(element.text)