杰瑞科技汇

Selenium Python如何实现截图功能?

save_screenshot()

这是 Selenium WebDriver 提供的内置方法,用于将当前浏览器窗口的可见区域保存为图像文件。

Selenium Python如何实现截图功能?-图1
(图片来源网络,侵删)

语法

driver.save_screenshot(filename)

参数

  • filename (str): 你想要保存截图的文件路径。强烈建议使用完整的绝对路径,以避免因工作目录不同而导致的文件保存失败。

返回值

  • 如果截图成功,返回 True
  • 如果截图失败,会抛出 Exception

基础示例

下面是一个最简单的截图示例,它会打开一个网页并保存截图到你的项目目录中。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import time
# 1. 初始化 WebDriver
# 使用 webdriver_manager 自动管理驱动,避免手动下载
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
try:
    # 2. 打开目标网页
    driver.get("https://www.baidu.com")
    print("已打开百度首页")
    # 3. 等待几秒,确保页面元素加载完成(仅作演示,实际项目中应使用显式等待)
    time.sleep(2)
    # 4. 定义截图文件名和路径
    # 使用 f-string 动态生成带时间戳的文件名,避免覆盖
    screenshot_path = "baidu_screenshot.png"
    # 5. 执行截图操作
    driver.save_screenshot(screenshot_path)
    print(f"截图已成功保存至: {screenshot_path}")
finally:
    # 6. 关闭浏览器
    driver.quit()

运行后,你的项目目录下就会生成一个名为 baidu_screenshot.png 的文件。


进阶用法与最佳实践

在实际项目中,仅仅会截图是不够的,我们还需要考虑命名、时机、异常处理等。

使用绝对路径

为了避免文件保存到奇怪的位置,最好使用绝对路径。

Selenium Python如何实现截图功能?-图2
(图片来源网络,侵删)
import os
# 获取当前脚本所在的目录
current_dir = os.path.dirname(os.path.abspath(__file__))
# 拼接出截图的完整路径
screenshot_path = os.path.join(current_dir, "screenshots", "baidu_screenshot.png")
# screenshots 目录不存在,则创建它
os.makedirs(os.path.dirname(screenshot_path), exist_ok=True)
driver.save_screenshot(screenshot_path)

截取特定元素

有时我们只想截取页面上的某个元素(比如一个按钮、一个错误提示框),而不是整个页面,这可以通过以下步骤实现:

  1. 找到该元素。
  2. 获取元素在页面中的位置和尺寸(x, y, width, height)。
  3. 使用 Python 的图像处理库(如 Pillow)来裁剪整个页面的截图。

你需要安装 Pillow 库: pip install Pillow

示例代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from PIL import Image
import os
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
try:
    driver.get("https://www.python.org")
    # 1. 先截取整个页面
    full_page_screenshot = "python_full_page.png"
    driver.save_screenshot(full_page_screenshot)
    # 2. 找到要截取的元素 ("Download" 按钮)
    element = driver.find_element(By.CSS_SELECTOR, ".download-button")
    # 3. 获取元素的位置和尺寸
    location = element.location  # {'x': 100, 'y': 500}
    size = element.size        # {'width': 200, 'height': 50}
    # 4. 计算裁剪区域的坐标 (left, top, right, bottom)
    left = location['x']
    top = location['y']
    right = location['x'] + size['width']
    bottom = location['y'] + size['height']
    # 5. 使用 Pillow 打开全屏截图并裁剪
    image_object = Image.open(full_page_screenshot)
    element_screenshot = image_object.crop((left, top, right, bottom))
    # 6. 保存元素截图
    element_screenshot.save("python_download_button.png")
    print("元素截图已保存: python_download_button.png")
finally:
    driver.quit()

在测试失败时自动截图

这是最常见的用法,我们可以结合 try...except...finally 结构,在测试用例抛出异常时自动捕获截图,方便调试。

Selenium Python如何实现截图功能?-图3
(图片来源网络,侵删)
import pytest
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def test_baidu_search():
    driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
    try:
        driver.get("https://www.baidu.com")
        # 使用显式等待来定位元素,比 time.sleep 更可靠
        search_box = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.ID, "kw"))
        )
        search_box.send_keys("Selenium")
        search_box.submit()
        # 等待搜索结果出现
        WebDriverWait(driver, 10).until(
            EC.title_contains("Selenium")
        )
        print("测试通过:搜索成功!")
    except TimeoutException:
        # 如果发生超时等异常,则截图
        timestamp = time.strftime("%Y%m%d_%H%M%S")
        screenshot_name = f"test_failure_{timestamp}.png"
        driver.save_screenshot(screenshot_name)
        print(f"测试失败!已自动保存截图: {screenshot_name}")
        # 可以选择重新抛出异常,让测试框架(如pytest)知道测试失败了
        raise
    finally:
        driver.quit()
# 如果使用 pytest,可以这样调用
# if __name__ == "__main__":
#     test_baidu_search()

截取整个滚动页面

标准的 save_screenshot() 只会截取浏览器当前视口(可见区域)的内容,如果页面很长,需要截取完整的长图,则需要更复杂的逻辑:

  1. 获取页面总高度。
  2. 滚动到页面底部。
  3. 循环截取视口,并拼接成一张长图。

注意: 这个功能比较复杂,通常建议使用专门的浏览器扩展或工具(如 Selenium Screenshot 库,或者 puppeteer 等工具)来实现,因为它们原生支持长截图。


功能 方法/代码 说明
基础截图 driver.save_screenshot("path/to/image.png") 最常用,截取当前视口。
最佳实践 os.path.join() + os.makedirs() 使用绝对路径,并自动创建目录,避免路径错误。
截取元素 element.location + element.size + Pillow 先截全屏,再用图像库裁剪出指定元素。
失败截图 try...except...finally except 块中调用截图方法,用于自动化测试调试。
长截图 复杂逻辑或使用其他工具 Selenium 本身不支持,需要额外处理或换工具。

掌握以上几种用法,你就可以在 Selenium 项目中灵活地处理各种截图需求了。

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