自己总结:selenium高阶知识

全篇大概10000字(含代码),建议阅读时间30min


一、等待机制

如果有一些内容是通过Ajax加载的内容,那就需要等待内容加载完毕才能进行下一步操作。

为了避免人为操作等待,会遇到的问题, selenium将等待转换为机器去等待,去判断在什么时间去进行下一步操作。

1.1 页面级等待机制

定义等待页面加载完毕的超时时间,默认设置为0表示等待时间不限。

set_page_load_timeout(最长等待秒数) 设置等待超时时间,全局设置,在WebDriver 生命周期内生效

python 复制代码
from selenium import webdriver

driver = webdriver.Chrome()
driver.set_page_load_timeout(3)
driver.get("https://www.selenium.dev/")
driver.quit()

等待时间设置为3秒,如果加载时间超过3秒,就会抛出异常。如果在3秒内加载完成,则执行下一行代码。

1.2元素级等待机制强制等待

也就是说有一些元素需要触发特定区域后才会显示,才能进行下一步操作。

这样就可以使用强制等待方式,通过 time库来进行等待。

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

driver.find_element(By.LINK_TEXT, "登录").click()
time.sleep(3)
driver.find_element(By.LINK_TEXT, "立即注册").click()
driver.quit()

不建议使用!

1.3 素级等待机制隐式等待

它是在执行函数时增加一些宽限时间,设置一个最长超出时间,如果在一定时间内元素还是没有出现,直接抛出异常、

implicitly_wait(等待秒数) 隐式等待

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.implicitly_wait(10)

driver.get("https://www.baidu.com")
driver.find_element(By.LINK_TEXT, "登录").click()
driver.find_element(By.LINK_TEXT, "立即注册").click()

driver.quit()

负作用:

  • 检查某元素是否不存在,等待隐式等待中设置最大时长,减缓测试速度。
  • 干扰显式等待。

1.4 元素及等待机制 显式等待

指定条件判断函数,每隔一定时间检测该条件是否成立。成立就执行下一步,直到超过最大等待时间。

from selenium.webdriver.support.wait import WebDriverWait 导入

WebDriverWait(WebDriver实例, 超时秒数, 检测时间间隔(可选), 可忽略异常集合(可选)) 实例化方法

检测时间间隔: 调用until 或until_not 中传入判断函数的间隔时间,默认0.5秒。

可忽略异常集合:调用until或until_not 中传入判断函数,如果抛出集合中定义的异常,代码不会执行失败,会继续正常执行。默认异常是 NoSuchElementException。

until 等待直到条件判断函数的返回值不为False。

until_not 等待直到条件判断函数返回值为False,如果抛出可忽略异常,会当做False处理。

使用自定义等待条件函数

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def registerLinkDisplayed(webDriver):
    # 检测是否已经显示立即注册链接
    return webDriver.find_element(By.LINK_TEXT, "立即注册").is_displayed()


driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

driver.find_element(By.LINK_TEXT, "登录").click()
# 每间隔0.5秒 去调用判断函数,条件满足执行下一行代码。
WebDriverWait(driver, 10).until(registerLinkDisplayed)
driver.find_element(By.LINK_TEXT, "立即注册").click()
driver.quit()

使用预定义等待条件函数

from selenium.webdriver.suport import expected_conditions 预定义等待函数

visibility_of_element_located() 判断目标元素是否处于可见状态

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

driver.find_element(By.LINK_TEXT, "登录").click()
targetLocator = (By.LINK_TEXT, "立即注册")
WebDriverWait(driver, 10).until(expected_conditions.visibility_of_all_elements_located(targetLocator))

driver.find_element(By.LINK_TEXT, "立即注册").click()

driver.quit()

预定义所有条件等待函数

|-----------------|---------------------------------------|--------------------------------------------------------|-------------------------------------------------------------------|
| 类别 | 函数名称 | 参数 | 功能 |
| 判断元素的可见性 | visibility_of_element_located | locator(目标元素定位) | 判断目标元素是否已显示,如果已显示,则返回该WebElement对象 |
| | visibility_of | webElement(目标元素) | 判断目标元素是否已显示,如果已显示,则返回该WebElement对象 |
| | visibility_of_all_elements_located | locator(目标元素定位) | 判断页面上是否存在一个或多个符合定位的元素,且是否已全部显示,如果是,则返回WebElement集合 |
| | visibility_of_any_elements_located | locator(目标元素定位) | 根据定位判断页面上是否存在一个或多个符合定位的元素,元素中是否至少有一个已先睡,如果是,则返回其中已显示的WebElement集合 |
| | invisibility_of_element_located | locator(目标元素定位) | 根据定位判断目标元素是否未显示 |
| 判断元素的状态、文本、值 | element_to_be_clickable | locator(目标元素定位) | 根据定位判断目标元素是否处于可单击状态 |
| | element_located_to_be_selected | locator(目标元素定位) | 根据定位判断目标元素是否处于已选中状态 |
| | element_to_be_selected | webElement(目标元素) | 判断目标元素是否处于已选中状态 |
| | element_located_selection_state_to_be | locator(目标元素定位),is_selected(期望状态) True(选中) False(未选中) | 根据定位判断选中状态是否符合预期 |
| | element_selection_state_to_be | webElement(目标元素),is_selected(期望状态) True(选中) False(未选中) | 判断目标元素选中状态是否符合预期 |
| | text_to_be_present_in_element | locator(目标元素定位), text(期望包含的文本) | 判断目标元素的文本是否包含期望的文本 |
| | text_to_be_present_in_element_value | locator(目标元素定位),text(期望包含的文本) | 判断目标元素的value属性是否已包含期望文本 |
| 判断元素是否存在 | presence_of_element_located | locator(目标元素定位) | 根据定位判断页面上是否存在首个符合定位元素,如果有,则返回该WebElement |
| | presence_of_all_elements_located | locator(目标元素定位) | 根据定位判断页面上是否存在一个或多个符合定位元素,如果有,则返回WebElement集合 |
| | staleness_of | webElement(目标元素) | 判断目标元素是否已经从DOM结构上完全消失 |
| 判断浏览器窗口、弹框及内嵌网页 | new_window_is_opened | current_handles(当前的窗口句柄集合) | 判断是否有新窗口打开,句柄数量是否会在当前句柄集合的基础上有所基础 |
| | number_of_windows_and_switch_to_it | locator(目标元素(IFrame/Frame)定位) | 根据定位判断是否可以切换到目标元素,如果可以切换,则会直接切换到指定元素(IFrame/Frame)上 |
| | alert_is_present | - | 判断是否已出现浏览器弹窗 |
| 判断网页标题或URL | title_contains | title(期望包含的标题) | 判断网页标题是否已包含期望的标题(即是否模糊匹配) |
| | title_is | title(期望相等的标题) | 判断网页标题是否完全等于期望的标题(即是否完全匹配) |
| | url_changes | url(当前URL) | 判断URL是否发生变化,即与当前的URL不相同 |
| | url_contains | url(期望包含的URL) | 判断URL是否已包含期望的URL(即是否模糊匹配) |
| | url_matches | pattern(格式表达式) | 判断URL是否匹配格式表达式(例如正则表达式) |
| | url_to_be | url(期望相等的URL) | 判断URL是否已包含期望的URL(即是否完全匹配) |

  1. 其他可选参数设置
python 复制代码
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common import exceptions

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

WebDriverWait(driver, 30, 2, [exceptions.NoSuchElementException, ZeroDivisionError])\
    .until(lambda p : 3/0, "很明显, 3是不能除以0的")

1.5 脚本级等待机制

driver.set_script_timeout(最长等待秒数) 为JavaScript设置超时时间

二、对键盘和鼠标进行精准模拟

ActionChains 偏向底层的自动化交互方式,实现鼠标移动、单击、右击、双击、鼠标按下或松开、悬停拖拽、按键按下或松开、按组合键等复杂的操作。

2.1 ActionChains 操作链

from selenium.webdriver.common.action_chains import ActionChains 引入模块使用库

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

ActionChains(driver).click(driver.find_element(By.LINK_TEXT, "登录")).perform()
# .click(...) 对操作进行设置,在操作链中预约了一个单击操作,操作对象是登录。
# .perform() 执行操作链中所有操作
driver.quit()

案例:鼠标悬停在设置菜单上,然后再弹出的菜单中选择搜索设置。最后在弹出的设置面板中按顺序进行不显示、仅繁体中文、显示、保存设置操作。

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()

driver.get("https://www.baidu.com")
# move_to_element会将鼠标指针放置在"设置"链接上,实现悬停效果
# pause(3) 等待秒
ActionChains(driver).move_to_element(
    driver.find_element(By.XPATH, "//span[text()='设置']"))\
    .pause(3).perform()
ActionChains(driver).click(driver.find_element(By.LINK_TEXT, "搜索设置"))\
    .pause(3).perform()
ActionChains(driver).click(driver.find_element(By.ID, "s1_2"))\
    .click(driver.find_element(By.ID, "SL_2"))\
    .click(driver.find_element(By.ID, "sh_1"))\
    .click(driver.find_element(By.LINK_TEXT, "保存设置"))\
    .pause(3).perform()

driver.quit()

2.2 ActionChains 鼠标与键盘操作设置

|----------|-----------------------------|---------------------------------------------------------|------------------------------------------|
| 类别 | 函数名 | 参数 | 功能 |
| 鼠标按钮操作设置 | click | element(目标元素,可选) | 单击目标元素,如果没有传入目标元素参数,会单击当前鼠标指针位置 |
| | context_click | element(目标元素,可选) | 右击目标元素,如果没有传入目标元素,会右击鼠标指针位置 |
| | double_click | element(目标元素,可选) | 双击目标元素,如果没有传入目标元素,会双击当前鼠标位置 |
| | click_and_hold | element(目标元素,可选) | 在目标元素长按鼠标按钮。如果没有传入目标元素,会在当前鼠标位置按下鼠标左键 |
| | release | element(目标元素,可选) | 在目标元素松开鼠标按钮。如果没有传入目标元素,则会在当前鼠标指针位置按下鼠标左键 |
| 鼠标移动操作设置 | move_to_element | element(目标元素) | 将鼠标指针移动到目标元素中间 |
| | move_to_element_with_offset | element(目标元素) ,x坐标,y坐标 | 将鼠标指针移动到相对目标元素的坐标(x,y) |
| | move_by_offset | x坐标,y坐标 | 将鼠标移动到相对于目标元素的坐标(x,y) |
| 鼠标综合性操作 | drag_and_drop | sourceElement(被拖放的元素), targetElement(要拖放到的目的地元素) | 在被拖放元素上按下鼠标按钮,然后移动到目标元素上松开鼠标 |
| | drag_and_drop_by_offset | sourceElement(被拖放的元素), targetElement(要拖放到目的地元素),x坐标,y坐标 | 在被拖放元素上按下鼠标按钮,然后移动到相距目标元素坐标x,y,并松开鼠标按钮 |
| 键盘按键操作设置 | send_keys | keys_to_send(要按的键钮) | 在当前焦点处输入 |
| | send_keys_to_element | element(目标元素),keys_to_send(要按的键钮) | 对目标元素按指定键 |
| | key_down | key(键),element(目标元素,可选) | 对目标元素按下指定键,如果没有传入目标元素,会在当前焦点位置按下指定键 |
| | key_up | key(键),element(目标元素,可选) | 对目标元素松开指定键,如果没有传入目标元素,则会在当前焦点位置松开指定键 |
| 等待设置 | pause | seconds(等待秒) | 在指定时间内暂停所有后续操作 |

reset_actions() 清空操作链中全部设置

2.3 模拟复杂键盘操作

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
baiduSearchInput = driver.find_element(By.ID, "kw")

baiduSearchInput.send_keys("python")
time.sleep(3)

baiduSearchInput.send_keys(Keys.CONTROL, "a")
time.sleep(3)
baiduSearchInput.send_keys(Keys.CONTROL, "x")
time.sleep(3)
baiduSearchInput.send_keys(Keys.CONTROL, "v")
time.sleep(3)
baiduSearchInput.send_keys(Keys.BACKSPACE)
time.sleep(3)
baiduSearchInput.send_keys(Keys.ENTER)

get_cookies() 获取所有cookie对象集合

get_cookie(cookie名称) 根据名称获取cookie

python 复制代码
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

# 获取全部cookies
pageCookies = driver.get_cookies()
for cookie in pageCookies:
    print(cookie)

# 根据名称获取cookie
print(driver.get_cookie("BD_HOME"))

3.1 新增和删除cookie

driver.add_cookie(cookie对象) 新增cookie

python 复制代码
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.add_cookie({'name': 'MockCookie', 'value': '小那同学'})

可以在浏览器F12调试工具中 Application查看当前添加的cookie

delete_all_cookies() 删除全部 cookie

delete_cookie(cookie名称) 按名称删除指定 cookie

python 复制代码
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

driver.delete_all_cookies()

3.2 对浏览窗口或元素截图

save_screenshot(截图文件保存路径) 对浏览器截图

python 复制代码
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

driver.save_screenshot("保存路径")

3.3 对元素截图

screenshot(截图文件路径)

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

driver.find_element(By.ID, "su").screenshot("图片地址")

3.4 Selenium操作附加自定义事件

from selenium.webdriver.support.event_firing_webdriver import EventFiringWebDriver 操作添加事件

EventFiringWebDriver(WebDriver实例,AbstractEventListener实例)

AbstractEventListener 抽象类,使用EventFiringWebDriver 需要设定自定义时间监听器类。

类需要继承 AbstractEventListener类。

|-------|-----------------------------------------|------------------------------------------------------|----------------------------------|
| 类别 | 函数名 | 参数 | 描述 |
| 浏览器级别 | before_navigate_to(url, driver) | url:跳转的目标URL driver:当前WebDriver实例 | 导航前事件,定义页面发生跳转前需要执行的代码 |
| | after_navigate_to(url, driver) | url: 跳转的目标URL driver:当前WebDriver实例 | 导航后事件,定义页面发生跳转后需要执行的代码 |
| | before_navigate_back(driver) | driver:当前WebDriver实例 | 浏览器后退前事件,定义浏览器在执行后退后需要执行的代码 |
| | after_navigate_forward(driver) | driver: 当前WebDriver实例 | 浏览器前进事件,定义浏览器在执行前进操作后需要执行的代码 |
| | after_navigate_forward(driver) | driver: 当前WebDriver实例 | 浏览器前进后事件,定义浏览器在执行关闭操作前需要执行的代码 |
| | before_close(driver) | driver: 当前WebDriver实例 | 浏览器关闭后事件,定义浏览器在执行关闭操作后需要执行的代码 |
| 元素级 | before_find(by, value, driver) | by: 当前使用的查找条件类型 value:当前使用的查找值 driver: 当前WebDriver实例 | 查找元素前事件,定义Selenium在查找元素前需要执行的代码 |
| | after_find(by, value, driver) | by: 当前使用的查找条件类型 value:当前使用的查找值 driver: 当前WebDriver实例 | 找到元素后事件,定义Selenium在找到元素后需要执行的代码 |
| | before_click(element, driver) | element: 要操作的元素 driver: 当前WebDriver实例 | 单击元素前事件,定义Selenium在单击元素前需要执行的代码 |
| | after_click(element, driver) | element: 要操作的元素 driver:当前WebDriver实例 | 单击元素后事件,定义Selenium在单击元素后需要执行的代码 |
| | before_change_value_of(element, driver) | element: 要操作的元素 driver:当前WebDriver实例 | 元素值变更前事件,定义Selenium更改元素需要执行的代码 |
| | after_change_value_of(element, driver) | element: 要操作的元素 driver: 当前WebDriver实例 | 元素值变更后事件,定义Selenium更改元素值后需要执行的代码 |
| 脚本级 | before_execute_script(script, driver) | script: 要执行的脚本 driver: 当前WebDriver实例 | 脚本执行前事件,定义脚本执行前需要执行的脚本 |
| | after_execute_script(script, driver) | script:要执行的脚本 driver:当前WebDriver实例 | 脚本执行后事件,定义脚本执行后需要执行的代码 |
| 异常或退出 | on_exception(exception, driver) | exception: 抛出的异常 driver:当前WebDriver实例 | 异常事件,定义在Selenium操作发生异常时需要执行的代码 |
| | before_quit(driver) | driver:当前WebDriver实例 | WebDriver退出会话前事件,定义在退出会话前需要执行的代码 |
| | after_quit(driver) | driver: 当前webDriver实例 | WebDriver退出会话后事件,定义在退出会话后需要执行的代码 |

四、浏览器启动参数设置

4.1 WebDriver 实例化参数

driver = webdriver.Chrome() 默认实例化没有参数

4.2 浏览器设置参数

options 启动选项,用于设置浏览器

desired_capabilities 类似于options, 在远程运行系统补丁或浏览器不定的情况下使用 desired_capabilities,推荐使用 options参数

chrome_options 等同于options参数,已过时不推荐使用

4.3 浏览器驱动程序设置参数

executable_path 浏览器驱动程序路径,没有指定,默认使用环境变量中的路径。

service_args 浏览器驱动程序参数。浏览器不同,参数也可能不相同。

port 驱动程序启用端口号,默认使用任意闲置端口号。

service_log_path 驱动程序存放日志文件地址。

4.4 selenium与浏览器驱动程序连接参数

keep-alive 表示与ChromeDriver连接时,是否带上HTTP请求头Connecton,默认值为True。

4.5 JavaScript 进行深度操作

虽然Selenium有丰富的操作,但是有一些场景可能需要使用JavaScript进行扩展。

webdriver.execute_script("js脚本", 自定义参数集(可选)) 执行同步脚本

webdriver.execute_async_script("js脚本", 自定义参数集(可选)) 执行异步脚本

不建议使用Js去执行selenium已经存在的内容。

相关推荐
qq_433716955 小时前
【接口自动化测试】一文从3000字从0到1详解接口测试用例设计
自动化测试·软件测试·功能测试·selenium·测试工具·测试用例·postman
steamedobun5 小时前
【爬虫】selenium打开浏览器以及页面
开发语言·python·selenium
川石课堂软件测试9 小时前
实用|金融银行项目测试业务流分析+常问面试题
功能测试·测试工具·金融·appium·自动化·压力测试
岑梓铭16 小时前
selenium自动爬虫工具
爬虫·selenium·测试工具
、、、、南山小雨、、、、17 小时前
tcpdump编译
网络·测试工具·tcpdump
小码哥说测试1 天前
Postman高阶技能:Collection集合批量运行!
自动化测试·软件测试·测试工具·jmeter·测试用例·postman·测试工程师
大霞上仙2 天前
selenium-ide web 自动化录制工具
ide·selenium·自动化
恩爸编程2 天前
Selenium WebDriver:自动化网页交互的利器
selenium·测试