杰瑞科技汇

Python Selenium日志如何配置与查看?

为什么需要配置 Selenium 日志?

默认情况下,Selenium 的日志信息非常少,通常只输出错误或警告,当你遇到以下情况时,就需要配置更详细的日志:

Python Selenium日志如何配置与查看?-图1
(图片来源网络,侵删)
  1. 调试定位问题:元素找不到 (NoSuchElementException)、页面加载超时 (TimeoutException) 时,详细的日志可以告诉你浏览器在执行什么操作,DOM 结构是怎样的,帮助你快速定位问题根源。
  2. 性能分析:通过日志记录页面各个部分的加载时间,可以分析性能瓶颈。
  3. 追踪流程:在复杂的自动化流程中,日志可以作为“面包屑”,清晰地记录脚本的执行路径。
  4. 记录用户操作:记录下脚本模拟的所有用户点击、输入等操作,方便回溯。

日志的来源

Selenium 的日志主要来自两个方面:

  1. 浏览器驱动日志:这是最重要的日志来源,ChromeDriver, GeckoDriver 等驱动程序在与浏览器通信时会产生大量的日志,包括启动信息、网络请求、JavaScript 执行错误、警告等。
  2. Selenium 客户端日志:这是 Python selenium 库自身产生的日志,比如一些参数验证、API 调用信息等,这部分日志相对较少,但有时也很有用。

我们的主要目标是配置并获取浏览器驱动日志


配置日志的方法

有几种方法可以配置 Selenium 的日志,从简单到推荐,我们逐一介绍。

最简单的方式 - 直接打印到控制台

这是最直接的方法,适合快速调试,通过 Service 对象来配置日志的输出级别和文件。

Python Selenium日志如何配置与查看?-图2
(图片来源网络,侵删)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import logging
# 1. 创建一个 Service 对象,指定日志级别和输出文件路径
# 这会将 ChromeDriver 的日志输出到文件 'chromedriver.log'
# 日志级别可以是 logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR
service = Service(
    executable_path='path/to/your/chromedriver', # 替换成你的 chromedriver 路径
    log_path='chromedriver.log',
    log_level=logging.DEBUG
)
# 2. 初始化 WebDriver,传入 service 对象
driver = webdriver.Chrome(service=service)
try:
    driver.get("https://www.example.com")
    # 等待并点击一个链接
    wait = WebDriverWait(driver, 10)
    link = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "More")))
    link.click()
    print("页面标题:", driver.title)
finally:
    driver.quit()
    print("日志已保存到 chromedriver.log")

优点

  • 非常简单,只需几行代码。

缺点

  • 日志信息会混合在 print 语句和程序输出中,不够清晰。
  • 不够灵活,无法同时输出到控制台和文件。

推荐的方式 - 使用 Python logging 模块

这是最强大、最灵活的方式,它允许你同时将日志输出到控制台和文件,并分别控制它们的格式和级别。

工作原理

Python Selenium日志如何配置与查看?-图3
(图片来源网络,侵删)
  1. 创建一个 logging.Logger 实例。
  2. 创建两个 logging.Handler:一个用于输出到控制台 (StreamHandler),一个用于输出到文件 (FileHandler)。
  3. 为每个 Handler 设置不同的日志级别和格式。
  4. Handler 添加到 Logger 中。
  5. Loggerlevel 设置为最低级别(如 DEBUG),这样它就能接收所有级别的日志,然后由各个 Handler 自己决定处理哪些级别的日志。

示例代码

import logging
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# --- 1. 配置 Python logging 模块 ---
# 创建一个 logger
logger = logging.getLogger('selenium_logger')
logger.setLevel(logging.DEBUG) # 设置 logger 的最低级别为 DEBUG
# 创建一个 formatter 用于定义日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 创建一个 console handler,用于输出到控制台
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO) # 只在控制台显示 INFO 及以上级别的日志
console_handler.setFormatter(formatter)
# 创建一个 file handler,用于输出到文件
file_handler = logging.FileHandler('selenium_debug.log')
file_handler.setLevel(logging.DEBUG) # 在文件中记录所有 DEBUG 及以上级别的日志
file_handler.setFormatter(formatter)
# 将 handlers 添加到 logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# --- 2. 配置 Selenium WebDriver ---
# 创建一个 Service 对象,将驱动日志输出到我们指定的 logger
# 这是关键!告诉 Selenium 把它的日志发送给我们的 Python logger
service = Service(
    executable_path='path/to/your/chromedriver', # 替换成你的 chromedriver 路径
    options=webdriver.ChromeOptions(),
    log_output=logger # 将驱动日志重定向到我们的 logger
)
driver = webdriver.Chrome(service=service)
try:
    logger.info("开始测试,导航到 Example.com")
    driver.get("https://www.example.com")
    logger.debug(f"页面 URL: {driver.current_url}")
    logger.debug(f"页面标题: {driver.title}")
    logger.info("尝试查找并点击 'More' 链接")
    wait = WebDriverWait(driver, 10)
    link = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "More")))
    logger.debug("成功找到 'More' 链接")
    link.click()
    logger.info("成功点击 'More' 链接")
    logger.info("获取新页面的标题")
    print("页面标题:", driver.title)
except Exception as e:
    logger.error(f"脚本执行出错: {e}", exc_info=True) # exc_info=True 会打印堆栈信息
finally:
    logger.info("测试结束,关闭浏览器")
    driver.quit()
    logger.info("日志已保存到 selenium_debug.log")

优点

  • 高度灵活:可以分别控制控制台和文件的日志级别、格式。
  • 结构化:日志格式统一,包含时间、模块名、级别等信息,易于阅读和分析。
  • 功能强大:可以轻松扩展,例如添加按日期分割的日志文件 (TimedRotatingFileHandler)。
  • Selenium 官方推荐:这是与 Python 日志系统集成的标准方式。

高级用法 - 使用 driver.log 方法

Selenium WebDriver 对象本身也提供了一个 log 方法,可以获取驱动在特定时间点的日志,这通常用于在脚本运行中或运行后,动态地获取特定类型的日志。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# ... (driver 初始化代码同上) ...
driver = webdriver.Chrome(service=Service(executable_path='path/to/your/chromedriver'))
driver.get("https://www.example.com")
# 获取不同类型的日志
# 'browser' - 浏览器控制台日志 (console.log, console.error 等)
# 'driver' - WebDriver 协议日志 (默认)
# 'client' - Selenium 客户端日志
# 'server' - 远程服务器日志 (如果使用 Selenium Grid)
# 获取浏览器控制台日志
browser_logs = driver.get_log('browser')
print("浏览器控制台日志:")
for entry in browser_logs:
    print(f"[{entry['level']}] {entry['message']}")
# 获取驱动协议日志
driver_logs = driver.get_log('driver')
print("\n驱动协议日志:")
for entry in driver_logs:
    print(f"[{entry['level']}] {entry['message']}")
driver.quit()

适用场景

  • 当你只关心浏览器控制台输出的 JavaScript 错误或警告时。
  • 当你不想在脚本运行期间持续记录日志,而是想在某个特定操作后检查日志时。

缺点

  • 不如 logging 模块灵活和强大,主要用于“拉取”日志,而不是“推送”日志。

日志级别详解

了解日志级别有助于你过滤和聚焦信息:

  • DEBUG:最详细的调试信息,通常只在诊断问题时启用,驱动日志会包含大量此类信息。
  • INFO:常规信息,确认程序按预期工作,脚本开始、导航到某个 URL、成功找到元素等。
  • WARNING:发生了一些意外,但程序仍在正常工作,某个 CSS 选择器没有找到元素,但使用了另一个备用选择器,Selenium 本身不常产生这类日志。
  • ERROR:严重问题,导致某些功能无法正常工作。NoSuchElementException,这是你最需要关注的日志级别之一。
  • CRITICAL:严重错误,可能导致程序完全停止。
  1. 首选 logging 模块:始终使用 Python 内置的 logging 模块来管理日志,这是最专业、最灵活的方式。
  2. 分离日志级别:将控制台日志级别设置为 INFOWARNING,以保持输出清晰;将文件日志级别设置为 DEBUG,以便在需要时进行深度调试。
  3. 格式化日志:为日志添加时间戳、级别和模块名,使其易于阅读和搜索。
  4. 在关键步骤添加日志:在脚本的关键操作(如 get, click, find_element)前后添加 logger.info()logger.debug(),这有助于追踪脚本执行流程。
  5. 妥善处理异常:使用 try...except 块捕获异常,并通过 logger.error() 记录错误信息,最好带上 exc_info=True 以获取完整的堆栈跟踪。
  6. 不要忘记 driver.quit():确保浏览器在脚本结束时被关闭,以释放资源,可以在 finally 块中添加日志,确认资源已释放。
分享:
扫描分享到社交APP
上一篇
下一篇