Skip to content

WebDriver

真正的用户正在操作浏览器

examples

入门

安装

无网url

# 有网首选
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()

使用selenium

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()

元素定位

locators

如果没有唯一的 id,那么最好使用写得好的 CSS 选择器来查找元素。

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 的关键概念:

DOMDocument Object Model,文档对象模型)是一个用于描述和操作 HTML 或 XML 文档的编程接口。它定义了页面的结构,使得开发者可以通过编程语言(如 JavaScript)来访问和修改页面的内容、结构和样式。

  1. 文档对象:DOM 表示一个 HTML 或 XML 文档为一棵树结构,每一个节点都是文档中的一个部分。例如,一个网页中的 <div><p> 标签、文本内容等都会是 DOM 树中的一个节点。

  2. 节点(Node):DOM 中的每个元素都是一个节点,节点可以是:

  3. 元素节点(Element Node):如 <div>, <p> 等标签。

  4. 文本节点(Text Node):包含文本内容的节点。
  5. 属性节点(Attribute Node):元素的属性(如 class, id)。
  6. 注释节点(Comment Node):HTML 注释。

每个节点都有一系列的属性和方法,允许开发者在脚本中进行操作。

  1. 树结构: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.)
  1. 操作 DOM:DOM 允许开发者通过编程语言访问和修改页面内容。比如,使用 JavaScript 可以:

  2. 修改 HTML 元素的内容和属性

  3. 动态添加、删除元素
  4. 改变元素的样式
  5. 响应用户交互

例如,以下 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 的组成部分:

BOMBrowser Object Model,浏览器对象模型)是浏览器中的一组 JavaScript 对象,用于描述和操作浏览器本身的行为和状态。与 DOM(文档对象模型)主要关注网页内容不同,BOM 关注的是浏览器窗口和浏览器环境的功能。

BOM 提供了一些 JavaScript 对象,可以让开发者与浏览器的其他功能交互,最常见的几个对象有:

  1. window 对象

  2. window 是 BOM 的核心对象,代表浏览器窗口或标签页。它不仅包含浏览器的全局环境,还提供了许多方法和属性来操作浏览器界面。

  3. window

    对象常见的方法和属性:

    • window.alert():弹出警告框。
    • window.location:获取或设置浏览器的当前 URL。
    • window.setTimeout():设置延迟执行的任务。
    • window.innerWidthwindow.innerHeight:获取浏览器窗口的宽度和高度。
  4. location 对象

  5. location 对象用于获取和设置浏览器的当前 URL。

  6. 常见操作:

    • window.location.href:获取当前 URL。
    • window.location.assign():加载新的 URL。
    • window.location.reload():重新加载当前页面。
  7. navigator 对象

  8. navigator 对象提供浏览器的相关信息,例如浏览器类型、操作系统、语言设置等。

  9. 常见属性:

    • navigator.userAgent:返回浏览器的用户代理字符串。
    • navigator.platform:返回浏览器运行的平台(操作系统)。
  10. screen 对象

  11. screen 对象提供有关屏幕的信息,如屏幕的宽度和高度。

  12. 常见属性:

    • screen.width:屏幕的宽度。
    • screen.height:屏幕的高度。
  13. history 对象

  14. history 对象提供浏览器的历史记录功能。

  15. 常见方法:
    • 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 常见用法:

  1. 操作浏览器的地址栏
window.location.href = "https://www.example.com";  // 跳转到新的 URL
  1. 获取浏览器的用户代理
console.log(navigator.userAgent);  // 输出浏览器的用户代理字符串
  1. 操作浏览器的历史记录
window.history.back();  // 返回上一页
  1. 控制浏览器窗口的大小
window.resizeTo(800, 600);  // 设置浏览器窗口的大小为 800x600
  1. 弹出警告框
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元素

image-20241119145015959

单选

# 具有 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接口

action_chains

ActionChains类是Selenium WebDriver中的一个重要功能模块,它提供了模拟用户输入和复杂交互的能力,包括鼠标移动、点击、拖放、键盘输入等。以下是对ActionChains类的详细讲解:

一、ActionChains类的主要功能

ActionChains类的主要功能是将多个动作链接在一起形成一个动作链,然后通过perform()方法执行这个动作链。这些动作可以包括鼠标移动、点击、双击、右击、悬停、拖放等,以及键盘的按键操作。

二、ActionChains类的方法

ActionChains类提供了多种方法用于模拟鼠标操作和键盘输入,以下是一些常用的方法:

  1. click(on_element=None):单击鼠标左键。如果指定了元素,则单击该元素;如果未指定元素,则在当前鼠标位置单击。
  2. context_click(on_element=None):右击鼠标右键。如果指定了元素,则右击该元素;如果未指定元素,则在当前鼠标位置右击。
  3. double_click(on_element=None):双击鼠标左键。如果指定了元素,则双击该元素;如果未指定元素,则在当前鼠标位置双击。
  4. move_to_element(to_element):将鼠标移动到指定的元素上。
  5. move_by_offset(xoffset, yoffset):将鼠标从当前位置移动到指定的坐标位置。
  6. drag_and_drop(source, target):将源元素拖拽到目标元素上。
  7. drag_and_drop_by_offset(source, xoffset, yoffset):将源元素拖拽到指定的偏移位置。
  8. click_and_hold(on_element=None):按住鼠标左键在源元素上。如果指定了元素,则按住该元素;如果未指定元素,则在当前鼠标位置按住。
  9. release(on_element=None):释放鼠标控制。如果指定了元素,则在该元素位置释放鼠标;如果未指定元素,则立即释放鼠标。
  10. key_down(value, element=None):按住指定的键。如果提供了元素,则在该元素上按住键。
  11. key_up(value, element=None):释放指定的键。如果提供了元素,则在该元素上释放键。
  12. send_keys(*keys_to_send):在当前焦点的元素上发送按键。
  13. send_keys_to_element(element, *keys_to_send):在指定元素上发送按键。
  14. pause(seconds):暂停指定的秒数。
  15. 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()

四、注意事项

  1. 在使用ActionChains类时,需要先导入相应的包,并创建一个WebDriver对象。
  2. 所有ActionChains的事件操作最后都需要执行perform()方法才会生效。
  3. ActionChains类的方法可以链式调用,也可以分步调用,但无论哪种方式,最后都需要调用perform()方法来执行所有操作。

综上所述,ActionChains类是Selenium WebDriver中一个非常强大的功能模块,它提供了丰富的方法来模拟用户的鼠标操作和键盘输入,从而实现自动化测试。

keys

1. 控制键和功能键

  • NULL ("\ue000") 表示空值,通常用于重置键盘状态。
  • CANCEL ("\ue001") 模拟“中断”功能键,类似于 Ctrl + Break 的功能。
  • HELP ("\ue002") 模拟 Help 键,通常用于打开帮助菜单。
  • BACKSPACE/BACK_SPACE ("\ue003") 模拟退格键,删除光标前的字符。
  • TAB ("\ue004") 模拟 Tab 键,用于切换焦点或输入字段。
  • CLEAR ("\ue005") 模拟清除键,通常用于清空输入框内容。
  • RETURN ("\ue006") 和 ENTER ("\ue007") 模拟回车键。RETURNENTER 的功能几乎相同,用于提交表单或确认输入。
  • 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)的按键:
  • NUMPAD0NUMPAD9 ("\ue01a""\ue023"):模拟数字键盘上的数字键。
  • MULTIPLY ("\ue024"):模拟数字键盘上的乘号键。
  • ADD ("\ue025"):模拟数字键盘上的加号键。
  • SEPARATOR ("\ue026"):模拟数字键盘上的分隔符键。
  • SUBTRACT ("\ue027"):模拟数字键盘上的减号键。
  • DECIMAL ("\ue028"):模拟数字键盘上的小数点键。
  • DIVIDE ("\ue029"):模拟数字键盘上的除号键。

4. 功能键 (F1 到 F12)

  • F1:帮助。
  • F5:刷新页面。
  • F11:全屏模式。

5. 其他键

  • METACOMMAND ("\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

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'])