WebDriver¶
真正的用户正在操作浏览器
入门¶
安装¶
# 有网首选
pip install selenium
# 无网
下载 .whl 文件(无网url)
pip install *.whl
pip install selenium-4.25.0-py3-none-any.whl
Selenium Manager¶
Selenium Manager 是 Selenium 项目的官方驱动程序管理器,它在每个 Selenium 版本中都是开箱即用的。对应浏览器包含版本
Chrome:Selenium 4.11.0
Firefox: Selenium 4.12.0
Edge: Selenium 4.14.0
使用 Selenium 驱动 Chrome 的典型示例。假设在启动新会话时,本地计算机上没有安装 Chrome驱动。在这种情况下,Selenium Manager 将发现、下载和缓存当前稳定的 CfT 版本(在 ~/.cache/selenium/chrome 中)。
first_selenium.py¶
from selenium import webdriver
from selenium.webdriver.common.by import By
# 1. 使用驱动实例开启会话
driver = webdriver.Chrome()
# 2. 在浏览器上执行操作
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
# 3. 请求 浏览器信息
title = driver.title
print(title)
# 4. 建立等待策略
driver.implicitly_wait(0.5)
# 5. 发送命令 查找元素
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
# 6. 操作元素
text_box.send_keys("Selenium")
submit_button.click()
# 7. 获取元素信息
message = driver.find_element(by=By.ID, value="message")
text = message.text
print(text)
# 8. 结束会话
# 这将结束驱动程序进程, 默认情况下, 该进程也会关闭浏览器. 无法向此驱动程序实例发送更多命令.
driver.quit()
Web 应用的自动化测试、重复性任务、网页爬虫
Test Runner 即使不使用 Selenium 做测试,如果你有高级用例,使用一个 test runner 去更好地组织你的代码是很有意义的。学会使用 before/after hooks 和分组执行或者并行执行将会非常有用。
pytest - 由于其简单性和强大的插件,许多人的首选。
from selenium import webdriver
from selenium.webdriver.common.by import By
def test_eight_components():
driver = setup()
title = driver.title
assert title == "Web form"
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")
value = message.text
assert value == "Received!"
teardown(driver)
def setup():
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
return driver
def teardown(driver):
driver.quit()
元素定位¶
如果没有唯一的 id,那么最好使用写得好的 CSS 选择器来查找元素。
元素选择策略¶
在 WebDriver 中有 8 种不同的内置元素定位策略
定位器 Locator | 描述 |
---|---|
class name | 定位class属性与搜索值匹配的元素(不允许使用复合类名) |
css selector | 定位 CSS 选择器匹配的元素 |
id | 定位 id 属性与搜索值匹配的元素 |
name | 定位 name 属性与搜索值匹配的元素 |
link text | 定位link text可视文本与搜索值完全匹配的锚元素 |
partial link text | 定位link text可视文本部分与搜索值部分匹配的锚点元素。如果匹配多个元素,则只选择第一个元素。 |
tag name | 定位标签名称与搜索值匹配的元素 |
xpath | 定位与 XPath 表达式匹配的元素 |
driver.find_element(By.ID, "lname").clear()
driver.find_element(By.CSS_SELECTOR, "#fname").send_keys('css_selector')
driver.find_element(By.XPATH, "//input[@value='f']").click()
driver.find_element(By.NAME, "newsletter").click()
driver.find_element(By.CLASS_NAME, "information").send_keys('class_name')
print(driver.find_element(By.TAG_NAME, "a").tag_name)
print(driver.find_element(By.LINK_TEXT, "Selenium Official Page").text)
print(driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page").text)
相对定位符¶
定位符 | 描述 |
---|---|
Above | 一个元素的上面一个元素 |
Below | 一个元素的下面一个元素 |
Left of | 一个元素的左面一个元素 |
Right of | 一个元素的右面一个元素 |
Near | 识别距离提供的定位符最多 50 像素 的元素 |
Chaining relative locators | 链接相对定位器:识别为在一个元素的上方/下方和另一个元素的右侧/左侧。 |
from selenium.webdriver.support.relative_locator import locate_with
# Above 上面
email_locator = locate_with(By.CSS_SELECTOR, "input").above({By.ID: "lname"})
driver.find_element(email_locator).send_keys("above")
# Below 下面
password_locator = locate_with(By.TAG_NAME, "input").below({By.ID: "fname"})
driver.find_element(password_locator).send_keys("below")
# Left of 左侧
left_of = locate_with(By.TAG_NAME, "input").to_left_of({By.CSS_SELECTOR: 'input[value="f"]'})
driver.find_element(left_of).click()
# Right of 右侧
# right = [By.CSS_SELECTOR, 'input[value="m"]']
submit_locator = locate_with(By.TAG_NAME, "input").to_right_of({By.CSS_SELECTOR: 'input[value="m"]'})
driver.find_element(submit_locator).click()
# Near 50像素
near_locator = locate_with(By.TAG_NAME, "input").near({By.CSS_SELECTOR: 'input[value="1"]'})
driver.find_element(near_locator).send_keys("near_locator")
# Chaining relative locators 链接相对定位器
# 上右
above_to_right_of = locate_with(By.TAG_NAME, "input").above({By.ID: "baidu"}).to_right_of({By.ID: "1"})
driver.find_element(above_to_right_of).click()
# 上左
above_to_left_of = locate_with(By.TAG_NAME, "input").above({By.ID: "baidu"}).to_left_of({By.ID: "2"})
driver.find_element(above_to_left_of).click()
# 下右
below_to_right_of = locate_with(By.TAG_NAME, "input").below({By.ID: "baidu"}).to_right_of({By.ID: 'email'})
driver.find_element(below_to_right_of).send_keys("below_to_right_of")
# 下左
below_to_left_of = locate_with(By.TAG_NAME, "input").below({By.ID: "baidu"}).to_left_of({By.ID: 'password'})
driver.find_element(below_to_left_of).send_keys("123456@qq.com")
等待¶
隐式¶
driver.implicitly_wait(30)
显示¶
from selenium.webdriver.support.wait import WebDriverWait
element = WebDriverWait(driver, 10).until(lambda x:x.find_element(By.ID, "someId"))
is_disappeared = WebDriverWait(driver, 30, 1,(ElementNotVisibleException)).until_not(lambda x:x.find_element(By.ID, "someId").is_displayed())
强制¶
import time
time.sleep(3)
Expected Conditions¶
1. title_is(title: str)
¶
功能:检查当前页面的标题是否完全匹配给定的标题。
- 输入:一个字符串
title
,表示期望的标题。 - 返回:一个函数,如果标题匹配则返回
True
,否则返回False
。
2. title_contains(title: str)
¶
功能:检查当前页面的标题是否包含特定的子字符串。
- 输入:一个字符串
title
,表示期望的子字符串。 - 返回:一个函数,如果标题包含该子字符串则返回
True
,否则返回False
。
3. presence_of_element_located(locator: Tuple[str, str])
¶
功能:等待直到元素出现在 DOM 中。这个检查并不保证元素可见。
- 输入:一个定位器元组
(by, value)
,用于识别元素。 - 返回:一个函数,定位到元素后返回该 WebElement。
4. url_contains(url: str)
¶
功能:检查当前页面的 URL 是否包含特定的子字符串。
- 输入:一个字符串
url
,表示期望的 URL 子字符串。 - 返回:一个函数,如果当前 URL 包含该子字符串则返回
True
,否则返回False
。
5. url_matches(pattern: str)
¶
功能:检查当前页面的 URL 是否与给定的正则表达式模式匹配。
- 输入:一个字符串
pattern
,表示期望的正则表达式模式。 - 返回:一个函数,如果当前 URL 匹配该模式则返回
True
,否则返回False
。
6. url_to_be(url: str)
¶
功能:等待直到当前页面的 URL 精确匹配给定的 URL。
- 输入:一个字符串
url
,表示期望的 URL。 - 返回:一个函数,如果 URL 匹配则返回
True
,否则返回False
。
7. url_changes(url: str)
¶
功能:等待直到当前页面的 URL 与给定的 url
不同。
- 输入:一个字符串
url
,表示当前 URL。 - 返回:一个函数,如果 URL 发生变化则返回
True
,否则返回False
。
8. visibility_of_element_located(locator: Tuple[str, str])
¶
功能:检查元素是否在 DOM 中存在且可见(即:元素不仅显示,而且其高度和宽度大于 0)。
- 输入:一个定位器元组
(by, value)
,用于识别元素。 - 返回:一个函数,如果元素可见则返回该 WebElement,否则返回
False
。
9. visibility_of(element: WebElement)
¶
功能:检查一个已知的 WebElement 是否可见。
- 输入:一个 WebElement。
- 返回:一个函数,如果元素可见则返回该 WebElement,否则返回
False
。
10. _element_if_visible(element: WebElement, visibility: bool = True)
¶
功能:检查元素是否可见的辅助函数。
- 输入:一个 WebElement 和一个可选的
visibility
标志(默认值为True
,表示检查元素是否可见)。 - 返回:如果元素可见则返回该 WebElement,否则返回
False
。
11. presence_of_all_elements_located(locator: Tuple[str, str])
¶
功能:等待直到至少有一个匹配该定位器的元素出现在 DOM 中。
- 输入:一个定位器元组
(by, value)
,用于识别元素。 - 返回:一个函数,定位到元素后返回元素的列表。
12. visibility_of_any_elements_located(locator: Tuple[str, str])
¶
功能:等待直到至少有一个匹配该定位器的元素可见。
- 输入:一个定位器元组
(by, value)
,用于识别元素。 - 返回:一个函数,返回所有可见的 WebElements 列表。
13. visibility_of_all_elements_located(locator: Tuple[str, str])
¶
功能:等待直到所有匹配该定位器的元素在 DOM 中可见。
- 输入:一个定位器元组
(by, value)
,用于识别元素。 - 返回:一个函数,返回所有可见的 WebElements 列表,如果其中任何一个元素不可见则返回
False
。
14. text_to_be_present_in_element(locator: Tuple[str, str], text_: str)
¶
功能:检查给定的文本是否出现在指定元素的文本内容中。
- 输入:一个定位器元组
(by, value)
和一个字符串text_
,表示期望出现在元素中的文本。 - 返回:一个函数,如果文本存在于元素的文本中则返回
True
,否则返回False
。
15. text_to_be_present_in_element_value(locator: Tuple[str, str], text_: str)
¶
功能:检查给定的文本是否出现在指定元素的值中(例如输入框的 value
属性)。
- 输入:一个定位器元组
(by, value)
和一个字符串text_
,表示期望出现在元素值中的文本。 - 返回:一个函数,如果文本存在于元素的值中则返回
True
,否则返回False
。
16. text_to_be_present_in_element_attribute(locator: Tuple[str, str], attribute_: str, text_: str)
¶
功能:检查给定的文本是否出现在指定元素的某个属性值中。
- 输入:一个定位器元组
(by, value)
,一个属性名,和一个字符串text_
,表示期望出现在该属性中的文本。 - 返回:一个函数,如果文本存在于元素的属性值中则返回
True
,否则返回False
。
17. frame_to_be_available_and_switch_to_it(locator: Union[Tuple[str, str], str])
¶
功能:检查给定的 frame 是否可用,如果可用则切换到该 frame。
- 输入:一个 frame 定位器(可以是字符串,表示 frame 的名称,也可以是定位器元组
(by, value)
)。 - 返回:一个函数,如果 frame 可用并切换成功则返回
True
,否则返回False
。
18. invisibility_of_element_located(locator: Union[WebElement, Tuple[str, str]])
¶
功能:检查元素是否不可见或者不在 DOM 中。
- 输入:一个 WebElement 或者一个定位器元组
(by, value)
。 - 返回:一个函数,如果元素不可见或不在 DOM 中则返回
True
,否则返回False
。
19. invisibility_of_element(element: Union[WebElement, Tuple[str, str]])
¶
功能:检查元素是否不可见或者不在 DOM 中(与 invisibility_of_element_located
类似,但此函数接受 WebElement 或定位器作为输入)。
- 输入:一个 WebElement 或者一个定位器元组
(by, value)
。 - 返回:一个函数,如果元素不可见或不在 DOM 中则返回
True
,否则返回False
。
20. element_to_be_clickable(mark: Union[WebElement, Tuple[str, str]])
¶
功能:检查元素是否可见且可点击(即元素既可见又启用)。
- 输入:一个 WebElement 或者一个定位器元组
(by, value)
。 - 返回:一个函数,如果元素可见且启用则返回该 WebElement,否则返回
False
。
21. staleness_of(element: WebElement)
¶
功能:检查一个元素是否已经不再附加到 DOM 中(即元素已过时)。
- 输入:一个 WebElement。
- 返回:一个函数,如果元素已经不在 DOM 中则返回
True
,否则返回False
。
22. element_to_be_selected(element: WebElement)
¶
功能:检查给定元素是否被选中(例如复选框或单选按钮)。
- 输入:一个 WebElement。
- 返回:一个函数,如果元素已被选中则返回
True
,否则返回False
。
23. element_located_to_be_selected(locator: Tuple[str, str])
¶
功能:检查由定位器找到的元素是否被选中。
- 输入:一个定位器元组
(by, value)
。 - 返回:一个函数,如果元素已被选中则返回
True
,否则返回False
。
1. element_selection_state_to_be(element: WebElement, is_selected: bool) -> Callable[[Any], bool]
¶
功能:检查给定的元素是否处于指定的选中状态。
- 输入:
element
是一个WebElement
对象,is_selected
是一个布尔值,表示期望的选中状态(True
表示选中,False
表示未选中)。 - 返回:返回一个函数,该函数检查元素的
is_selected()
状态是否与is_selected
相匹配。
2. element_located_selection_state_to_be(locator: Tuple[str, str], is_selected: bool) -> Callable[[WebDriverOrWebElement], bool]
¶
功能:通过定位器找到元素,并检查该元素的选中状态是否与给定的状态一致。
- 输入:
locator
是一个定位器元组(by, path)
,is_selected
是一个布尔值,表示期望的选中状态。 - 返回:返回一个函数,该函数首先查找元素,并检查其
is_selected()
状态是否与is_selected
相匹配。如果元素被删除或不可用,则返回False
。
3. number_of_windows_to_be(num_windows: int) -> Callable[[WebDriver], bool]
¶
功能:检查当前浏览器窗口的数量是否等于指定的窗口数量。
- 输入:
num_windows
是一个整数,表示期望的窗口数量。 - 返回:返回一个函数,该函数检查当前打开的窗口数量是否与指定的数量
num_windows
相等。
4. new_window_is_opened(current_handles: List[str]) -> Callable[[WebDriver], bool]
¶
功能:检查是否有新的窗口打开,且窗口句柄的数量增加。
- 输入:
current_handles
是一个字符串列表,表示当前已打开的窗口句柄。 - 返回:返回一个函数,该函数检查当前窗口句柄的数量是否大于
current_handles
中的数量。如果有新的窗口打开,则返回True
,否则返回False
。
5. alert_is_present() -> Callable[[WebDriver], Union[Alert, Literal[False]]]
¶
功能:检查是否有警告框(Alert)弹出并切换到它。
- 输入:无
- 返回:返回一个函数,该函数尝试切换到当前的警告框(Alert)。如果没有警告框,则返回
False
。
6. element_attribute_to_include(locator: Tuple[str, str], attribute_: str) -> Callable[[WebDriverOrWebElement], bool]
¶
功能:检查指定元素的属性值是否包含某个指定的属性。
- 输入:
locator
是一个定位器元组(by, path)
,attribute_
是一个字符串,表示要检查的属性名。 - 返回:返回一个函数,该函数检查指定元素的属性值是否包含该属性。如果元素不存在或无法找到,返回
False
。
7. any_of(*expected_conditions: Callable[[D], T]) -> Callable[[D], Union[Literal[False], T]]
¶
功能:检查多个期望条件中是否有一个为 True
。相当于逻辑 "OR" 操作。
- 输入:
expected_conditions
是多个期望条件,每个期望条件都是一个函数。 - 返回:返回一个函数,该函数会依次检查每个期望条件,若有任何一个条件满足,则返回该条件的结果。如果没有条件满足,则返回
False
。
8. all_of(*expected_conditions: Callable[[D], Union[T, Literal[False]]]) -> Callable[[D], Union[List[T], Literal[False]]]
¶
功能:检查多个期望条件是否都为 True
。相当于逻辑 "AND" 操作。
- 输入:
expected_conditions
是多个期望条件,每个期望条件都是一个函数。 - 返回:返回一个函数,该函数依次检查每个期望条件。如果所有条件都满足,则返回一个包含每个期望条件结果的列表。如果有任何条件不满足,则返回
False
。
9. none_of(*expected_conditions: Callable[[D], Any]) -> Callable[[D], bool]
¶
功能:检查多个期望条件中是否没有任何一个为 True
。相当于逻辑 "NOT-OR" 操作。
- 输入:
expected_conditions
是多个期望条件,每个期望条件都是一个函数。 - 返回:返回一个函数,该函数会依次检查每个期望条件,若没有任何一个条件满足,则返回
True
。如果有任何条件满足,则返回False
。
这些函数通过返回符合条件的判断函数,帮助 Selenium WebDriver 等自动化框架等待并检查特定的条件是否满足,从而在自动化测试过程中进行适当的同步和操作。
DOM 的关键概念:¶
DOM(Document Object Model,文档对象模型)是一个用于描述和操作 HTML 或 XML 文档的编程接口。它定义了页面的结构,使得开发者可以通过编程语言(如 JavaScript)来访问和修改页面的内容、结构和样式。
-
文档对象:DOM 表示一个 HTML 或 XML 文档为一棵树结构,每一个节点都是文档中的一个部分。例如,一个网页中的
<div>
、<p>
标签、文本内容等都会是 DOM 树中的一个节点。 -
节点(Node):DOM 中的每个元素都是一个节点,节点可以是:
-
元素节点(Element Node):如
<div>
,<p>
等标签。 - 文本节点(Text Node):包含文本内容的节点。
- 属性节点(Attribute Node):元素的属性(如
class
,id
)。 - 注释节点(Comment Node):HTML 注释。
每个节点都有一系列的属性和方法,允许开发者在脚本中进行操作。
- 树结构:DOM 是一个树状结构,页面中的每个 HTML 元素都表示为树的一个节点。树的根节点是
document
对象,它包含了页面的所有内容。
举例来说,以下是一个简单的 HTML 页面:
<html>
<body>
<div id="container">
<h1>Hello, World!</h1>
<p>This is a paragraph.</p>
</div>
</body>
</html>
该 HTML 页面在 DOM 中的结构会呈现为类似这样的树形结构:
Document
├── HTML
├── BODY
├── DIV (id="container")
├── H1 (Hello, World!)
└── P (This is a paragraph.)
-
操作 DOM:DOM 允许开发者通过编程语言访问和修改页面内容。比如,使用 JavaScript 可以:
-
修改 HTML 元素的内容和属性
- 动态添加、删除元素
- 改变元素的样式
- 响应用户交互
例如,以下 JavaScript 代码修改了一个 div
元素的内容:
document.getElementById("container").innerHTML = "新的内容!";
DOM 与 HTML 的关系:¶
- HTML 是一种静态的标记语言,用于定义网页的结构和内容。
- DOM 是浏览器对 HTML 文档的动态表示和抽象。它将静态的 HTML 页面转换为可以通过编程语言(如 JavaScript)动态操作的对象模型。
在 Selenium 中的 DOM:¶
在 Selenium 中,DOM 用来描述页面的结构。WebDriver 操作页面时,实际上是在与 DOM 交互。例如,当你使用 driver.find_element()
方法查找元素时,Selenium 会通过浏览器的 DOM 找到相应的元素节点。
driver.find_element()
查找的是页面中的 DOM 元素。WebElement
对象代表的是 DOM 中的某个元素。- 你可以通过 WebDriver 执行各种操作,比如点击、输入文本、获取属性等,实际上是在操作 DOM 中的元素节点。
总结:¶
- DOM 是网页的编程接口,提供了对网页内容、结构和样式的动态访问和修改能力。
- 在 Selenium 中,WebDriver 通过 DOM 操控网页元素,模拟用户的交互行为。
BOM 的组成部分:¶
BOM(Browser Object Model,浏览器对象模型)是浏览器中的一组 JavaScript 对象,用于描述和操作浏览器本身的行为和状态。与 DOM(文档对象模型)主要关注网页内容不同,BOM 关注的是浏览器窗口和浏览器环境的功能。
BOM 提供了一些 JavaScript 对象,可以让开发者与浏览器的其他功能交互,最常见的几个对象有:
-
window 对象:
-
window
是 BOM 的核心对象,代表浏览器窗口或标签页。它不仅包含浏览器的全局环境,还提供了许多方法和属性来操作浏览器界面。 -
window
对象常见的方法和属性:
window.alert()
:弹出警告框。window.location
:获取或设置浏览器的当前 URL。window.setTimeout()
:设置延迟执行的任务。window.innerWidth
和window.innerHeight
:获取浏览器窗口的宽度和高度。
-
location 对象:
-
location
对象用于获取和设置浏览器的当前 URL。 -
常见操作:
window.location.href
:获取当前 URL。window.location.assign()
:加载新的 URL。window.location.reload()
:重新加载当前页面。
-
navigator 对象:
-
navigator
对象提供浏览器的相关信息,例如浏览器类型、操作系统、语言设置等。 -
常见属性:
navigator.userAgent
:返回浏览器的用户代理字符串。navigator.platform
:返回浏览器运行的平台(操作系统)。
-
screen 对象:
-
screen
对象提供有关屏幕的信息,如屏幕的宽度和高度。 -
常见属性:
screen.width
:屏幕的宽度。screen.height
:屏幕的高度。
-
history 对象:
-
history
对象提供浏览器的历史记录功能。 - 常见方法:
window.history.back()
:返回到上一页。window.history.forward()
:前进到下一页。window.history.go()
:跳转到特定的历史记录。
BOM 和 DOM 的区别:¶
- DOM
(文档对象模型)是用来操作网页内容的。它提供了 HTML 或 XML 文档的结构,允许你在网页加载后修改页面的结构、内容和样式。
-
示例:使用
document.getElementById()
获取页面上的元素并修改其内容。 -
BOM
(浏览器对象模型)则是用来与浏览器的环境交互的。它提供了一些接口来操作浏览器的窗口、历史记录、地址栏等。
- 示例:使用
window.location.href
获取当前网页的 URL,或使用window.alert()
显示一个弹框。
重要区别总结:¶
- DOM 处理的是页面内容和结构。
- BOM 处理的是浏览器环境和浏览器的状态。
BOM 常见用法:¶
- 操作浏览器的地址栏:
window.location.href = "https://www.example.com"; // 跳转到新的 URL
- 获取浏览器的用户代理:
console.log(navigator.userAgent); // 输出浏览器的用户代理字符串
- 操作浏览器的历史记录:
window.history.back(); // 返回上一页
- 控制浏览器窗口的大小:
window.resizeTo(800, 600); // 设置浏览器窗口的大小为 800x600
- 弹出警告框:
window.alert("Hello, World!"); // 弹出一个警告框
总结:¶
- BOM 是浏览器环境的对象模型,提供了与浏览器窗口、地址栏、历史记录等进行交互的能力。
- DOM 是文档的对象模型,用来操作网页内容和结构。
在 Web 开发中,DOM 主要用于操作页面内容,而 BOM 主要用于与浏览器环境交互。
文件上传¶
单个文件¶
[!CAUTION]
由于 Selenium 无法与文件上传对话框交互,因此它提供了一种无需打开对话框即可上传文件的方法。如果元素是类型为 file 的 input 元素,则可以使用 send keys 方法将要上传的文件的完整路径发送。
<input type="file">
file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
file_input.send_keys(upload_file)
driver.find_element(By.ID, "file-submit").click()
多个文件¶
pyperclip.copy(path) # 将图片文件复制到剪贴板上
pyperclip.paste() # 获取剪贴板上的内容
pyautogui.hotkey('ctrl', 'v') # 将剪贴板上的文件路径粘贴到应用窗口
pyautogui.press('enter') # 模拟回车
Select元素¶
单选¶
# 具有 disabled 属性的选项可能无法被选择.
select_element = driver.find_element(By.NAME, "selectomatic")
select = Select(select_element)
# 文本
select.select_by_visible_text('Four')
print(select.first_selected_option.text)
# 值
select.select_by_value("two")
print(select.first_selected_option.text)
# 索引
select.select_by_index(3)
print(select.first_selected_option.text)
复选¶
select_multi = driver.find_element(By.ID, 'multi')
select = Select(select_multi)
option_list = select.options
for i in option_list:
print(i.text)
# print(option_list)
selected_option_list = select.all_selected_options
for i in selected_option_list:
print(i.text)
# 选中所有
select_multi = driver.find_element(By.ID, 'multi')
select = Select(select_multi)
# 确保 <select> 支持多选
if select.is_multiple:
# 遍历所有选项并选择
for option in select.options:
select.select_by_visible_text(option.text) # 或使用 select_by_value(option.get_attribute('value'))
print("已选择全部选项")
# 验证选中的选项
selected_options = [option.text for option in select.all_selected_options]
print("选中的选项:", selected_options)
Actions接口¶
ActionChains类是Selenium WebDriver中的一个重要功能模块,它提供了模拟用户输入和复杂交互的能力,包括鼠标移动、点击、拖放、键盘输入等。以下是对ActionChains类的详细讲解:
一、ActionChains类的主要功能¶
ActionChains类的主要功能是将多个动作链接在一起形成一个动作链,然后通过perform()方法执行这个动作链。这些动作可以包括鼠标移动、点击、双击、右击、悬停、拖放等,以及键盘的按键操作。
二、ActionChains类的方法¶
ActionChains类提供了多种方法用于模拟鼠标操作和键盘输入,以下是一些常用的方法:
- click(on_element=None):单击鼠标左键。如果指定了元素,则单击该元素;如果未指定元素,则在当前鼠标位置单击。
- context_click(on_element=None):右击鼠标右键。如果指定了元素,则右击该元素;如果未指定元素,则在当前鼠标位置右击。
- double_click(on_element=None):双击鼠标左键。如果指定了元素,则双击该元素;如果未指定元素,则在当前鼠标位置双击。
- move_to_element(to_element):将鼠标移动到指定的元素上。
- move_by_offset(xoffset, yoffset):将鼠标从当前位置移动到指定的坐标位置。
- drag_and_drop(source, target):将源元素拖拽到目标元素上。
- drag_and_drop_by_offset(source, xoffset, yoffset):将源元素拖拽到指定的偏移位置。
- click_and_hold(on_element=None):按住鼠标左键在源元素上。如果指定了元素,则按住该元素;如果未指定元素,则在当前鼠标位置按住。
- release(on_element=None):释放鼠标控制。如果指定了元素,则在该元素位置释放鼠标;如果未指定元素,则立即释放鼠标。
- key_down(value, element=None):按住指定的键。如果提供了元素,则在该元素上按住键。
- key_up(value, element=None):释放指定的键。如果提供了元素,则在该元素上释放键。
- send_keys(*keys_to_send):在当前焦点的元素上发送按键。
- send_keys_to_element(element, *keys_to_send):在指定元素上发送按键。
- pause(seconds):暂停指定的秒数。
- perform():执行ActionChains中的所有操作。
三、ActionChains类的使用示例¶
以下是一个使用ActionChains类模拟鼠标操作的示例代码:
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
import time
# 创建WebDriver对象
driver = webdriver.Chrome()
driver.get("https://www.example.com") # 访问目标网页
driver.maximize_window() # 最大化窗口
# 定位需要操作的元素
element = driver.find_element(By.ID, "example-element")
# 创建ActionChains对象
actions = ActionChains(driver)
# 模拟鼠标操作
actions.move_to_element(element) # 鼠标移动到元素上
actions.click() # 单击元素
actions.double_click(element) # 双击元素
actions.context_click(element) # 右击元素
actions.perform() # 执行所有操作
# 暂停一段时间以便观察效果
time.sleep(5)
# 关闭浏览器
driver.quit()
四、注意事项¶
- 在使用ActionChains类时,需要先导入相应的包,并创建一个WebDriver对象。
- 所有ActionChains的事件操作最后都需要执行perform()方法才会生效。
- ActionChains类的方法可以链式调用,也可以分步调用,但无论哪种方式,最后都需要调用perform()方法来执行所有操作。
综上所述,ActionChains类是Selenium WebDriver中一个非常强大的功能模块,它提供了丰富的方法来模拟用户的鼠标操作和键盘输入,从而实现自动化测试。
Cookie¶
keys¶
1. 控制键和功能键¶
NULL
("\ue000"
) 表示空值,通常用于重置键盘状态。CANCEL
("\ue001"
) 模拟“中断”功能键,类似于Ctrl + Break
的功能。HELP
("\ue002"
) 模拟Help
键,通常用于打开帮助菜单。BACKSPACE
/BACK_SPACE
("\ue003"
) 模拟退格键,删除光标前的字符。TAB
("\ue004"
) 模拟Tab
键,用于切换焦点或输入字段。CLEAR
("\ue005"
) 模拟清除键,通常用于清空输入框内容。RETURN
("\ue006"
) 和ENTER
("\ue007"
) 模拟回车键。RETURN
和ENTER
的功能几乎相同,用于提交表单或确认输入。SHIFT
/LEFT_SHIFT
("\ue008"
) 模拟左Shift
键,用于切换大写字母或组合键。CONTROL
/LEFT_CONTROL
("\ue009"
) 模拟左Ctrl
键,用于组合键操作,例如Ctrl+C
。ALT
/LEFT_ALT
("\ue00a"
) 模拟左Alt
键,用于组合键操作,如Alt+Tab
。PAUSE
("\ue00b"
) 模拟暂停键,通常用于中断进程。ESCAPE
("\ue00c"
) 模拟Esc
键,通常用于退出或取消操作。
2. 导航键¶
SPACE
("\ue00d"
) 模拟空格键,用于输入空白字符或激活某些控件。PAGE_UP
("\ue00e"
) 和PAGE_DOWN
("\ue00f"
) 分别模拟向上翻页和向下翻页操作。END
("\ue010"
) 和HOME
("\ue011"
)END
:将光标移动到行尾或页面底部。HOME
:将光标移动到行首或页面顶部。- 箭头键 (
LEFT
,UP
,RIGHT
,DOWN
) LEFT
("\ue012"
):模拟左箭头键,用于向左移动光标或选择。UP
("\ue013"
):模拟上箭头键。RIGHT
("\ue014"
):模拟右箭头键。DOWN
("\ue015"
):模拟下箭头键。INSERT
("\ue016"
) 和DELETE
("\ue017"
)INSERT
:切换插入模式和覆盖模式。DELETE
:删除光标后的字符。
3. 数字键盘键¶
- 数字键盘(Numpad)的按键:
NUMPAD0
到NUMPAD9
("\ue01a"
到"\ue023"
):模拟数字键盘上的数字键。MULTIPLY
("\ue024"
):模拟数字键盘上的乘号键。ADD
("\ue025"
):模拟数字键盘上的加号键。SEPARATOR
("\ue026"
):模拟数字键盘上的分隔符键。SUBTRACT
("\ue027"
):模拟数字键盘上的减号键。DECIMAL
("\ue028"
):模拟数字键盘上的小数点键。DIVIDE
("\ue029"
):模拟数字键盘上的除号键。
4. 功能键 (F1 到 F12)¶
F1
:帮助。F5
:刷新页面。F11
:全屏模式。
5. 其他键¶
META
和COMMAND
("\ue03d"
) 模拟元键,用于 macOS 系统上的Command
键或 Windows 系统的Windows
键。ZENKAKU_HANKAKU
("\ue040"
) 模拟全角/半角切换键,常用于日语输入法。
切换win窗口、标签页、IFrames框架¶
属性、方法名 | 解释 |
---|---|
driver.current_window_handle | 查看当前driver实例在那个活动窗口 |
driver.window_handles | 查看所有的的窗口 |
driver.switch_to.window() | 切换窗口 |
driver.switch_to.frame() | 切换frame框架 |
driver.switch_to.default_content() | 离开frame框架 |
driver.close() | 关闭标签页或窗口 |
driver.switch_to.new_window('tab') | 打开新标签页并切换到新标签页 |
driver.switch_to.new_window('window') | 打开一个新窗口并切换到新窗口 |
driver.quit() | 退出浏览器 关闭所有与 WebDriver 会话相关的窗口和选项卡 结束浏览器进程 结束后台驱动进程 通知 Selenium Grid 浏览器不再使用,以便可以由另一个会话使用它(如果您正在使用 Selenium Grid) |
driver.get_window_size().get("width") | 获取窗口的宽 |
driver.get_window_size().get("height") | 获取窗口的高 |
driver.set_window_size(1024, 768) | 设置窗口大小 |
driver.get_window_position().get('x') | 左上角的坐标 |
driver.get_window_position().get('y') | 左上角的坐标 |
driver.set_window_position(0, 0) | 将窗口移动到主显示器的左上角 |
driver.maximize_window() | 窗口最大化 |
driver.minimize_window() | 窗口最小化(selenium4以上版本) |
driver.fullscreen_window() | 窗口全屏 |
driver.save_screenshot('./image.png') | 屏幕截图 |
ele.screenshot('./image.png') | 元素截图 |
driver.execute_script('return arguments[0].innerText', header) | 执行脚本 |
from selenium.webdriver.common.print_page_options import PrintOptions | 打印页面Chromium |
滑块操作¶
# 定位滑块
ele_k = self.driver.find_element(*LoginPage.ele_s)
ele_t = self.driver.find_element(*LoginPage.ele_e)
distance = ele_t.size['width'] - ele_k.size['width']
# 执行鼠标操作
ac = ActionChains(self.driver)
ac.drag_and_drop_by_offset(ele_k, xoffset=distance, yoffset=0).perform()
time.sleep(1)
# 滑块状态
status = self.driver.find_element(*LoginPage.status)
print(status.text) # 验证通过
window窗口¶
driver.get('https://tieba.baidu.com')
print(driver.current_window_handle)
driver.switch_to.new_window('window')
driver.get('https://taobao.com')
print(driver.current_window_handle)
print(driver.window_handles)
B65DEDA5C79063FBAD1BE2B0D7D46B51
3D4F91F700FAA2144F86F63341232B78
['B65DEDA5C79063FBAD1BE2B0D7D46B51', '3D4F91F700FAA2144F86F63341232B78']
标签¶
driver.get('https://tieba.baidu.com')
driver.find_element(By.LINK_TEXT, '立即注册').click()
print(driver.current_window_handle)
window_list = driver.window_handles
try:
driver.find_element(By.NAME, 'userName').send_keys('123123')
except:
driver.switch_to.window(window_list[1])
driver.find_element(By.NAME, 'userName').send_keys('123123')
iframe¶
<iframe id="i01" name="myframe" src="https://www.taobao.com" width="100%" height="100%"></iframe>
<iframe id="i02" name="tianmao" src="https://www.tmall.com" width="100%" height="100%"></iframe>
try:
driver.find_element(By.LINK_TEXT, '免费注册').click()
except NoSuchElementException:
# WebElement 先定位,在切换
iframe = driver.find_element(By.CSS_SELECTOR, 'body>iframe:first-child')
driver.switch_to.frame(iframe)
driver.find_element(By.LINK_TEXT, '免费注册').click()
# 使用name,id
driver.switch_to.frame('i01')
driver.find_element(By.LINK_TEXT, '免费注册').click()
driver.switch_to.frame('myframe')
driver.find_element(By.LINK_TEXT, '免费注册').click()
# 使用索引
iframe = driver.find_elements(By.TAG_NAME, 'iframe')[1]
driver.switch_to.frame(iframe)
driver.find_element(By.LINK_TEXT, '亲,请登录').click()
# 离开框架
driver.switch_to.default_content()
selenium 滚动条¶
# 1. 滚动到页面底部
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
# 利用JavaScript代码将页面滚动到最底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 2. 滚动到页面顶部
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
# 执行JavaScript让页面滚动到顶部,水平坐标和垂直坐标都设为0
driver.execute_script("window.scrollTo(0, 0);")
# 3. 滚动到指定元素位置
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://example.com")
# 先通过元素定位方式(这里以ID为例)找到目标元素
element = driver.find_element(By.ID, "target_element_id")
# 使用JavaScript的scrollIntoView方法将元素滚动到可视区域
driver.execute_script("arguments[0].scrollIntoView();", element)
# 4. 滚动条的相对滚动(向下滚动一定像素值为例)
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
# 获取当前垂直滚动位置(单位是像素)
current_y = driver.execute_script("return window.pageYOffset;")
# 设定要向下滚动的像素值,这里设为100像素,可按需修改
scroll_amount = 100
# 通过JavaScript代码让页面相对当前位置向下滚动指定像素值
driver.execute_script(f"window.scrollTo(0, {current_y + scroll_amount});")
# 5. 结合隐式等待与滚动操作
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.implicitly_wait(10) # 设置隐式等待时间为10秒
driver.get("https://example.com")
# 先滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 再查找页面底部某个元素(这里以class name定位为例),隐式等待会生效
element = driver.find_element(By.CLASS_NAME, "bottom_element_class")
JavaScript警告框,提示框和确认框¶
print(alert.text) # 获取弹出框中的文本
print(alert.send_leys('向弹框中输入内容')) # 向弹框中输入内容
# Alerts 警告框
driver.find_element(By.ID, "1").click()
wait = WebDriverWait(driver, 5)
alert = wait.until(lambda d: d.switch_to.alert)
alert.accept()
time.sleep(2)
# Confirm 确认框
driver.find_element(By.ID, "2").click()
wait = WebDriverWait(driver, 5)
confirm = wait.until(lambda d: d.switch_to.alert)
confirm.dismiss() # 确认按钮
confirm.accept() # 取消按钮
time.sleep(2)
# Prompt 提示框
driver.find_element(By.ID, "3").click()
wait = WebDriverWait(driver, 5)
prompt = wait.until(lambda d: d.switch_to.alert)
prompt.accept()
prompt.accept()
time.sleep(2)
webdriver方法¶
webelement方法¶
浏览器配置¶
Chrome特定功能¶
默认情况下,Selenium 4与Chrome v75及更高版本兼容. 但是请注意Chrome浏览器的版本与chromedriver的主版本需要匹配.
server¶
# 默认服务
service = webdriver.ChromeService()
# 制定驱动位置
service = webdriver.ChromeService(executable_path=chromedriver_bin)
# 驱动程序端口
service = webdriver.ChromeService(port=1234)
# 日志
service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'],log_output=get_log_path_and_name())
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent
def get_log_path_and_name():
"""
按照年月生成日志目录
按照年月日生成日志文件
"""
now = datetime.now()
log_dir = BASE_DIR / 'logs' / f"{now.year}-{now.month:02d}"
if not os.path.exists(log_dir):
os.makedirs(log_dir)
log_file = log_dir / f"{now.year}-{now.month:02d}-{now.day:02d}.log"
return str(log_file)
options¶
options = webdriver.ChromeOptions()
# 搜索引擎选择屏幕
options.add_argument('--disable-search-engine-choice-screen')
# 禁止下载语言插件
options.add_argument(
'--disable-features=OptimizationGuideModelDownloading,OptimizationHintsFetching,OptimizationTargetPrediction,'
'OptimizationHints')
# 无痕模式
options.add_argument("--incognito")
# 设置语言
options.add_argument("lang=zh-CN")
# 窗口最大化
options.add_argument("--start-maximized")
# 禁止硬件加速
options.add_argument("--disable-gpu")
# 禁止图片
options.add_argument("blink-settings=imagesEnabled=false")
# 浏览器稳定版本
options.browser_version = 'stable'
# 禁止自动关闭浏览器
options.add_experimental_option("detach", True)
# 禁止显示"Chrome 正受到自动测试软件的控制。"
options.add_experimental_option('excludeSwitches', ['enable-automation'])