杰瑞科技汇

如何用Python玩转Selenium自动化测试?

Selenium 是一个强大的自动化测试工具,它允许你使用代码控制浏览器,模拟用户的操作,比如点击、输入、导航等,结合 Python,它变得异常强大和灵活,用途远不止于测试。

如何用Python玩转Selenium自动化测试?-图1
(图片来源网络,侵删)

Selenium 能做什么?(核心应用场景)

  1. Web 自动化测试:这是 Selenium 最核心的用途,你可以编写脚本来自动化测试 Web 应用的功能、回归测试、跨浏览器兼容性测试等。
  2. 网络爬虫:对于动态加载内容的网站(使用 JavaScript 渲染),传统的 requests 库可能无法获取到最终页面内容,Selenium 可以驱动浏览器,等待页面完全加载后,再提取所需数据。
  3. 自动化任务:任何需要重复在浏览器上进行的操作,都可以用 Selenium 来自动化,
    • 自动登录网站。
    • 定时抓取电商网站的价格信息。
    • 自动提交表单。
    • 在社交媒体上自动发帖(需遵守平台规则)。

环境准备

在开始之前,你需要安装必要的软件和库。

安装 Python

确保你的系统已经安装了 Python (推荐 3.6+ 版本),你可以在终端或命令行中输入 python --version 来检查。

安装 Selenium 库

使用 pip (Python 的包管理器) 来安装 Selenium 库。

pip install selenium

安装浏览器驱动

Selenium 本身不控制浏览器,它通过一个叫做 WebDriver 的中间件来与浏览器通信,你需要为你想要控制的浏览器下载对应的驱动。

如何用Python玩转Selenium自动化测试?-图2
(图片来源网络,侵删)

以最常用的 Chrome 浏览器 为例:

  1. 确定你的 Chrome 浏览器版本

    • 打开 Chrome 浏览器。
    • 点击右上角三个点 -> “帮助” -> “Google Chrome”。
    • 记下你的版本号,0.6778.85
  2. 下载对应版本的 WebDriver

    • 访问 ChromeDriver 下载页面:https://googlechromelabs.github.io/chrome-for-testing/
    • 找到与你 Chrome 版本最匹配的 chromedriver
    • 根据你的操作系统下载对应的文件(chromedriver-win64.zip)。
    • 重要:将下载好的 chromedriver.exe (Windows) 或 chromedriver (Mac/Linux) 文件放到一个固定的、容易找到的路径下(C:\WebDriver\),或者将其所在目录添加到系统的环境变量 PATH 中,为了方便,很多教程会建议直接把它和你的 Python 脚本放在同一个文件夹下。

安装浏览器

确保你的电脑上已经安装了对应版本的 Chrome 浏览器。


第一个 Selenium 脚本:打开浏览器并访问网页

让我们从一个最简单的例子开始。

# 1. 导入必要的模块
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
import time
# 2. 指定 chromedriver 的路径
# chromedriver 已添加到系统 PATH,可以省略此步
# CHROME_DRIVER_PATH = "C:/WebDriver/chromedriver.exe" 
# chromedriver 和脚本在同一目录,可以这样写
CHROME_DRIVER_PATH = "./chromedriver.exe" 
# 3. 初始化 WebDriver 服务
# 这是新版 Selenium 推荐的初始化方式
service = Service(executable_path=CHROME_DRIVER_PATH)
# 4. 创建 WebDriver 实例,这会打开一个浏览器窗口
driver = webdriver.Chrome(service=service)
# 5. 访问目标网页
driver.get("https://www.baidu.com")
# 6. 获取页面标题并打印
print("页面标题是:", driver.title)
# 7. 在搜索框中输入内容
# 首先要找到搜索框这个元素
try:
    # 通过 ID 定位搜索框
    search_box = driver.find_element(By.ID, "kw")
    # 输入 "Selenium"
    search_box.send_keys("Selenium")
    # 模拟按下回车键
    search_box.send_keys(Keys.ENTER)
    # 等待3秒,以便观察结果
    time.sleep(3)
except Exception as e:
    print(f"未找到元素或发生错误: {e}")
# 8. 关闭浏览器
# driver.quit() # 关闭所有由 WebDriver 打开的窗口
driver.close() # 关闭当前窗口

代码解释

  • webdriver.Chrome(): 创建一个 Chrome 浏览器的自动化实例。
  • driver.get(url): 导航到指定的 URL。
  • driver.title: 获取当前页面的标题。
  • driver.find_element(By.ID, "kw"): 这是元素定位的核心。By.ID 表示通过元素的 ID 属性来查找。"kw" 是百度搜索框的 ID。
  • send_keys(): 在定位到的元素上输入文本。
  • Keys.ENTER: 模拟按下键盘上的 Enter 键。
  • time.sleep(): 强制脚本暂停几秒,方便我们观察浏览器行为,在实际自动化测试中,应尽量使用显式等待(后面会讲)。
  • driver.quit(): 非常重要,用于关闭浏览器并结束 WebDriver 会话,这会释放所有相关资源。

核心概念详解

元素定位

这是 Selenium 最关键、最常用的部分,你需要告诉 Selenium 要操作页面上的哪个元素,以下是几种常用的定位方式:

定位方式 方法 描述 示例 (在百度搜索框上)
ID find_element(By.ID, "value") 通过元素的 id 属性定位,最常用、最稳定的方式。 find_element(By.ID, "kw")
Name find_element(By.NAME, "value") 通过元素的 name 属性定位。 find_element(By.NAME, "wd")
XPath find_element(By.XPATH, "value") 通过路径表达式定位,非常强大和灵活,可以处理复杂情况。 find_element(By.XPATH, '//input[@id="kw"]')
CSS Selector find_element(By.CSS_SELECTOR, "value") 通过 CSS 选择器定位,通常比 XPath 更快,语法简洁。 find_element(By.CSS_SELECTOR, "#kw")
Link Text find_element(By.LINK_TEXT, "value") 通过完整的链接文本定位一个 <a> find_element(By.LINK_TEXT, "新闻")
Partial Link Text find_element(By.PARTIAL_LINK_TEXT, "value") 通过部分链接文本定位一个 <a> find_element(By.PARTIAL_LINK_TEXT, "新")
Tag Name find_element(By.TAG_NAME, "value") 通过标签名定位,div, input, a 等。 find_element(By.TAG_NAME, "input")
Class Name find_element(By.CLASS_NAME, "value") | 通过元素的class属性定位。 |find_element(By.CLASS_NAME, "s_ipt")`

提示:你可以使用浏览器开发者工具(按 F12)来轻松获取元素的定位信息(ID, Name, XPath, CSS Selector 等)。

交互操作

定位到元素后,你可以对它进行各种操作:

  • element.click(): 点击元素。
  • element.send_keys("文本"): 输入文本。
  • element.clear(): 清空输入框的文本。
  • element.get_attribute("属性名"): 获取元素的属性值,get_attribute("href") 获取链接地址。

等待

time.sleep() 是一种“硬性等待”,它会让脚本固定等待一段时间,无论页面是否加载完成,这种方式效率低下且不稳定,Selenium 推荐使用“智能等待”,即显式等待

显式等待:你设置一个条件和一个最长等待时间,Selenium 会在这个时间内不断检查条件是否满足,一旦满足就立即继续执行;如果超时仍未满足,则抛出异常。

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.presence_of_element_located((By.ID, "myDynamicElement"))
    )
    print("元素已找到!")
finally:
    driver.quit()

expected_conditions (通常简写为 EC) 提供了很多预定义的条件,

  • EC.presence_of_element_located: 元素出现在 DOM 中(不一定可见)。
  • EC.visibility_of_element_located: 元素不仅出现在 DOM 中,而且是可见的。
  • EC.element_to_be_clickable: 元素是可点击的。

进阶示例:抓取动态加载的图片信息

假设我们要抓取 Unsplash 首页上图片的标题和下载链接。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
# 假设 chromedriver 在脚本同目录下
driver = webdriver.Chrome(service=Service(executable_path="./chromedriver.exe"))
try:
    driver.get("https://unsplash.com")
    # 使用显式等待,确保页面加载完成并且图片列表可见
    # 等待最多15秒,直到 class 为 "cYrRz" 的容器出现
    WebDriverWait(driver, 15).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, ".cYrRz"))
    )
    print("页面加载完成,开始抓取...")
    # 找到所有图片卡片容器
    # Unsplash 的结构可能会变,这里的选择器需要根据实际情况调整
    photo_cards = driver.find_elements(By.CSS_SELECTOR, "a[title] > div[style*='background-image']")
    print(f"找到 {len(photo_cards)} 张图片。")
    for i, card in enumerate(photo_cards[:5]): # 只取前5张图片作为示例
        try:
            # 获取图片标题 (通过父元素的 title 属性)
            title = card.find_element(By.XPATH, "..").get_attribute("title")
            # 获取图片的背景图片URL (通过 style 属性)
            style = card.get_attribute("style")
            # 简单提取URL,实际URL可能更复杂,这里只是一个示例
            url_start = style.find("url('") + 5
            url_end = style.find("')", url_start)
            image_url = style[url_start:url_end]
            print(f"--- 第 {i+1} 张图片 ---")
            print(f"标题: {title}")
            print(f"图片URL: {image_url}")
            print("-" * 20)
        except Exception as e:
            print(f"处理第 {i+1} 张图片时出错: {e}")
finally:
    # 确保浏览器最终被关闭
    driver.quit()

总结与最佳实践

  1. 为浏览器驱动设置 PATH:这是最佳实践,将下载好的 chromedriver 放到一个固定目录(如 C:\WebDriver),然后将该目录添加到系统的环境变量 PATH 中,这样你就可以在任何地方直接使用 webdriver.Chrome() 而无需指定路径。
  2. 优先使用显式等待:避免使用 time.sleep(),除非是调试,显式等待让你的脚本更健壮、更高效。
  3. 使用 try...except 处理异常:网络不稳定、元素加载慢、元素不存在等情况时有发生,使用异常处理可以让你的脚本更稳定。
  4. 合理使用 find_element (单个) 和 find_elements (多个):当你确定只有一个元素时用 find_element,当你需要获取一组元素时用 find_elements
  5. 善用浏览器开发者工具:这是你定位元素、分析页面结构的“利器”。
  6. 保持代码整洁:使用函数或类来封装你的操作,提高代码的可读性和复用性。

Selenium 是一个非常强大的工具,掌握它能为你的工作和项目带来极大的便利,希望这份指南能帮助你快速入门!

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