杰瑞科技汇

Python Selenium 方法有哪些常用技巧?

目录

  1. 环境准备
  2. 基本流程
  3. 核心对象与方法详解
    • 1 WebDriver 对象 - 浏览器驱动
    • 2 WebElement 对象 - 页面元素
    • 3 By 类 - 定位策略
  4. 常用操作详解
    • 1 元素定位
    • 2 操作元素
    • 3 获取元素信息
    • 4 等待
    • 5 处理弹窗
    • 6 处理多窗口/多标签页
    • 7 执行 JavaScript
    • 8 截图
  5. 最佳实践与进阶
    • 1 显式等待 vs. 隐式等待
    • 2 使用 Page Object Model (POM) 设计模式
    • 3 无头模式
    • 4 选项设置

环境准备

在开始之前,确保你已经安装了必要的软件和库。

Python Selenium 方法有哪些常用技巧?-图1
(图片来源网络,侵删)

a. 安装 Python 如果尚未安装,请从 Python官网 下载并安装。

b. 安装 Selenium 库 打开终端或命令行,使用 pip 进行安装:

pip install selenium

c. 下载浏览器驱动 Selenium 本身不控制浏览器,它需要通过一个“驱动”程序来与浏览器通信,你需要为你的浏览器下载对应的驱动。

d. 配置环境变量 (推荐) 将下载好的驱动程序(如 chromedriver.exegeckodriver)所在的目录添加到系统的环境变量 PATH 中,这样你就可以在任何地方直接调用驱动,而无需在代码中指定其完整路径。


基本流程

一个典型的 Selenium 脚本通常遵循以下步骤:

  1. 导入库: 导入 selenium 和其他需要的模块。
  2. 创建驱动实例: 初始化一个 WebDriver 对象,如 Chrome()
  3. 打开网页: 使用 get() 方法打开目标 URL。
  4. 定位元素: 使用 find_element()find_elements() 方法找到页面上的元素。
  5. 操作元素: 对找到的元素进行点击、输入、清除等操作。
  6. 获取信息: 从元素或浏览器中获取需要的数据(如文本、标题等)。
  7. 关闭浏览器: 使用 quit()close() 方法结束会话。

核心对象与方法详解

1 WebDriver 对象 - 浏览器驱动

这是整个自动化脚本的基石,代表了一个浏览器实例。

创建实例:

from selenium import webdriver
# 创建 Chrome 浏览器驱动实例
driver = webdriver.Chrome()
# 创建 Firefox 浏览器驱动实例
# driver = webdriver.Firefox()

常用方法:

  • driver.get(url): 导航到一个 URL。
    driver.get("https://www.baidu.com")
  • driver.title: 获取当前页面的标题。
    print(driver.title)  # 输出: 百度一下,你就知道
  • driver.current_url: 获取当前页面的 URL。
    print(driver.current_url)
  • driver.find_element(by, value) / driver.find_elements(by, value): 查找单个或多个元素,这是最核心的方法。
  • driver.maximize_window(): 最大化浏览器窗口。
  • driver.refresh(): 刷新当前页面。
  • driver.back(): 后退到上一页。
  • driver.forward(): 前进到下一页。
  • driver.page_source: 获取当前页面的 HTML 源代码。
  • driver.save_screenshot(filename): 截取屏幕截图并保存为文件。
  • driver.close(): 关闭当前标签页或窗口。
  • driver.quit(): 关闭所有窗口并彻底终止 WebDriver 会话,通常在脚本结束时调用。

2 WebElement 对象 - 页面元素

当你通过 find_element() 找到一个元素后,会返回一个 WebElement 对象,代表页面上的一个 DOM 元素。

常用方法:

  • element.click(): 点击元素。
  • element.send_keys(*value): 在可输入的元素中模拟按键输入。
    search_box = driver.find_element(By.ID, "kw")
    search_box.send_keys("Selenium 教程")
  • element.clear(): 清除输入框中的内容。
  • element.submit(): 提交表单,相当于在最后一个输入框上按下回车键。
  • element.get_attribute(name): 获取元素的属性值,如 id, name, src, href 等。
    logo_src = driver.find_element(By.ID, "lg").get_attribute("src")
  • element.text: 获取元素的可见文本。
    search_text = driver.find_element(By.ID, "s-top-left").text
  • element.is_displayed(): 判断元素是否可见。
  • element.is_enabled(): 判断元素是否可用(未被禁用)。
  • element.is_selected(): 判断元素是否被选中(用于复选框、单选框)。
  • element.size: �回元素的尺寸字典 {'width': xxx, 'height': yyy}
  • element.location: 返回元素的位置字典 {'x': xxx, 'y': yyy}

3 By 类 - 定位策略

By 类是一个枚举,提供了标准的定位策略,在使用 find_element 时,需要传入 By 中的值。

from selenium.webdriver.common.by import By
# 单个元素
element = driver.find_element(By.ID, "id_value")
# 多个元素
elements = driver.find_elements(By.CLASS_NAME, "class_value")

定位策略 (非常重要): | 定位方式 | By 值 | 描述 | 示例 | | :--- | :--- | :--- | :--- | | ID | By.ID | 通过元素的 id 属性定位(最快) | find_element(By.ID, "kw") | | Name | By.NAME | 通过元素的 name 属性定位 | find_element(By.NAME, "wd") | | XPath | By.XPATH | 通过 XPath 路径定位(最强大、最灵活) | find_element(By.XPATH, "//input[@class='s_ipt']") | | CSS Selector | By.CSS_SELECTOR | 通过 CSS 选择器定位(推荐,性能好于 XPath) | find_element(By.CSS_SELECTOR, "#kw") | | Link Text | By.LINK_TEXT | 通过链接的完整文本定位 | find_element(By.LINK_TEXT, "新闻") | | Partial Link Text| By.PARTIAL_LINK_TEXT| 通过链接的部分文本定位 | find_element(By.PARTIAL_LINK_TEXT, "新") | | Tag Name | By.TAG_NAME | 通过 HTML 标签名定位 | find_element(By.TAG_NAME, "input") | | Class Name | By.CLASS_NAME | 通过元素的 class 属性定位 | find_element(By.CLASS_NAME, "s_ipt") |


常用操作详解

1 元素定位

结合 By 类和 find_element 方法:

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# 1. 通过 ID 定位
search_box_by_id = driver.find_element(By.ID, "kw")
# 2. 通过 Name 定位
search_box_by_name = driver.find_element(By.NAME, "wd")
# 3. 通过 CSS Selector 定位 (推荐)
# ID选择器: #id
search_box_by_css_id = driver.find_element(By.CSS_SELECTOR, "#kw")
# Class选择器: .class
search_box_by_css_class = driver.find_element(By.CSS_SELECTOR, ".s_ipt")
# 属性选择器: [attribute='value']
search_box_by_css_attr = driver.find_element(By.CSS_SELECTOR, "[name='wd']")
# 4. 通过 XPath 定位
# 绝对路径 (不推荐,页面结构变化易失效)
# search_box_by_xpath_abs = driver.find_element(By.XPATH, "/html/body/div[1]/div[1]/div[5]/div[1]/div/form/span[1]/input")
# 相对路径 (推荐)
//input[@id='kw']      # 查找 id 为 'kw' 的 input 元素
//input[@class='s_ipt'] # 查找 class 为 's_ipt' 的 input 元素
//input[@name='wd' and @type='text'] # 查找 name='wd' 且 type='text' 的 input 元素
//a[text()='新闻']       # 查找文本为 '新闻' 的 a 链接
# 5. 通过链接文本定位
news_link = driver.find_element(By.LINK_TEXT, "新闻")
driver.quit()

2 操作元素

# 假设已经定位到搜索框和搜索按钮
search_box = driver.find_element(By.ID, "kw")
search_button = driver.find_element(By.ID, "su")
# 清除搜索框(如果之前有内容)
search_box.clear()
# 输入关键词
search_box.send_keys("Python 自动化测试")
# 点击搜索按钮
search_button.click()

3 获取元素信息

# 获取页面标题
print("页面标题是:", driver.title)
# 获取输入框的 placeholder 属性
placeholder = search_box.get_attribute("placeholder")
print("搜索框的 placeholder 是:", placeholder)
# 获取搜索按钮的文本
button_text = search_button.text
print("搜索按钮的文本是:", button_text)

4 等待

这是自动化测试中至关重要的一环,因为网页加载需要时间,元素可能不会立即出现,直接操作不存在的元素会导致 NoSuchElementException 错误。

a. 隐式等待 为整个 driver 设置一个全局等待时间,在查找元素时,如果元素没有立即找到,它会轮询(默认每 0.5 秒一次)直到元素出现或超时。

driver.implicitly_wait(10)  # 全局等待 10 秒
# 之后所有的 find_element 操作都会尝试等待 10 秒

缺点: 它只对 find_elementfind_elements 有效,并且如果元素在 5 秒后出现,它会等待 10 秒后才继续执行,效率不高。

b. 显式等待 (推荐) 针对某个特定的元素设置等待条件,代码会一直等待,直到某个条件成立(例如元素可见、可点击)或超时。

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 等待最多 10 秒,直到 id 为 'myDynamicElement' 的元素可见
try:
    element = WebDriverWait(driver, 10).until(
        EC.visibility_of_element_located((By.ID, "myDynamicElement"))
    )
    print("元素找到了!")
except TimeoutException:
    print("在 10 秒内未找到元素")
# 常用的 EC 条件:
# EC.presence_of_element_located((By, 'value'))  # 元素存在于 DOM 中
# EC.visibility_of_element_located((By, 'value')) # 元素可见 (存在于DOM中且displayed为true)
# EC.element_to_be_clickable((By, 'value'))      # 元素可被点击contains("百度")                      # 页面标题包含 "百度"

5 处理弹窗

# 切换到 alert
alert = driver.switch_to.alert
# 获取 alert 文本
print(alert.text)
# 接受 alert (点击 "确定")
alert.accept()
# 或者取消 alert (点击 "取消")
# alert.dismiss()
# 如果是 prompt 弹窗,还可以输入文本
# alert.send_keys("some text")

6 处理多窗口/多标签页

# 打开一个新标签页并切换
driver.execute_script("window.open('');")
# 获取所有窗口句柄
handles = driver.window_handles
# 切换到新打开的窗口(最后一个)
driver.switch_to.window(handles[-1])
# 在新窗口中操作
driver.get("https://www.taobao.com")
# 切换回第一个窗口
driver.switch_to.window(handles[0])

7 执行 JavaScript

Selenium 可以直接在浏览器中执行任意 JavaScript 代码,这非常有用。

# 滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 滚动到页面顶部
driver.execute_script("window.scrollTo(0, 0);")
# 高亮显示一个元素 (需要先定位到元素)
element = driver.find_element(By.ID, "kw")
driver.execute_script("arguments[0].style.border='3px solid red'", element)

8 截图

在测试失败时截图是很好的调试手段。

try:
    # ... 你的自动化操作 ...
    assert "成功" in driver.page_source
except AssertionError:
    # 如果断言失败,则截图
    driver.save_screenshot("failure.png")
    print("测试失败,已截图!")
    raise

最佳实践与进阶

1 显式等待 vs. 隐式等待

特性 显式等待 隐式等待
作用范围 针对单个元素或条件 针对整个 driver 的所有 find_element 调用
等待条件 灵活,可以是可见、可点击、标题包含等 仅等待元素出现在 DOM 中
代码位置 在需要等待的代码块前 通常在 driver 初始化后立即设置
推荐度 强烈推荐,更精确、更高效 不推荐,或仅作为辅助手段

最佳实践: 尽量使用显式等待,如果确实需要一个全局等待,可以设置一个较短的隐式等待(如 1-2 秒),但主要逻辑仍应依赖显式等待。

2 使用 Page Object Model (POM) 设计模式

当测试用例增多时,如果所有定位和操作都写在一个文件里,代码会变得难以维护,POM 是一种设计模式,它将页面和操作分离。

  • Page 对象: 将每个 Web 页面或组件建模为一个类,这个类包含页面的元素定位(By)和针对该页面的操作方法。
  • Test 脚本: 只负责调用 Page 对象的方法,描述测试的业务逻辑,而不关心具体的定位细节。

简单示例:

# page_objects/baidu_home_page.py
from selenium.webdriver.common.by import By
class BaiduHomePage:
    def __init__(self, driver):
        self.driver = driver
    # 页面元素定位
    search_box = (By.ID, "kw")
    search_button = (By.ID, "su")
    # 页面操作方法
    def load(self):
        self.driver.get("https://www.baidu.com")
    def search(self, keyword):
        self.driver.find_element(*self.search_box).send_keys(keyword)
        self.driver.find_element(*self.search_button).click()
# tests/test_baidu_search.py
from selenium import webdriver
from page_objects.baidu_home_page import BaiduHomePage
def test_baidu_search():
    driver = webdriver.Chrome()
    baidu_home = BaiduHomePage(driver)
    baidu_home.load()
    baidu_home.search("Selenium")
    assert "Selenium" in driver.title
    driver.quit()

3 无头模式

在不打开浏览器界面的情况下运行脚本,适用于服务器环境或 CI/CD 流程。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("--headless")  # 启用无头模式
chrome_options.add_argument("--disable-gpu") # 某些系统需要禁用GPU
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://www.baidu.com")
print(driver.title)
driver.quit()

4 选项设置

通过 Options 对象,你可以配置浏览器的各种启动参数,如无头模式、下载路径、代理、禁用图片等。

from selenium.webdriver.chrome.options import Options
options = Options()
# 设置下载路径
prefs = {
    "download.default_directory": "C:/Users/YourUser/Downloads",
    "download.prompt_for_download": False,
    "download.directory_upgrade": True,
    "safebrowsing.enabled": True
}
options.add_experimental_option("prefs", prefs)
# 禁用图片加载 (可加快页面加载速度)
prefs["profile.managed_default_content_settings.images"] = 2
options.add_experimental_option("prefs", prefs)
# 禁用日志
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(options=options)
# ...

希望这份详细的指南能帮助你全面掌握 Python Selenium!

分享:
扫描分享到社交APP
上一篇
下一篇