自己总结: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已经存在的内容。

相关推荐
suimeng611 小时前
ChromeDriver的常用方法
java·selenium
niuniu_66617 小时前
Selenium 性能测试指南
selenium·测试工具·单元测试·测试·安全性测试
莓事哒17 小时前
selenium和pytessarct提取古诗文网的验证码(python爬虫)
爬虫·python·selenium·测试工具·pycharm
suimeng619 小时前
基本元素定位(findElement方法)
java·selenium
mywpython20 小时前
mac 最新的chrome版本配置selenium的方式
chrome·python·selenium·macos
软件测试曦曦20 小时前
如何使用Python自动化测试工具Selenium进行网页自动化?
自动化测试·软件测试·python·功能测试·测试工具·程序人生·自动化
freejackman21 小时前
Selenium框架——Web自动化测试
python·selenium·测试
互联网杂货铺1 天前
黑盒测试、白盒测试、集成测试和系统测试的区别与联系
自动化测试·软件测试·python·功能测试·测试工具·单元测试·集成测试
Feng.Lee1 天前
聊一聊缓存如何进行测试
功能测试·测试工具·缓存
爱学测试的雨果1 天前
Postman —— postman实现参数化
软件测试·功能测试·测试工具·lua·postman