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

- 调试定位问题:元素找不到 (
NoSuchElementException)、页面加载超时 (TimeoutException) 时,详细的日志可以告诉你浏览器在执行什么操作,DOM 结构是怎样的,帮助你快速定位问题根源。 - 性能分析:通过日志记录页面各个部分的加载时间,可以分析性能瓶颈。
- 追踪流程:在复杂的自动化流程中,日志可以作为“面包屑”,清晰地记录脚本的执行路径。
- 记录用户操作:记录下脚本模拟的所有用户点击、输入等操作,方便回溯。
日志的来源
Selenium 的日志主要来自两个方面:
- 浏览器驱动日志:这是最重要的日志来源,ChromeDriver, GeckoDriver 等驱动程序在与浏览器通信时会产生大量的日志,包括启动信息、网络请求、JavaScript 执行错误、警告等。
- Selenium 客户端日志:这是 Python
selenium库自身产生的日志,比如一些参数验证、API 调用信息等,这部分日志相对较少,但有时也很有用。
我们的主要目标是配置并获取浏览器驱动日志。
配置日志的方法
有几种方法可以配置 Selenium 的日志,从简单到推荐,我们逐一介绍。
最简单的方式 - 直接打印到控制台
这是最直接的方法,适合快速调试,通过 Service 对象来配置日志的输出级别和文件。

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 模块
这是最强大、最灵活的方式,它允许你同时将日志输出到控制台和文件,并分别控制它们的格式和级别。
工作原理:

- 创建一个
logging.Logger实例。 - 创建两个
logging.Handler:一个用于输出到控制台 (StreamHandler),一个用于输出到文件 (FileHandler)。 - 为每个
Handler设置不同的日志级别和格式。 - 将
Handler添加到Logger中。 - 将
Logger的level设置为最低级别(如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:严重错误,可能导致程序完全停止。
- 首选
logging模块:始终使用 Python 内置的logging模块来管理日志,这是最专业、最灵活的方式。 - 分离日志级别:将控制台日志级别设置为
INFO或WARNING,以保持输出清晰;将文件日志级别设置为DEBUG,以便在需要时进行深度调试。 - 格式化日志:为日志添加时间戳、级别和模块名,使其易于阅读和搜索。
- 在关键步骤添加日志:在脚本的关键操作(如
get,click,find_element)前后添加logger.info()或logger.debug(),这有助于追踪脚本执行流程。 - 妥善处理异常:使用
try...except块捕获异常,并通过logger.error()记录错误信息,最好带上exc_info=True以获取完整的堆栈跟踪。 - 不要忘记
driver.quit():确保浏览器在脚本结束时被关闭,以释放资源,可以在finally块中添加日志,确认资源已释放。
