selenium_webdriver高级运用
[TOC]
本文是学习了《Selenium自动化测试完全指南》和其他网络上的教程写出的学习笔记
selenium的等待机制
人们在手工测试网站时,总会自然而然地等待网页加载完毕再进行操作。如果某个局部区域是由Ajax加载的内容,人们要等待局部加载完毕才能进行下一步操作,而不是在空白或残缺的界面上操作。另一方面,如果等待超过一定时间,但页面或局部区域依然没有加载完毕,那么人们很可能将其标记为一处程序错误,要求开发人员去排查这个问题。
Selenium拥有丰富的等待机制,将原本人为的等待转换为由机器去等待,并判断什么时候该进行下一步操作
页面级等待机制
等待页面加载完毕的超时时间,默认为0
1 | wd.set_page_load_timeout(最长等待秒数) |
元素级等待机制
现代网站大多数是Ajax型网站,很多页面元素都不再是页面加载完毕就能显示出来,而是要触发特定区域的操作,然后等待目标元素出现在页面上才能进行下一步操作。
1 | # 方法一:强制等待 |
Selenium预定义等待条件函数
1 | from selenium.webdriver.support import expected_conditions |
脚本级等待机制
在Selenium中,可以使用execute_async_script函数来执行异步JavaScript脚本,如果异步JavaScript脚本没有指定回调函数或者超过时间期限仍然没有调用回调函数,那么JavaScript脚本可能超时
1 | # 异步超时时间 |
对键盘和鼠标进行精准模拟
ActionChains操作链
ActionChains操作链:一种偏向底层的自动化交互方式,它可以实现鼠标移动、单击、右击、双击、鼠标按下或松开、悬停拖曳、按键按下或松开、按组合键等更复杂的操作。
1 | from selenium.webdriver.common.action_chains import ActionChains |
操作链中包含两种类型的函数,第一种类型是操作设置函数,第二种类型是操作链执行函数(只有一个perform函数)。在调用perform时,将连续执行之前在操作链中设置的操作,然后结束操作链。
1 | ActionChains(wd).click(webElement).perform() |
ps: 操作链中涉及的所有WebElement元素在操作链执行时必须同时存在,且处于可操作状态,否则无法执行操作链
ActionChains支持的全部鼠标与键盘操作
函数名称 | 参数 | 功能 |
---|---|---|
click | element(目标元素可选) | 单击,如果没传入目标元素参数,则会单击当前位置 |
context_click | element(目标元素,可选) | 右键单击 |
double_click | element(目标元素,可选) | 双击 |
click_and_hold | element(目标元素,可选) | 单击按住 |
release | 释放 | |
move_to_element | element | 移动到目标元素 |
键盘操作
1 | from selenium.webdriver.common.keys import Keys |
ps: send_keys就足以胜任组合键操作,但它只支持按下操作,如果要实现精准控制,例如对某个键需要按下多少秒再松开,则只能使用ActionChains进行模拟,通过key_down、pause、key_up来精准控制某个键需要按下多少秒。
操作浏览器Cookie
Selenium支持操作浏览器Cookie,包括Cookie的读取、新增和删除。
1 | # 读取 |
对浏览器窗口或元素截图
1 | # 对浏览器窗口截图 |
为Selenium操作附加自定义事件
EventFiringWebDriver
EventFiringWebDriver,它可以为各类操作添加事件
1 | from selenium.webdriver.support.event_firing_webdriver import EventFiringWebDriver |
AbstractEventListener
函数 | 参数 | 作用 |
---|---|---|
before_navigate_to(self,url,driver) | url: 跳转的目标地址 | 导航前事件,页面在发生跳转前执行的代码 |
after_navigate_to(self,url,driver) | driver: wd实例 | 导航后事件,页面跳转后 |
before_navigate_back(self,driver) | driver: wd实例 | 浏览器后退事件,后退操作前执行的代码 |
after_navigate_back(self,driver) | driver: wd实例 | 浏览器后退事件,后退操作后执行的代码 |
before_navigate_forward(self,driver) | driver: wd实例 | 浏览器前进事件,前进操作前执行的代码 |
after_navigate_forward(self,driver) | driver: wd实例 | 浏览器前进事件,前进操作后执行的代码 |
before_close(self,driver) | … | 浏览器关闭事件,关闭前 |
after_close(self,driver) | … | 浏览器关闭事件,关闭后 |
before_find(self,by,value,driver) | by表示查找条件类型 | 查找元素前事件 |
after_find(self,by,value,driver) | value表示查找值 | 找到元素后事件 |
before_click(self,element,driver) | element表示操作的元素 | 单击元素前事件 |
after_click(self,element,driver) | … | 单击元素后事件 |
before_change_value_of(self,element,driver) | … | 元素值变更前事件 |
after_change_value_of(self,element,driver) | … | 元素中变更后事件 |
before_excute_script(self,script,driver) | script表示需要执行的脚本 | 脚本执行前事件 |
after_excute_script(self,script,driver) | … | 脚本执行后事件 |
EventFiringWebElement
元素级自定义事件
1 | from selenium.webdriver.support.event_firing_webdriver import EventFiringWebElement |
浏览器启动参数设置
在创建WebDriver实例时,可以配置它的启动参数以进行一些初始设置。这些设置将会在WebDriver的整个生命周期内生效。
1 | wd = webdriver.Chrome(executable_path='chromedriver', port=0, options=None, |
参数 | 作用 | 描述 |
---|---|---|
options | 启动选项,自定义浏览器选项 | 例如启用或禁用浏览器的特定功能,设置浏览器窗口的大小,配置代理服务器等。 |
desired_capabilities | 类似于options | 主要在早期版本的Selenium中使用 |
chrome_options | 完全等同于options | 该参数是早期版本Selenium使用的参数,现在的版本已不推荐使用 |
executable_path | 浏览器驱动程序路径 | chrome.exe,如果没有指定,则默认使用环境变量PATH中设置的路径。 |
service_args | 浏览器驱动程序的参数 | 可以通过chromedriver –help命令查看驱动程序支持的参数 |
port | 驱动程序启用的端口号 | 如果不填写,则自动使用任意闲置的端口号。等同–port参数。 |
service_log_path | 驱动程序存放日志文件的地址 | 完全等同于chromedriver命令中的–log-path参数。 |
keep_alive | 是否带上HTTP请求头 | Connection: keep-alive,即是否使用长连接。(该参数为布尔类型,默认值为True)。 |
1 | from selenium.webdriver.chrome.options import Options |
通过JavaScript执行器进行深度操作
虽然Selenium支持非常丰富的操作,但还是会遇到极少数无法处理的场景。此时可能需要使用JavaScript执行器来扩展Selenium。
1 | # 执行 |
执行同步脚本
返回值与类型转换
execute_script函数的返回值类型会随JavaScript脚本返回值动态改变
1 | >------返回值为None的情况------ |
ps: 一般来说,不建议通过JavaScript来执行Selenium已经支持的功能。
传入参数
execute_script函数还支持输入参数,然后在JavaScript脚本中通过arguments[0]、arguments[1]等使用这些参数。
1 | from selenium import webdriver |
执行异步脚本
在使用该函数时,虽然JavaScript是异步处理的,但是Selenium脚本是同步执行的。如果Selenium回调函数没有执行,那么execute_async_script函数会处于阻塞状态,只有Selenium回调函数执行后才会执行下一行代码。