Selenium SessionNotCreatedException:浏览器驱动版本匹配与系统性解决方案

发布时间:2026/7/2 4:38:19
Selenium SessionNotCreatedException:浏览器驱动版本匹配与系统性解决方案 1. 问题现象与核心原因剖析最近在调试一个UI自动化脚本时又遇到了这个老朋友selenium.common.exceptions.SessionNotCreatedException: Message: session not created:。这个报错对于使用Selenium做自动化测试或数据采集的朋友来说简直是“家常便饭”但每次出现都让人心头一紧因为它意味着浏览器驱动和浏览器之间的“握手”失败了整个自动化流程在起跑线上就摔了个跟头。简单来说这个异常就是Selenium WebDriver尝试与一个浏览器实例如Chrome、Firefox建立通信会话时失败了。你可以把它想象成你想用遥控器WebDriver去控制一台电视机浏览器但遥控器发出的信号频率和电视机接收的频率对不上或者电视机压根没开机于是遥控器就报错了。这个“对不上”的原因绝大多数情况下都集中在浏览器驱动Driver与浏览器Browser版本不匹配这个问题上。ChromeDriver的版本必须与已安装的Chrome浏览器版本兼容通常是相同的大版本号。除此之外浏览器驱动路径未正确配置、浏览器未安装、浏览器存在多个版本冲突、甚至杀毒软件或防火墙拦截了驱动进程都可能导致这个异常。这个问题的棘手之处在于错误信息本身往往不够具体。它可能只告诉你“session not created”后面跟着一串可能包含“This version of ChromeDriver only supports Chrome version XX”的详细信息也可能什么都没有让你无从下手。因此系统性地排查和解决这个问题是每个Selenium使用者必须掌握的技能。2. 系统性排查与解决方案遇到SessionNotCreatedException不要慌张按照从简到繁、从最常见到最隐蔽的顺序进行排查十有八九能快速定位问题。2.1 首要检查浏览器与驱动版本匹配这是导致该异常的最高频原因没有之一。1. 确认浏览器版本打开你的Chrome浏览器在地址栏输入chrome://settings/help或点击右上角三个点 - 帮助 - 关于Google Chrome即可看到版本号例如版本 124.0.6367.91正式版本 64 位。记住主版本号124。2. 确认驱动版本如果你已经下载了ChromeDriver可以通过命令行检查。打开终端CMD或PowerShell导航到驱动所在目录执行chromedriver --version或者对于Windows系统如果已将驱动路径加入系统环境变量直接运行上述命令即可。输出会类似于ChromeDriver 124.0.6367.91 (...)。同样关注主版本号124。3. 版本匹配规则理想情况下ChromeDriver的主版本号应与Chrome浏览器的主版本号完全一致。例如Chrome 124 对应 ChromeDriver 124。有时相邻的小版本也可能兼容但为了稳定性强烈建议保持主版本号一致。注意Chrome浏览器会自动更新但ChromeDriver不会。某天你的脚本还能运行第二天就报SessionNotCreatedException很可能就是浏览器夜间自动升级了而驱动还是旧版本。因此建立驱动版本的定期检查机制很有必要。4. 下载与配置正确驱动如果版本不匹配你需要去官方站点下载对应版本的驱动。ChromeDriver官方地址https://chromedriver.chromium.org/更推荐的方式使用淘宝的镜像站速度更快https://npm.taobao.org/mirrors/chromedriver/ 在镜像站中找到与你的Chrome浏览器主版本号一致的目录下载对应操作系统win32, mac64, linux64的压缩包。下载后通常是一个可执行文件如chromedriver.exe。你有两种方式使用它方法A放入系统PATH路径。将其放在一个固定目录如C:\WebDriver\并将该目录添加到系统的环境变量PATH中。这是最一劳永逸的方法。方法B在代码中指定路径。在实例化WebDriver时通过service参数指定驱动文件的绝对路径。from selenium import webdriver from selenium.webdriver.chrome.service import Service # 指定你的chromedriver.exe的绝对路径 driver_path rC:\WebDriver\chromedriver.exe service Service(executable_pathdriver_path) driver webdriver.Chrome(serviceservice)我个人的习惯是使用方法B尤其是在项目初期或需要管理多个不同版本驱动时。这样可以将驱动文件放在项目目录里通过相对路径引用便于项目迁移和版本管理避免污染全局环境。2.2 环境与配置问题排查如果版本确认无误问题依然存在那么我们需要深入环境层面。1. 浏览器未安装或安装异常这听起来很基础但确实发生过。请确认你代码中指定的浏览器如Chrome已正确安装在默认位置。对于Chrome可以尝试在命令行直接输入chrome或google-chrome看能否启动。有时便携版Portable浏览器或非标准安装路径也会导致问题此时需要在ChromeOptions中指定二进制文件路径。from selenium.webdriver.chrome.options import Options options Options() options.binary_location rD:\MyPortableChrome\chrome.exe # 指定非标准路径的Chrome driver webdriver.Chrome(optionsoptions, serviceservice)2. 浏览器多版本冲突系统中安装了多个Chrome例如稳定版、Beta版、Canary版可能导致WebDriver混淆。你需要明确指定使用哪一个。除了上述binary_location还可以通过命令行参数指定用户数据目录来隔离。3. 杀毒软件或防火墙拦截一些安全软件可能会将chromedriver.exe识别为可疑程序并阻止其运行或创建网络连接。尝试临时禁用杀毒软件特别是其实时防护功能或防火墙然后运行脚本。如果成功则需要在安全软件中将ChromeDriver添加为信任程序。4. 端口占用或残留进程Selenium WebDriver启动浏览器时会使用特定端口进行通信。如果之前的脚本异常退出可能导致浏览器进程或驱动进程残留占用端口。解决方法是任务管理器Windows或活动监视器Mac中结束所有名为chrome.exe、chromedriver.exe或geckodriver.exefor Firefox的进程然后重试。5. 权限问题在Linux或Mac系统下确保chromedriver文件具有可执行权限。在终端中进入驱动所在目录执行chmod x chromedriver2.3 代码层面与高级选项调试环境没问题就要看看是不是代码写法或浏览器选项配置有误。1. 确保正确导入和实例化最基本的错误往往最容易忽略。检查你的导入语句和WebDriver实例化代码。# 正确示例 from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options options Options() # ... 添加你的options配置如无头模式、禁用沙盒等 service Service(executable_pathpath/to/chromedriver) driver webdriver.Chrome(optionsoptions, serviceservice)特别注意新版本的Selenium4.x及以上推荐使用Service类来管理驱动生命周期旧的executable_path参数直接传入webdriver.Chrome()的方式已被弃用。2. 浏览器选项ChromeOptions配置某些选项配置不当会导致浏览器无法正常启动。以下是一些常见且通常安全的配置可以尝试添加以规避一些已知问题options Options() options.add_argument(--no-sandbox) # 在Linux无头环境或某些Docker环境中常需禁用沙盒 options.add_argument(--disable-dev-shm-usage) # 解决共享内存空间不足问题常见于Docker options.add_argument(--disable-gpu) # 早期版本在无头模式下可能需要禁用GPU options.add_argument(--window-size1920,1080) # 设置初始窗口大小 # 如果遇到用户配置文件相关问题可以尝试启动一个全新的临时用户目录 options.add_argument(--user-data-dir/tmp/chrome_test_profile) driver webdriver.Chrome(optionsoptions, serviceservice)实操心得--no-sandbox和--disable-dev-shm-usage这两个参数在服务器如Linux Docker容器上运行Selenium时几乎是必需的。在本地Windows/Mac开发时如果问题依旧也可以尝试加上作为排查步骤。3. 使用更详细的日志输出为了获取更详细的错误信息可以在创建Service对象时启用日志。from selenium.webdriver.chrome.service import Service import logging service Service(executable_pathpath/to/chromedriver, log_outputchromedriver.log) # 输出到文件 # 或者输出到标准输出 service Service(executable_pathpath/to/chromedriver) service.log_path chromedriver.log # 也可以这样设置 driver webdriver.Chrome(serviceservice)运行后查看生成的chromedriver.log文件里面可能会有比异常信息更详细的错误描述例如具体的Chrome启动命令、网络错误等。3. 针对不同场景的专项解决方案不同的运行环境本地IDE、CI/CD流水线、Docker容器会遇到不同侧重点的问题。3.1 本地开发环境如PyCharm、VSCode在本地集成开发环境中问题相对单纯主要聚焦于版本匹配和路径配置。常见陷阱虚拟环境干扰如果你使用了Python虚拟环境venv, conda请确保是在激活了虚拟环境的终端或IDE配置中运行脚本。有时IDE的运行配置Run Configuration没有正确指向虚拟环境的解释器导致使用的是系统Python其PATH环境变量可能不包含你的驱动路径。PyCharm运行配置在PyCharm中检查Run - Edit Configurations。确保Working directory设置正确特别是当你使用相对路径指定驱动时。更好的做法是使用基于项目根目录的绝对路径构造方法import os from selenium import webdriver from selenium.webdriver.chrome.service import Service project_root os.path.dirname(os.path.abspath(__file__)) driver_path os.path.join(project_root, drivers, chromedriver.exe) service Service(executable_pathdriver_path)缓存问题极少数情况下IDE或Python的缓存可能导致问题。尝试重启IDE或者清除Python的__pycache__目录。3.2 持续集成/持续部署环境如Jenkins、GitHub Actions在CI/CD环境中浏览器和驱动通常需要动态安装环境是全新的、隔离的。核心策略使用WebDriver管理器这是最推荐的做法。库如webdriver-manager(Python) 可以自动下载、缓存和管理正确版本的浏览器驱动。# 安装 pip install webdriver-manager from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager # 自动下载并使用匹配的ChromeDriver service Service(ChromeDriverManager().install()) driver webdriver.Chrome(serviceservice)webdriver-manager会检查系统已安装的Chrome版本并自动下载对应的驱动。这极大地简化了CI环境的配置。对于GitHub Actions你可以在工作流步骤中先安装Chrome然后使用webdriver-manager。在CI脚本中显式安装浏览器确保CI环境中有确定版本的浏览器。例如在GitHub Actions中可以使用actions/setup-chrome动作。- name: Set up Chrome uses: browser-actions/setup-chromev1 with: chrome-version: stable # 或指定具体版本如 124.0.6367.91 - name: Install Python dependencies run: pip install selenium webdriver-manager使用无头模式并添加必要参数CI环境通常没有图形界面必须使用无头模式并加上之前提到的服务器常用参数。options.add_argument(--headlessnew) # Selenium 4.8 推荐使用new headless options.add_argument(--no-sandbox) options.add_argument(--disable-dev-shm-usage)3.3 Docker容器环境在Docker中运行Selenium最佳实践是直接使用官方或社区维护的Selenium镜像如selenium/standalone-chrome。这些镜像已经完美配置好了浏览器、驱动以及必要的依赖如一个显示服务器XVFB用于无头模式。如果你坚持要在自定义Dockerfile中安装基础镜像选择带有图形库的如python:3.11-slim可能不够需要python:3.11或基于Ubuntu的镜像。安装Chrome时使用官方的APT源确保版本稳定。务必安装xvfb(X Virtual Framebuffer) 来模拟显示环境即使你使用无头模式某些浏览器操作仍可能需要。在Dockerfile中复制或使用webdriver-manager下载驱动。运行命令时可能需要启动xvfb并在该虚拟显示中运行你的Python脚本。# 示例Dockerfile片段 FROM python:3.11 RUN apt-get update apt-get install -y \ wget \ gnupg \ xvfb \ wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ echo deb [archamd64] http://dl.google.com/linux/chrome/deb/ stable main /etc/apt/sources.list.d/google.list \ apt-get update apt-get install -y google-chrome-stable RUN pip install selenium webdriver-manager踩过的坑在Docker中/dev/shm共享内存空间可能很小导致Chrome崩溃。这就是为什么--disable-dev-shm-usage参数如此重要它告诉Chrome使用/tmp替代/dev/shm。4. 进阶排查与替代方案考量当所有常规手段都失效时我们需要一些进阶的排查思路甚至考虑技术选型的替代。4.1 深入日志与网络分析如果错误信息依然模糊可以尝试提升日志级别甚至进行网络抓包。1. 启用Selenium和浏览器的详细日志除了之前提到的service.log_path还可以通过环境变量或ChromeOptions启用Chrome的详细日志。options Options() options.add_argument(--verbose) options.add_argument(--log-level0) # INFO0, DEBUG1, 数字越小越详细 # 将日志重定向到文件 options.add_experimental_option(prefs, {logging: {log-level: 0}})同时可以配置Python的logging模块来捕获Selenium库本身的日志。import logging logging.basicConfig(levellogging.DEBUG)运行脚本后控制台会输出海量的调试信息从中你可能发现连接超时、协议错误等线索。2. 使用浏览器开发者工具协议直接调试Selenium底层使用的是浏览器的开发者工具协议。你可以尝试绕过Selenium直接用更底层的工具如puppeteer的browserless或直接使用chrome-remote-interface连接浏览器看是否能成功创建会话以此隔离是否是Selenium客户端库的问题。4.2 考虑使用Playwright作为替代方案如果你长期受困于Selenium的驱动版本兼容性问题并且项目允许技术栈变更那么Playwright是一个极具吸引力的现代替代品。它由微软开发近年来在自动化测试和爬虫领域势头很猛。Playwright相比Selenium的优势自动管理浏览器驱动Playwright在安装时playwright install会自动下载与其API版本匹配的Chromium、Firefox和WebKit浏览器完全无需手动管理驱动版本从根本上杜绝了SessionNotCreatedException。API设计更现代强大提供了更简洁的API内置了智能等待auto-wait、网络拦截、移动端模拟、截图录屏等高级功能很多在Selenium中需要复杂操作实现的功能Playwright一行代码搞定。执行速度更快由于其架构设计通常执行速度比Selenium快。更好的跨浏览器一致性统一管理三大浏览器引擎行为一致性更高。一个简单的Playwright示例# 安装 pip install playwright # 然后运行 playwright install from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch(headlessFalse) # 自动使用配套的浏览器 page browser.new_page() page.goto(https://www.example.com) print(page.title()) browser.close()可以看到代码中完全没有驱动路径的概念。对于新项目或者对Selenium环境问题感到极度疲惫的团队评估并迁移到Playwright是一个值得认真考虑的选项。当然Selenium由于其历史久、社区大、语言绑定多Java, Python, C#, JavaScript等的优势在现有老项目和企业环境中依然占据主导地位。4.3 建立健壮的自动化脚本启动机制最后分享一个我个人在项目中使用的脚本启动封装它集成了一些健壮性检查。import os import sys import time from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from webdriver_manager.chrome import ChromeDriverManager import logging def create_driver(headlessTrue, user_data_dirNone): 创建一个健壮的Chrome WebDriver实例。 :param headless: 是否使用无头模式 :param user_data_dir: 自定义用户数据目录路径用于保存登录状态等 :return: WebDriver 实例 options Options() # 基础优化参数 options.add_argument(--disable-blink-featuresAutomationControlled) options.add_experimental_option(excludeSwitches, [enable-automation]) options.add_experimental_option(useAutomationExtension, False) if headless: options.add_argument(--headlessnew) # 使用新的Headless模式 options.add_argument(--no-sandbox) options.add_argument(--disable-dev-shm-usage) options.add_argument(--disable-gpu) options.add_argument(--window-size1920,1080) if user_data_dir: options.add_argument(f--user-data-dir{user_data_dir}) # 尝试使用webdriver-manager自动管理驱动如果失败则回退到指定路径 driver None try: service Service(ChromeDriverManager().install()) driver webdriver.Chrome(serviceservice, optionsoptions) logging.info(Driver created successfully using webdriver-manager.) except Exception as e1: logging.warning(fwebdriver-manager failed: {e1}. Trying fallback path...) # 回退方案假设驱动在项目根目录的 drivers 文件夹下 fallback_driver_path os.path.join(os.path.dirname(__file__), drivers, chromedriver) if sys.platform.startswith(win): fallback_driver_path .exe if os.path.exists(fallback_driver_path): try: service Service(executable_pathfallback_driver_path) driver webdriver.Chrome(serviceservice, optionsoptions) logging.info(Driver created successfully using fallback path.) except Exception as e2: logging.error(fFallback path also failed: {e2}) raise else: logging.error(fFallback driver not found at {fallback_driver_path}) raise FileNotFoundError(fChromeDriver not found in fallback location.) # 添加一些基本的脚本防止被一些网站检测为自动化工具可选 driver.execute_script(Object.defineProperty(navigator, webdriver, {get: () undefined})) return driver # 使用示例 if __name__ __main__: logging.basicConfig(levellogging.INFO) try: driver create_driver(headlessFalse) driver.get(https://www.baidu.com) time.sleep(3) print(driver.title) except Exception as e: logging.error(fFailed to run script: {e}) finally: if driver: driver.quit()这个函数做了几件事1) 使用webdriver-manager作为首选提高环境兼容性2) 提供了回退机制3) 集成了常用的反检测参数4) 结构清晰便于扩展其他浏览器或选项。将浏览器启动逻辑这样封装起来能让你的主业务代码更干净也更容易应对环境变化。