Selenium
官网地址:
https://www.selenium.dev/文档地址:
https://www.selenium.dev/documentation/源码地址:
https://github.com/seleniumhq/selenium
Selenium 是一个包含一系列工具和库的统称,这些工具和库支持 web 浏览器的自动化。
它提供了用于模拟用户与浏览器交互的扩展、用于扩展浏览器分配的分发服务器,以及用于实现 W3C WebDriver 规范的基础设施,该规范允许您为所有主要 web 浏览器编写可互换的代码。
Selenium 的核心是 WebDriver,它是一个编写指令集的接口,可以在许多浏览器中交替运行。安装完所有内容后,只需编写几行代码即可进入浏览器。您可以在编写第一个 Selenium 脚本中找到一个更全面的示例。
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://selenium.dev")
driver.quit()
Selenium 不仅仅是一个工具或 API;它包括许多工具。
| 名称 | 说明 |
|---|---|
WebDriver |
如果您开始使用桌面网站或移动网站测试自动化,那么您将使用 WebDriver api。WebDriver 使用浏览器厂商提供的浏览器自动化 api 来控制浏览器并运行测试。这就好像是一个真正的用户在操作浏览器一样。由于 WebDriver 不需要用应用程序代码编译它的 API,所以它不是侵入式的。因此,您正在测试您推出的同一个应用程序 |
IDE |
集成开发环境(Integrated Development Environment,IDE)是用于开发 Selenium 测试用例的工具。它是一个易于使用的 Chrome 和 Firefox 扩展,通常是开发测试用例的最有效方法。它使用现有的 Selenium 命令在浏览器中为您记录用户的操作,并使用该元素的上下文定义的参数。这不仅节省了时间,而且是学习 Selenium 脚本语法的一种极好的方式 |
Grid |
Selenium Grid 允许您在不同平台上的不同机器上运行测试用例。触发测试用例的控制在本端,当测试用例被触发后,由远端自动执行。 在开发 WebDriver 测试之后,您可能需要在多个浏览器和操作系统组合上运行测试。这就是 Grid 出现的地方。 |
因为要进行爬虫开发工作,所以我们重点关注 WebDriver。
WebDriver 通过本地浏览器或者使用 Selenium 服务的远程机器模拟用户自动操控浏览器。它标志着浏览器自动化方面的一个飞跃。
Selenium WebDriver 是 W3C推荐标准:
WebDriver被设计成一个简单和更简洁的编程接口。WebDriver是一个紧凑的面向对象API。- 它有效地驱动浏览器。
安装
首先,您需要为自动化项目安装 Selenium绑定。库的安装过程取决于您选择使用的开发语言。通过检查 Selenium下载页面,以确保使用的是最新版本。每个 Selenium 版本支持的最小Python版本可以在 PyPi 上的 "Supported Python Versions" 中找到。
# Python
uv add selenium
第一个应用
首先导入并实例化:
from selenium import webdriver
driver = webdriver.Chrome()
然后开始访问页面:
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
通过以上代码,我们和该站点建立一个 Session 连接并获取请求页面的信息:
title = driver.title
将代码与浏览器的当前状态同步是使用 Selenium 的最大挑战之一。
如果你想定位要操作的元素和想和这个元素互操作的前提是你要确定该元素已经加载到页面上。
隐式等待不是一个好的解决方案,但它是这里最容易演示的,因此我们将使用它作为占位符。展示如何构建一个等待策略:
driver.implicitly_wait(0.5)
假设元素已经加载完成,现在我们来演示如果查找元素:
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
找到了元素,然后通过代码来修改元素的点击事件:
text_box.send_keys("Selenium")
submit_button.click()
我们再举个提取文本的例子:
message = driver.find_element(by=By.ID, value="message")
text = message.text
最后,结束这次的工作:
driver.quit()
会话
创建新会话符合 W3C创建会话的命令。会话是通过初始化一个新的 Driver类对象自动创建的。
每种计算机语言都允许使用以下类(或同等类)的参数创建会话:
- 通过
options配置会话的参数选项;默认用于本地,但也可用于远程。 - 某种形式的
HTTP客户端配置(不同语言的实现不同) - 侦听器
启动会话
# 使用Chrome浏览器,不同浏览器不同
driver = webdriver.Chrome(options=options)
关闭会话
driver.quit()
浏览器支持
WebDriver 支持目前主流的浏览器,包括 Chrome、Edge、FireFox、Internet Explore 和 Safari 等。因为各浏览器的特性,除了通用的支持外,针对不同的浏览器,还有特定的支持。
Chrome 浏览器
默认情况下,Selenium 4 与 Chrome v75 及更高版本兼容。注意 Chrome 浏览器版本和 chromedriver 版本必须与主版本保持一致。
Chrome 和 Chromium 独有的功能记录在 https://chromedriver.chromium.org/capabilities 页面上。
开始一个 Chrome 会话与基本定义的选项看起来像这样:
options = get_default_chrome_options()
driver = webdriver.Chrome(options=options)
参数
从上面代码中可以看到传入了配置参数,args 参数用于在启动浏览器时使用的命令行开关列表。有两个很好的资源可以用来研究这些论点:
- 用于工具的Chrome标志 :
https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md - Chromium命令行开关列表:
https://peter.sh/experiments/chromium-command-line-switches/
常用参数包括 --start-maximized、--headless=new 和 --user-data-dir=... 等。给 options 添加一个参数:
options.add_argument("--start-maximized")
指定浏览器位置
bin 参数可人工设定要使用的浏览器的本地执行路径。有了这个参数,你可以使用 chromedriver 来驱动各种基于 Chromium 的浏览器。
向选项中添加浏览器位置:
options.binary_location = chrome_bin
添加扩展
extensions 参数接受 crx 文件,通过该参数指定 crx 文件;对于未打包的目录,使用 load-extension 参数,正如本文中提到的。
添加一个扩展选项:
options.add_extension(extension_file_path)
保持浏览器连接
设置 detach 参数为 true ,只要不向驱动程序发送退出命令,在进程结束后保持浏览器打开。
options.add_experimental_option("detach", True)
剔除默认参数
Chromedriver 有几个默认参数用来启动浏览器。如果你不想添加这些参数,把它们传递给 excludeswitch。一个常见的例子是重新打开弹出窗口拦截器。在选项上设置排除的参数:
options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
日志输出到文件
更改日志输出以保存到指定文件:
service = webdriver.ChromeService(log_output=log_path)
日志输出到控制台
将日志输出更改为在控制台中显示:
service = webdriver.ChromeService(log_output=subprocess.STDOUT)
设定日志输出级别
有六个可用的日志级别:ALL、DEBUG、INFO、WARNING、SEVERE 和 OFF。注意,--verbose 相当于 --log-level=ALL,--silent 相当于 --log-level=OFF,所以这个例子只是一般地设置日志级别:
service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)
只有在记录到文件时才有两个功能:
- 添加日志
- 可读的时间戳
要使用它们,还需要显式指定日志路径和日志级别。日志输出将由驱动程序管理,而不是进程,因此可能会看到细微的差异。
service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)
禁用构建检查
Chromedriver 和 Chrome 浏览器版本应该匹配,如果不匹配,驱动程序将出错。如果您禁用构建检查,您可以强制驱动程序与任何版本的 Chrome 一起使用。请注意,这是一个不受支持的特性,不会调查错误。
service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)
特定特征 - Casting
你可以驱动 Chrome Cast 设备,包括共享标签:
sinks = driver.get_sinks()
if sinks:
sink_name = sinks[0]['name']
driver.start_tab_mirroring(sink_name)
driver.stop_casting(sink_name)
特定特征 - 网络条件
您可以模拟各种网络条件。
network_conditions = {
"offline": False,
"latency": 20, # 20 ms of latency
"download_throughput": 2000 * 1024 / 8, # 2000 kbps
"upload_throughput": 2000 * 1024 / 8, # 2000 kbps
}
driver.set_network_conditions(**network_conditions)
特定特征 - Logs
logs = driver.get_log("browser")
特定特征 - 权限
driver.set_permissions('camera', 'denied')
Edge 浏览器
这些是 Microsoft Edge 浏览器特有的功能和特性。
Microsoft Edge 是用 Chromium 实现的,支持的最早版本是 v79 。与 Chrome 类似,edgedriver 的主版本号必须与 Edge 浏览器的主版本号匹配。
options = get_default_edge_options()
driver = webdriver.Edge(options=options)
参数
从上面代码中可以看到传入了配置参数,args 参数用于在启动浏览器时使用的命令行开关列表。有两个很好的资源可以用来研究这些论点:
- 用于工具的Chrome标志 :
https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md - Chromium命令行开关列表:
https://peter.sh/experiments/chromium-command-line-switches/
常用参数包括 --start-maximized、--headless=new 和 --user-data-dir=... 等。给 options 添加一个参数:
options.add_argument("--start-maximized")
指定浏览器位置
bin 参数可人工设定要使用的浏览器的本地执行路径。有了这个参数,你可以使用 chromedriver 来驱动各种基于 Chromium 的浏览器。
向选项中添加浏览器位置:
options.binary_location = edge_bin
添加扩展
extensions 参数接受 crx 文件,通过该参数指定 crx 文件;对于未打包的目录,使用 load-extension 参数,正如本文中提到的。
添加一个扩展选项:
options.add_extension(extension_file_path)
保持浏览器连接
设置 detach 参数为 true ,只要不向驱动程序发送退出命令,在进程结束后保持浏览器打开。
options.add_experimental_option("detach", True)
剔除默认参数
Chromedriver 有几个默认参数用来启动浏览器。如果你不想添加这些参数,把它们传递给 excludeswitch。一个常见的例子是重新打开弹出窗口拦截器。在选项上设置排除的参数:
options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
日志输出到文件
更改日志输出以保存到指定文件:
service = webdriver.EdgeService(log_output=log_path)
日志输出到控制台
将日志输出更改为在控制台中显示:
service = webdriver.EdgeService(log_output=subprocess.STDOUT)
该功能要求 seleium v4.11 版本及以上。
设定日志输出级别
有六个可用的日志级别:ALL、DEBUG、INFO、WARNING、SEVERE 和 OFF。注意,--verbose 相当于 --log-level=ALL,--silent 相当于 --log-level=OFF,所以这个例子只是一般地设置日志级别:
service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)
只有在记录到文件时才有两个功能:
- 添加日志
- 可读的时间戳
要使用它们,还需要显式指定日志路径和日志级别。日志输出将由驱动程序管理,而不是进程,因此可能会看到细微的差异。
service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)
禁用构建检查
Chromedriver 和 Chrome 浏览器版本应该匹配,如果不匹配,驱动程序将出错。如果您禁用构建检查,您可以强制驱动程序与任何版本的 Chrome 一起使用。请注意,这是一个不受支持的特性,不会调查错误。
service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)
特定特征 - `Casting``
你可以驱动 Chrome Cast 设备,包括共享标签:
sinks = driver.get_sinks()
if sinks:
sink_name = sinks[0]['name']
driver.start_tab_mirroring(sink_name)
driver.stop_casting(sink_name)
特定特征 - 网络条件
您可以模拟各种网络条件。
network_conditions = {
"offline": False,
"latency": 20, # 20 ms of latency
"download_throughput": 2000 * 1024 / 8, # 2000 kbps
"upload_throughput": 2000 * 1024 / 8, # 2000 kbps
}
driver.set_network_conditions(**network_conditions)
特定特征 - Logs
logs = driver.get_log("browser")
特定特征 - 权限
driver.set_permissions('camera', 'denied')
FireFox 浏览器
这些是 Mozilla Firefox 浏览器特有的功能和特性。
Selenium 4 需要 Firefox 78 或更高版本。建议始终使用最新版本的 geckodriver。
Firefox 独有的功能可以在 Mozilla 的 https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions 页面上找到。
现在开始启动一个Firefox会话,如下所示:
options = webdriver.FirefoxOptions()
driver = webdriver.Firefox(options=options)
参数
args 参数用于在启动浏览器时使用的命令行开关列表。常用参数包括 -headless 和 -profile, /path/to/profile
给 options 添加一个参数:
options.add_argument("-headless")
指定浏览器执行程序位置
bin 参数可人工设定要使用的浏览器的本地执行路径。有了这个参数,你可以使用 chromedriver 来驱动各种基于 Chromium 的浏览器。
向选项中添加浏览器位置:
options.binary_location = edge_bin
Fprofiles
有几种方法可以使用Firefox配置文件。
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
options = Options()
firefox_profile = FirefoxProfile()
firefox_profile.set_preference("javascript.enabled", False)
options.profile = firefox_profile
driver = webdriver.Firefox(options=options)
注意:无论您是创建一个空的 FirefoxProfile 还是将其指向您自己的 Profile 文件的目录,Selenium 都将创建一个临时目录来存储新 Profile 文件的数据或现有 Profile 文件的副本。每次运行程序时,都会创建一个不同的临时目录。这些目录不会被 Selenium 显式地清除,它们最终会被操作系统删除。但是,如果你想手动删除副本(例如,如果你的配置文件很大),那么该副本的路径将由FirefoxProfile 对象公开。
如果希望使用现有的 Firefox 配置文件,可以传入该配置文件的路径。
日志输出到文件
更改日志输出以保存到指定文件:
service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
该功能有效,需要 Selenium v4.11 版本及以上。
日志输出到控制台
将日志输出更改为在控制台中显示:
service = webdriver.FirefoxService(log_output=subprocess.STDOUT)
该功能要求 seleium v4.11 版本及以上。
设定日志输出级别
有六个可用的日志级别:ALL、DEBUG、INFO、WARNING、SEVERE 和 OFF。注意,--verbose 相当于 --log-level=ALL,--silent 相当于 --log-level=OFF,所以这个例子只是一般地设置日志级别:
service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
截断日志
Webdriver 日志发送的所有内容,包括大型二进制文件的字符串表示,Firefox在默认情况下会截断行。关闭截断:
service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)
更改 Profile 配置根目录
Profile 文件的默认目录是系统临时目录。如果你没有访问该目录的权限,或者想要在某个特定的地方创建配置文件,你可以更改配置文件的根目录:
service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])
特定特征 - 安装附加组件
与 Chrome 不同,Firefox 扩展不是作为本问题中提到的功能的一部分添加的,它们是在启动驱动程序后创建的。
以下示例适用于本地 web 驱动程序。对于远程 web 驱动程序,请参考远程 web 驱动程序页面
driver.install_addon(addon_path_xpi)
卸载附加组件
卸载插件需要知道它的id。该id可以在安装附加组件时从返回值中获得。
driver.uninstall_addon(id)
未签名安装附加组件
当使用未完成或未发布的扩展时,它可能不会被签名。因此,它只能作为"临时"安装。这可以通过传入一个zip文件或一个目录来完成,这里有一个目录的例子:
driver.install_addon(addon_path_dir, temporary=True)
整页截图
以下示例适用于本地 web 驱动程序。对于远程 web 驱动程序,请参考远程 web 驱动程序页面。
driver.save_full_page_screenshot("full_page_screenshot.png")
上下文
以下示例适用于本地 web 驱动程序。对于远程 web 驱动程序,请参考远程 web 驱动程序页面。
with driver.context(driver.CONTEXT_CHROME):
driver.execute_script("console.log('Inside Chrome context');")
Safari 浏览器
这些是 Apple Safar i浏览器特有的功能和特性。
与 Chromium 和 Firefox 驱动程序不同,safardriver 是随操作系统一起安装的。要在 Safari 上启用自动化,从终端运行以下命令:
safaridriver --enable
参数
Safari 独有的功能可以在苹果关于 Safari的 https://developer.apple.com/documentation/webkit/about_webdriver_for_safari#2957227 页面上找到
首先启动一个 Safari 会话,如下所示:
options = webdriver.SafariOptions()
driver = webdriver.Safari(options=options)
打开/关闭日志
与其他浏览器不同,Safari 不允许您选择日志输出位置或更改级别。一个可用的选项是关闭或打开日志。如果日志被打开,它们可以在:~/Library/ logs /com.apple.WebDriver/找到。
service = webdriver.SafariService(enable_logging=True)
开发者工具
苹果提供了他们浏览器的开发版本。
options = webdriver.SafariOptions()
options.use_technology_preview = True
service = webdriver.SafariService(
executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
)
driver = webdriver.Safari(options=options, service=service)
IE 浏览器
IE 浏览器已经停用,在此不累述;感兴趣的可以自行学习。
同步策略
也许浏览器自动化最常见的挑战是确保 web 应用程序执行特定 Selenium命令时能够得到所需的状态。这些进程通常以竞争状态结束,有时浏览器首先进入正确的状态(事情按预期工作),有时 Selenium 代码首先执行(事情不按预期工作)。
在 Webdriver 将控制权返回给代码之前,所有导航命令都等待基于页面加载策略的特定 readyState值(默认为 complete)。readyState 只关注 HTML 中加载的资源,但是加载的 JavaScript 资源通常会导致站点的更改,并且当代码准备执行下一个Selenium 命令时,需要与之互动的元素可能还没有出现在页面上。
类似地,在许多单页面应用中,元素被动态地添加到页面中,或者根据点击情况改变可见性。只有元素已经加载并显示在页面上,Selenium 才能与之交互。
以https://www.selenium.dev/selenium/web/dynamic.html 页面为例,当 "Add a box!" 按钮点击后,则创建一个原本不存在的 "div" 元素。当单击 "Reveal a new input" 按钮时,将显示一个隐藏的文本输入框。在这两种情况下,转换都需要几秒钟。如果 Selenium 代码要单击其中一个按钮并与生成的元素交互,那么它将在该元素准备好并失败之前执行此操作。
好多人采用的第一个解决方案是添加一个 sleep 语句,将代码执行暂停一段时间。因为代码不能确切地知道它需要等待多长时间,所以当它等待时长不够时,这可能会失败。另外,如果该值设置得太高,并且在每个需要的地方都添加了 sleep 语句,那么会话的持续时间可能会变得令人望而却步。
Selenium提供了两种更好的同步机制:隐式同步策略(Implicit Waits) 和 显式同步策略(Explicit Waits)。
隐式同步策略
Selenium 有一种内置的方法来自动等待元素加载,称为"隐式等待"。隐式等待值可以通过浏览器选项中的超时功能设置,也可以通过 Webdriver 方法设置(如下所示)。
这是一个全局设置,适用于整个会话的每个元素位置调用。默认值是0,这意味着如果没有找到该元素,它将立即返回一个错误。如果设置了隐式等待,Webdriver 将在返回错误之前等待所提供值的持续时间。请注意,一旦元素被定位,Webdriver 将返回元素引用,代码将继续执行,因此较大的隐式等待值不一定会增加会话的持续时间。
警告:不要混合隐式和显式等待。这样做可能会导致不可预测的等待时间。例如,将隐式等待时间设置为10秒,将显式等待时间设置为15秒,可能会导致在20秒后发生超时。
用隐式等待来解决我们的例子是这样的:
driver.implicitly_wait(2)
显式同步策略
显式等待是添加到代码中的循环,它在应用程序退出循环并继续执行代码中的下一个命令之前,轮询应用程序以确定特定条件是否为真。如果在指定的超时值之前没有满足条件,代码将给出一个超时错误。由于有许多方法可以使应用程序不处于期望的状态,因此显式等待是一个很好的选择,可以在需要的每个位置指定要等待的确切条件。另一个很好的特性是,默认情况下,Selenium Wait类会自动等待指定的元素存在。
定制化
可以用各种参数实例化 Wait类,这些参数将改变条件的计算方式。包括:
- 更改代码的求值频率(轮询间隔)
- 指定应该自动处理哪些异常
- 更改总超时长度
- 自定义超时消息
例如,如果默认情况下重试了元素不可交互错误,那么我们可以在执行的代码中为方法添加一个操作(我们只需要确保代码成功时返回true):
errors = [NoSuchElementException, ElementNotInteractableException]
wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
wait.until(lambda _ : revealed.send_keys("Displayed") or True)
网页元素操作
文件上传
因为 Selenium 不能与文件上传对话框交互,所以它提供了一种不打开对话框就可以上传文件的方法。如果元素是类型为 file 的输入元素,则可以使用 send keys 方法发送要上传的文件的完整路径。
file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
file_input.send_keys(upload_file) # upload_file:要上传的文件的完整路径
driver.find_element(By.ID, "file-submit").click()
元素查找定位
识别 DOM 树中一个或多个特定元素的方法。
定位器是一种识别页面上元素的方法。它是传递给 Finding 元素方法的参数。Selenium 为 WebDriver 中的这8种传统位置定位策略提供了支持:
| 定位器 | 说明 |
|---|---|
By.CLASS_NAME |
定位元素类名中包含搜索值的元素(不允许使用复合类名) |
By.CSS_SELECTOR |
定位元素的 css 与 CSS 选择器匹配的元素 |
By.ID |
定位 ID与搜索值匹配的元素 |
By.NAME |
查找 NAME 属性与搜索值匹配的元素 |
By.LINK_TEXT |
定位其可见文本与搜索值匹配的锚元素 |
By.PARTIAL_LINK_TEXT |
定位其可见文本包含搜索值的锚(A)元素。如果有多个元素匹配,则只选择第一个元素。 |
By.TAG_NAME |
定位标记名称与搜索值匹配的元素 |
By.XPATH |
定位与 XPath表达式匹配的元素 |
通过 class 属性定位
HTML 网页元素可以有属性类。我们可以在上面显示的 HTML 片段中看到一个示例。我们可以使用 Selenium 中可用的类名定位器来标识这些元素。
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
element = driver.find_element(By.CLASS_NAME, "information")
通过 CSS 选择器定位
CSS 是用于样式化 HTML 页面的语言。我们可以使用 css选择器定位器策略来识别页面上的元素。如果元素有一个 id,我们创建定位符 css = #id。否则,我们遵循的格式是 css =[attribute=value]。让我们看看上面 HTML 片段中的一个例子。我们将使用 css 为名字文本框创建定位器。
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
element = driver.find_element(By.CSS_SELECTOR, "#fname")
通过 id 定位
我们可以使用网页中元素的 ID 属性来定位它。一般来说,对于网页上的每个元素,ID 属性应该是唯一的。
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
element = driver.find_element(By.ID, "lname")
通过 name 定位
我们可以使用网页中元素的 NAME 属性来定位它。一般来说,NAME 属性对于网页上的每个元素都应该是唯一的。
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
element = driver.find_element(By.NAME, "newsletter")
通过链接的文本定位
如果我们想要定位的元素是一个链接,我们可以使用链接文本定位器在网页上识别它。链接文本是链接显示的文本。
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")
通过链接的部分文本定位
如果我们想要定位的元素是一个链接,我们可以使用部分链接文本定位器在网页上识别它。链接文本是链接显示的文本。我们可以将部分文本作为值传递。
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")
通过 HTML 标签定位
我们可以使用 HTML TAG 本身作为定位器来识别页面上的 web 元素。
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
element = driver.find_element(By.TAG_NAME, "a")
通过 XPath 定位
可以将 HTML 文档视为 XML 文档,然后我们可以使用 xpath ,它将是遍历的路径,以到达感兴趣的元素以定位该元素。XPath 可以是绝对 XPath,它是从文档的根创建的。- /html/form/input[1]。这将返回男性单选按钮。xpath也可以是相对的。如 //input[@name='fname'],这将返回名字文本框。
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
element = driver.find_element(By.XPATH, "//input[@value='f']")
元素的属性和方法
is_displayed
此方法用于检查所连接的元素是否显示在网页上。返回一个布尔值,如果连接的元素显示在当前浏览上下文中则返回 True,否则返回False。
driver.get("https://www.selenium.dev/selenium/web/inputs.html")
# isDisplayed
is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
is_enabled
此方法用于检查在网页上是否启用或禁用了已连接的元素。返回一个布尔值,如果连接的元素在当前浏览上下文中启用,则返回 True,否则返回 False。
is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
is_selected
此方法确定引用的元素是否被选中。该方法广泛用于复选框、单选按钮、输入元素和选项元素。返回一个布尔值,如果引用的元素在当前浏览上下文中被选中,则返回 True,否则返回 False
is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
tag_name
它用于获取当前浏览上下文中具有焦点的引用元素的 TagName。
tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
位置和尺寸
它用于获取被引用元素的尺寸和坐标。获取的数据体包含以下详细信息:
-
从元素的左上角开始的
x轴位置 -
从元素的左上角开始的
y轴位置 -
元素的高度
-
元素的宽度
rect = driver.find_element(By.NAME, "range_input").rect
获取 css 值
检索当前浏览上下文中元素的指定计算样式属性的值。
css_value = driver.find_element(By.NAME, "color_input").value_of_css_property("font-size")
获取文本
检索指定元素的呈现文本。
text = driver.find_element(By.TAG_NAME, "h1").text
元素互动
用于操作表单控件的高级指令集。
在一个元素上只能执行5个基本命令:
click:点击。适用于任何元素。send_keys:发送键。仅适用于文本字段和内容可编辑元素。clear:清除。仅适用于文本字段和内容可编辑元素。submit:提交。仅适用于表单元素。select:选择。参见选择列表元素。
点击互动
# Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/inputs.html")
# Click on the checkbox
check_input = driver.find_element(By.NAME, "checkbox_input")
check_input.click()
发送键
元素send_keys命令将提供的键输到一个可编辑的元素中。通常,这意味着元素是具有文本类型的表单的输入元素或具有内容可编辑属性的元素。如果它不可编辑,则返回无效的元素状态错误。
# Handle the email input field
email_input = driver.find_element(By.NAME, "email_input")
email_input.clear() # Clear field
email = "admin@localhost.dev"
email_input.send_keys(email) # Enter text
清除
clear 命令用来重置元素的内容。这要求元素是可编辑和可重置的。通常,这意味着元素是具有 text 类型的表单的输入元素或具有content-editable 属性的元素。如果不满足这些条件,则返回无效的元素状态错误。
email_input = driver.find_element(By.NAME, "email_input")
email_input.clear() # Clear field
提交
在 Selenium 4 中,不再通过执行脚本使用单独的端点和函数来实现这一点。因此,建议不要使用这种方法,而是单击适用的表单提交按钮。
行为模拟
键盘模拟
用于与网页交互的任何键输入设备的表示形式。
只有两种操作可以用键盘完成:按下一个键和释放一个键。除了支持 ASCII 字符外,每个键盘键都有一个表示,可以按指定的顺序按下或释放。
除了常规 unicode 表示的键之外,还将 unicode 值分配给其他键盘键以供 Selenium 使用。每种语言都有自己的方式来引用这些键;完整的名单可以在这里找到。
key_down
ActionChains(driver)\
.key_down(Keys.SHIFT)\
.send_keys("abc")\
.perform()
key_up
ActionChains(driver)\
.key_down(Keys.SHIFT)\
.send_keys("a")\
.key_up(Keys.SHIFT)\
.send_keys("b")\
.perform()
激活元素
send_keys 是 Actions API 中的一个方便方法,它在一个操作中组合了 keyDown 和 keyUp 命令。执行此命令与使用元素的方法略有不同,但主要是在需要在其他操作中键入多个字符时使用。
text_input = driver.find_element(By.ID, "textInput")
ActionChains(driver)\
.send_keys_to_element(text_input, "abc")\
.perform()
以上代码表示向指定的输入框发送 abc 字符串并激活输入框。下面的代码是未指定元素而直接发送字符串并激活当前元素:
ActionChains(driver)\
.send_keys("abc")\
.perform()
复制/粘贴
cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL
ActionChains(driver)\
.send_keys("Selenium!")\
.send_keys(Keys.ARROW_LEFT)\
.key_down(Keys.SHIFT)\
.send_keys(Keys.ARROW_UP)\
.key_up(Keys.SHIFT)\
.key_down(cmd_ctrl)\
.send_keys("xvv")\
.key_up(cmd_ctrl)\
.perform()
鼠标模拟
鼠标总共有5个已定义的按钮:
0:左键(默认)1:中间键(目前不支持)2:右键3:X1(后退)按钮4:X2(前进)按钮
鼠标左键按下并保持
此方法结合了将鼠标移动到元素的中心和按下鼠标左键。这对于聚焦特定元素很有用。
clickable = driver.find_element(By.ID, "clickable")
ActionChains(driver) \
.click_and_hold(clickable) \
.perform()
鼠标左键按下后松开
此方法将移动到元素的中心与按下并释放鼠标左键结合起来。这也就是所谓的"点击":
clickable = driver.find_element(By.ID, "click")
ActionChains(driver) \
.click(clickable) \
.perform()
鼠标右键点击
此方法结合了移动到元素中心和按下并释放鼠标右键(按钮2)。这也就是所谓的"右键点击"。
clickable = driver.find_element(By.ID, "clickable")
ActionChains(driver) \
.context_click(clickable) \
.perform()
鼠标后退键点击
这没有方便的方法,只是按下并释放鼠标按钮 3:
action = ActionBuilder(driver)
action.pointer_action.pointer_down(MouseButton.BACK)
action.pointer_action.pointer_up(MouseButton.BACK)
action.perform()
鼠标前进键点击
这没有方便的方法,它只是按下和释放鼠标按钮 4:
action = ActionBuilder(driver)
action.pointer_action.pointer_down(MouseButton.FORWARD)
action.pointer_action.pointer_up(MouseButton.FORWARD)
action.perform()
鼠标左键双击
此方法将移动到元素的中心与按下并释放鼠标左键两次相结合。
clickable = driver.find_element(By.ID, "clickable")
ActionChains(driver) \
.double_click(clickable) \
.perform()
鼠标移动到指定元素上
此方法将鼠标移动到元素的视图中心点。这也被称为"悬停"。注意,元素必须在视窗中,否则命令会出错。
hoverable = driver.find_element(By.ID, "hover")
ActionChains(driver) \
.move_to_element(hoverable) \
.perform()
按相对位置移动鼠标
这些方法首先将鼠标移动到指定的原点,然后移动所提供偏移量中的像素数。注意,鼠标的位置必须在视窗(viewport)中,否则命令将出错。相对位置移动有三种情况:一种是将鼠标移动到元素的视图中心点,然后按提供的偏移量移动。
mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
ActionChains(driver) \
.move_to_element_with_offset(mouse_tracker, 8, 0) \
.perform()
另外一种是通过提供的偏移量将鼠标从当前视窗(viewport)的左上角移动。
action = ActionBuilder(driver)
action.pointer_action.move_to_location(8, 0)
action.perform()
第三种是通过用户提供的偏移量将鼠标从当前位置移动。如果之前没有移动过鼠标,则该位置将位于视口的左上角。注意,滚动页面时,指针的位置不会改变。
注意,第一个参数 XXX 指定当为正数时向右移动,而第二个参数 YYY 指定当为正数时向下移动。因此 moveByOffset(30, -10)从当前鼠标位置向右移动 303030 和向上移动 101010。
ActionChains(driver) \
.move_by_offset(13, 15) \
.perform()
拖动元素
该方法首先在源元素上执行单击并按住操作,移动到目标元素的位置,然后释放鼠标。
draggable = driver.find_element(By.ID, "draggable")
droppable = driver.find_element(By.ID, "droppable")
ActionChains(driver) \
.drag_and_drop(draggable, droppable) \
.perform()
按相对位置拖动元素
该方法首先在源元素上执行单击并按住操作,移动到给定的偏移量,然后释放鼠标。
draggable = driver.find_element(By.ID, "draggable")
start = draggable.location
finish = driver.find_element(By.ID, "droppable").location
ActionChains(driver) \
.drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
.perform()
使用手写笔
这是一种用于与网页交互的指针输入的手写笔的表示。Pen 是一种指针输入类型,具有与鼠标相同的大部分行为,但也可以具有触控笔特有的事件属性。此外,鼠标有 555 个按钮,而笔有 333 个相同的按钮状态:
0: Touch Contact(默认;相当于左键点击)2:桶形按钮(相当于右键)5:橡皮擦按钮(目前驱动程序不支持)
手写笔功能要求 selenium 版本至少为 4.2 版本及以上。
pointer_area = driver.find_element(By.ID, "pointerArea")
pen_input = PointerInput(POINTER_PEN, "default pen")
action = ActionBuilder(driver, mouse=pen_input)
action.pointer_action\
.move_to(pointer_area)\
.pointer_down()\
.move_by(2, 2)\
.pointer_up()
action.perform()
添加指针事件属性
pointer_area = driver.find_element(By.ID, "pointerArea")
pen_input = PointerInput(POINTER_PEN, "default pen")
action = ActionBuilder(driver, mouse=pen_input)
action.pointer_action\
.move_to(pointer_area)\
.pointer_down()\
.move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
.pointer_up(0)
action.perform()
滚轮
用于与网页交互的滚轮输入设备的表示形式。要求 Selenium v4.2 版本及以上,且只能在 Chromium上使用。
滚动到元素
这是最常见的场景。与传统的 click 和 send_keys方法不同,actions 类不会自动将目标元素滚动到视图中,所以如果元素不在视图中,则需要使用此方法。
这个方法接受一个web元素作为唯一参数。无论元素是在当前视屏的上方还是下方,视屏都会被滚动,这样元素的底部就会在屏幕的底部。
iframe = driver.find_element(By.TAG_NAME, "iframe")
ActionChains(driver)\
.scroll_to_element(iframe)\
.perform()
按给定坐标值滚动
这是第二种常见的滚动场景。传入一个 xxx 值和一个 yyy 值,表示向右和向下滚动的幅度。负值分别表示向左和向上。
footer = driver.find_element(By.TAG_NAME, "footer")
delta_y = footer.rect['y']
ActionChains(driver)\
.scroll_by_amount(0, delta_y)\
.perform()
从一个元素滚动给定的量
这种场景实际上是上述两种方法的组合。要执行此操作,请使用 Scroll From方法,该方法接受 333 个参数。第一个表示起始点,我们将其指定为元素,第二个两个表示 xxx 和 yyy 值。
如果元素在视口之外,它将被滚动到屏幕的底部,然后页面将被提供的 xxx 和 yyy 值滚动。
iframe = driver.find_element(By.TAG_NAME, "iframe")
scroll_origin = ScrollOrigin.from_element(iframe)
ActionChains(driver)\
.scroll_from_origin(scroll_origin, 0, 200)\
.perform()
从带有偏移量的元素滚动
当您只需要滚动屏幕的一部分,并且它在视窗(viewport)之外时,使用此场景。或位于视窗中,并且必须滚动的屏幕部分是与特定元素的已知偏移量。
这再次使用了 Scroll From 方法,除了指定元素之外,还指定了一个偏移量来指示滚动的原点。偏移量从所提供元素的中心计算。
如果元素位于视窗之外,则首先将其滚动到屏幕底部,然后将通过向元素中心的坐标添加偏移量来确定滚动的原点,最后将根据提供的 xxx 和 yyy 值滚动页面。
请注意,如果元素中心的偏移量落在视口之外,则会导致异常。
footer = driver.find_element(By.TAG_NAME, "footer")
scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
ActionChains(driver)\
.scroll_from_origin(scroll_origin, 0, 200)\
.perform()
从原点(元素)的偏移量开始滚动给定的量
最后一种场景是当您只需要滚动屏幕的一部分,并且它已经在视窗中时使用。
这再次使用了 Scroll From 方法,但是视窗被指定而不是一个元素。从当前视窗的左上角指定偏移量。确定原点后,将根据提供的 xxx 和 yyy 值滚动页面。
请注意,如果视窗左上角的偏移量落在屏幕之外,则会导致异常。
scroll_origin = ScrollOrigin.from_viewport(10, 10)
ActionChains(driver)\
.scroll_from_origin(scroll_origin, 0, 200)\
.perform()
浏览器级交互
获取浏览器信息
获取页面标题
title = driver.title
获取当前页面链接
url = driver.current_url
导航操作
导航到指定地址
driver.get("https://www.selenium.dev/selenium/web/index.html")
上一个历史访问
driver.back()
下一个历史访问
driver.forward()
刷新
driver.refresh()
对话框
alert
element = driver.find_element(By.LINK_TEXT, "See an example alert")
element.click()
wait = WebDriverWait(driver, timeout=2)
alert = wait.until(lambda d : d.switch_to.alert)
text = alert.text
alert.accept()
confirm
element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
driver.execute_script("arguments[0].click();", element)
wait = WebDriverWait(driver, timeout=2)
alert = wait.until(lambda d : d.switch_to.alert)
text = alert.text
alert.dismiss()
prompt
element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
driver.execute_script("arguments[0].click();", element)
wait = WebDriverWait(driver, timeout=2)
alert = wait.until(lambda d : d.switch_to.alert)
alert.send_keys("Selenium")
text = alert.text
alert.accept()
操作 cookie
添加 cookie
driver = webdriver.Chrome()
driver.get("http://www.example.com")
# Adds the cookie into current browser context
driver.add_cookie({"name": "key", "value": "value"})
根据名称获取 cookie
driver = webdriver.Chrome()
driver.get("http://www.example.com")
# Adds the cookie into current browser context
driver.add_cookie({"name": "foo", "value": "bar"})
# Get cookie details with named cookie 'foo'
print(driver.get_cookie("foo"))
获取所有 cookie
driver = webdriver.Chrome()
driver.get("http://www.example.com")
driver.add_cookie({"name": "test1", "value": "cookie1"})
driver.add_cookie({"name": "test2", "value": "cookie2"})
# Get all available cookies
print(driver.get_cookies())
删除 cookie
driver = webdriver.Chrome()
driver.get("http://www.example.com")
driver.add_cookie({"name": "test1", "value": "cookie1"})
driver.add_cookie({"name": "test2", "value": "cookie2"})
# Delete cookie with name 'test1'
driver.delete_cookie("test1")
删除所有 cookie
driver = webdriver.Chrome()
driver.get("http://www.example.com")
driver.add_cookie({"name": "test1", "value": "cookie1"})
driver.add_cookie({"name": "test2", "value": "cookie2"})
# Delete all cookies
driver.delete_all_cookies()
操作 Frame
Frame是一种从同一域中的多个文档构建站点布局的方法,现在已经过时了。除非你使用的是 HTML5 之前的网页应用,否则你不太可能使用它们。iframe 允许从完全不同的域插入文档,并且仍然被广泛使用。
如果你需要使用帧或 iframe, WebDriver 允许你以同样的方式使用它们。考虑 iframe 中的按钮。如果我们使用浏览器开发工具检查元素,我们可能会看到以下内容:
<div id="modal">
<iframe id="buttonframe" name="myframe" src="https://seleniumhq.github.io">
<button>Click here</button>
</iframe>
</div>
如果它不是为 iframe,我们将期望点击按钮使用类似:
# This Wont work
driver.find_element(By.TAG_NAME, 'button').click()
但是,如果 iframe 之外没有按钮,则可能会得到 no such element 错误。这是因为 Selenium 只知道顶层文档中的元素。为了与按钮交互,我们需要首先切换到框架,以类似于切换窗口的方式。WebDriver 提供了三种切换到帧的方法。下面的示例代码展示了我们如何使用一个实时的 web 示例来做到这一点。
使用 WebElement
使用 WebElement 进行切换是最灵活的选择。您可以使用首选选择器找到框架并切换到它。
# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source
email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()
使用 name 或者 id 操作
如果您的框架或 iframe 具有 id 或 name 属性,则可以使用此属性。如果名称或 ID 在页面上不是唯一的,那么将切换到找到的第一个。
# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name") # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source
email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()
使用索引
也可以使用框架的索引,例如可以在 JavaScript 中使用 window.frames 进行查询。
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source
要保留 iframe或 frameset,请切换回默认内容,如下所示:
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source
页面打印
打印网页是一项常见的任务,无论是共享信息还是维护档案。Selenium 通过 printopoptions、PrintsPage 和 browsingContext 类简化了这个过程,这些类为自动打印网页提供了灵活直观的界面。这些类使您能够配置打印首选项,例如页面布局、页边距和缩放,从而确保输出满足您的特定需求
配置页面方向
使用 getOrientation()和 setOrientation()方法,您可以获取/设置页面方向: PORTRAIT(纵向) 或 LANDSCAPE(横向)。
driver.get("https://www.selenium.dev/")
print_options = PrintOptions()
print_options.orientation = "landscape" ## landscape or portrait
配置打印页面范围
使用 getPageRanges()和 setPageRanges()方法,您可以获取/设置要打印的页面范围(如"2-4")。
driver.get("https://www.selenium.dev/")
print_options = PrintOptions()
print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
设置页面尺寸
使用 getPageSize()和 setPageSize()方法,您可以获取/设置要打印的纸张大小(如"A0","A6","Legal","小报"等)。
driver.get("https://www.selenium.dev/")
print_options = PrintOptions()
print_options.page_height = 27.94 # Use page_width to assign width
设置页边距
使用 getPageMargin()和 setPageMargin()方法,你可以设置你想要打印的页面的边距大小即 top, bottom, left, right 边距。
driver.get("https://www.selenium.dev/")
print_options = PrintOptions()
print_options.margin_top = 10
print_options.margin_bottom = 10
print_options.margin_left = 10
print_options.margin_right = 10
设置缩放
使用 getScale()和 setScale()方法,你可以获取/设置你想要打印的页面的比例(例如1.0是100%或默认值,0.25是25%,等等)。
driver.get("https://www.selenium.dev/")
print_options = PrintOptions()
print_options.scale = 0.5 ## 0.1 to 2.0
current_scale = print_options.scale
设置背景
使用 getBackground()和 setBackground()方法,您可以获取/设置背景颜色和图像是否出现-布尔值为真或假。
driver.get("https://www.selenium.dev/")
print_options = PrintOptions()
print_options.background = True ## True or False
设置自适应填充
使用 getShrinkToFit()和 setShrinkToFit()方法,您可以获取/设置页面是否将收缩到适合页面上的内容-布尔值为真或假。
driver.get("https://www.selenium.dev/")
print_options = PrintOptions()
print_options.shrink_to_fit = True ## True or False
打印
配置好打印选项之后,就可以打印页面了。为此,您可以调用 print 函数,该函数生成网页的 PDF 表示形式。生成的 PDF 可以保存到本地存储以供进一步使用或分发。使用 printpage(), print 命令将返回 base64 编码格式的 PDF 数据,该格式可以解码并写入所需位置的文件,使用 BrowsingContext()将返回 String。
根据您选择的语言,目前可能有多种实现。例如,使用 Java ,您可以使用 BrowingContext()或 printpage()进行打印。两者都以PrintOptions()对象作为参数。
driver.get("https://www.selenium.dev/")
print_options = PrintOptions()
pdf = driver.print_page(print_options)
操作浏览器
获取浏览器窗口句柄
WebDriver 不区分窗口和选项卡。如果您的站点打开了一个新的选项卡或窗口,Selenium会让您使用窗口句柄来处理它。每个窗口都有一个唯一的标识符,在单个会话中保持持久。你可以使用以下命令获取当前窗口的窗口句柄:
driver.current_window_handle
切换浏览器窗口
单击在新窗口中打开的链接将使新窗口或选项卡集中在屏幕上,但 WebDriver不知道操作系统认为哪个窗口是活动的。要使用新窗口,您需要切换到它。为此,我们获取所有窗口句柄,并将它们存储在一个数组中。数组位置按照窗口启动的顺序填充。所以第一个位置将是默认浏览器,等等。
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
with webdriver.Firefox() as driver:
# Open URL
driver.get("https://seleniumhq.github.io")
# Setup wait for later
wait = WebDriverWait(driver, 10)
# Store the ID of the original window
original_window = driver.current_window_handle
# Check we don't have other windows open already
assert len(driver.window_handles) == 1
# Click the link which opens in a new window
driver.find_element(By.LINK_TEXT, "new window").click()
# Wait for the new window or tab
wait.until(EC.number_of_windows_to_be(2))
# Loop through until we find a new window handle
for window_handle in driver.window_handles:
if window_handle != original_window:
driver.switch_to.window(window_handle)
break
# Wait for the new tab to finish loading content
wait.until(EC.title_is("SeleniumHQ Browser Automation"))
关闭浏览器或选项卡
当你完成了一个窗口或选项卡,并且它不是浏览器中打开的最后一个窗口或选项卡时,你应该关闭它并切换回你之前使用的窗口。假设您遵循了上一节中的代码示例,那么您将把前面的窗口句柄存储在一个变量中。把这些放在一起,你会得到:
#Close the tab or window
driver.close()
#Switch back to the old tab or window
driver.switch_to.window(original_window)
创建浏览器窗口/选项卡
创建一个新窗口(或)选项卡,并将新窗口或选项卡聚焦在屏幕上。您不需要切换到使用新窗口(或)选项卡。如果你打开了两个以上的窗口(或)选项卡,而不是新窗口,你可以在 WebDriver 可以看到的窗口或选项卡上循环,并切换到不是原来的那个。
注意:此特性适用于 Selenium 4 及更高版本。
# Opens a new tab and switches to new tab
driver.switch_to.new_window('tab')
# Opens a new window and switches to new window
driver.switch_to.new_window('window')
获取浏览器窗口大小
# Access each dimension individually
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")
# Or store the dimensions and query them later
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
设置浏览器窗口大小
driver.set_window_size(1024, 768)
获取浏览器窗口位置
# Access each dimension individually
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')
# Or store the dimensions and query them later
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
设置浏览器窗口位置
driver.set_window_position(0, 0)
最大化浏览器窗口
driver.maximize_window()
浏览器全屏
driver.fullscreen_window()
页面截图
用于捕获当前浏览上下文的屏幕截图。WebDriver 端点截图返回 Base64 格式编码的截图。
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.example.com")
# Returns and base64 encoded string into image
driver.save_screenshot('./image.png')
driver.quit()
元素截图
用于为当前浏览上下文捕获元素的屏幕截图。WebDriver 端点截图返回 Base64 格式编码的截图。
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("http://www.example.com")
ele = driver.find_element(By.CSS_SELECTOR, 'h1')
# Returns and base64 encoded string into image
ele.screenshot('./image.png')
driver.quit()
执行脚本
在选定框架或窗口的当前上下文中执行 JavaScript 代码片段。
# Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")
# Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
虚拟认证
Web Authenticator 模型的表示形式。
Web 应用程序可以启用称为 Web authentication 的基于公钥的身份验证机制,以无密码的方式对用户进行身份验证。Web 身份验证定义了允许用户创建公钥凭据并将其注册到身份验证器的 api 。身份验证器可以是存储用户公钥凭证并在请求时检索它们的硬件设备或软件实体。
顾名思义,Virtual Authenticator 模拟这样的验证器进行测试。
配置
虚拟身份验证具有一组属性。这些属性在 Selenium 绑定中被映射为 VirtualAuthenticatorOptions。
options = VirtualAuthenticatorOptions()
options.is_user_verified = True
options.has_user_verification = True
options.is_user_consenting = True
options.transport = VirtualAuthenticatorOptions.Transport.USB
options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
options.has_resident_key = False
添加虚拟认证器
它使用所提供的属性创建一个新的虚拟身份验证器。
options = VirtualAuthenticatorOptions()
options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
options.has_resident_key = False
# Register a virtual authenticator
driver.add_virtual_authenticator(options)
删除虚拟认证器
删除先前添加的虚拟身份验证器。
options = VirtualAuthenticatorOptions()
# Register a virtual authenticator
driver.add_virtual_authenticator(options)
# Remove virtual authenticator
driver.remove_virtual_authenticator()
创建有状态凭据
使用给定的必需凭据参数创建常驻(有状态)凭据。
# parameters for Resident Credential
credential_id = bytearray({1, 2, 3, 4})
rp_id = "localhost"
user_handle = bytearray({1})
privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
sign_count = 0
# create a resident credential using above parameters
resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
创建无状态凭据
使用给定的必需凭据参数创建常驻(无状态)凭据。
# parameters for Non Resident Credential
credential_id = bytearray({1, 2, 3, 4})
rp_id = "localhost"
privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
sign_count = 0
# create a non resident credential using above parameters
credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)
添加凭据
向身份验证者注册凭据。
driver.add_credential(credential)
获取凭据
返回验证者拥有的凭据列表。
credential_list = driver.get_credentials()
删除凭据
根据传递的凭据id从身份验证器中删除凭据。
driver.remove_credential(credential.id)
删除所有凭据
从身份验证器中删除所有凭据。
driver.remove_all_credentials()
设置用户验证结果状态
设置验证器在用户验证时模拟成功还是失败。
# Create virtual authenticator options
options = VirtualAuthenticatorOptions()
options.is_user_verified = True