ChromeDriver版本不匹配?Python+Selenium环境整合包配置详解
简介谷歌浏览器105.0.5195.102稳定版与其匹配的Chromedriver驱动已打包成整包可整体放入Python项目使用面向需要快速搭建Selenium网页自动化环境的开发者解决浏览器与驱动版本难匹配、项目部署后需重新配置路径等棘手问题。压缩包共103个文件体积约152.05MB文件类型分布清晰包括58个pak界面资源、12个dll运行库、8个exe程序模块、8个png图标以及json、sig等辅助配置覆盖浏览器运行所需组件与常规浏览器安装目录结构基本一致。通过示例中的相对路径即可加载chrome.exe与chromedriver.exe项目迁移或打包时无需额外安装浏览器特别适合交付给他人运行。目前已有730人学习下载。读者可直接复用这套整合包免去手动下载、版本对比和PATH设置也可借鉴其目录组织方式将完整浏览器组件内置到自动化工具中提高项目的可移植性与稳定性。1. 先把版本匹配这件事说透做 Python 自动化的人十个里有八个在 ChromeDriver 上翻过车。你写好了一个 selenium 脚本跑起来却报SessionNotCreatedException一行行看全是“This version of ChromeDriver only supports Chrome version xxx”——浏览器昨天还能用今天就废了。问题多半不在代码而在浏览器和驱动版本错位。谷歌浏览器和对应版本驱动的整合包就是把 Chrome 的安装版和匹配的 Chromedriver 打包在同一个压缩包里解压即用从源头隔绝这种“版本玄学”。这套环境是 PythonSelenium 自动化测试和网页抓取的刚需脚本要在浏览器里模拟点击、填表、截图驱动是浏览器和代码之间的桥。桥搭错了脚本全崩。这篇文章适合两类人一类是刚配环境的新手照着就能把环境跑通另一类是已经被版本折腾过的熟手我这里把参数取舍和常见坑一次说清。2. 版本对应规则为什么 ChromeDriver 必须跟着 Chrome 走2.1 主版本一致是一道硬门槛ChromeDriver 不是随便配一个就能用的。它和 Chrome 之间有一条明确的对应规则驱动的主版本号必须和浏览器的主版本号一致。Chrome 是 128那 Chromedriver 就必须是 128.0.xxxx浏览器是 114驱动也得 114.0.xxxx。这个规则已经存在很多年Selenium 从 3 到 4 代代没变过。为什么设计成这么严苛因为 ChromeDriver 要和浏览器内部的自动化协议做对接浏览器每次大版本升级协议细节就会变驱动不跟着更新就听不懂浏览器的话。小版本号可以不逐一对应——浏览器 128.0.6613.120 配驱动 128.0.6613.36 通常能跑但主版本号差了协议直接对不上这是硬门槛。浏览器主版本驱动主版本能否运行Chrome 128ChromeDriver 128.x可以Chrome 128ChromeDriver 125.x报 SessionNotCreatedChrome 121ChromeDriver 121.x可以这套规则听起来简单实际维护起来很烦。Chrome 默认开了自动更新今天还是 127下周悄悄变成 128你手里的驱动还停在 127脚本就废了。这也是我一直推荐用整合包的原因整合包把特定版本的浏览器和对应驱动绑在一起浏览器被打包成固定版本不接收自动更新驱动和浏览器永远在同一水平线上。2.2 三步查到当前浏览器的准确版本号如果你手里已经有一份乱配的驱动先别急着重装第一步是搞清楚当前浏览器到底是什么版本。别去点“关于 Chrome”那个页面它动画慢不说有时还要等几秒才显示。直接看版本号更快。# Linux/Mac 下如果你用的是系统安装的 chrome google-chrome --version # Windows 下进入 Chrome 安装目录后执行 chrome.exe --version # 或者用 PowerShell 直接查 (Get-Item C:\Program Files\Google\Chrome\Application\chrome.exe).VersionInfo.FileVersion上面的命令输出Google Chrome 128.0.6613.120这样的字符串取第一个数字 128 作为主版本号。Windows 下路径不同的话先看下 Chrome 安装到哪里多数情况在Program Files或Program Files (x86)里。还有一种更省事的查法在浏览器地址栏直接输入chrome://version/回车页面第一行就写着完整版本号。这个方法最不容易出错不管你是 Windows、Mac 还是 Linux打开就能看到。拿到版本号之后再去对照你手里的 Chromedriver 版本chromedriver --version # 输出类似 ChromeDriver 128.0.6613.36两条命令的输出越靠拢环境越安全。如果驱动版本是 127 开头浏览器是 128趁早换驱动别抱有侥幸心理。2.3 整合包的价值点版本匹配这件事让包替你解决单独下载 Chrome 和单独下载 ChromeDriver 都不难难的是让两者保持匹配。很多人图省事直接 pip 装 selenium再用webdriver.Chrome()裸跑Selenium 4.6 之后的版本确实自带 Selenium Manager 能自动找驱动但它的前提是机器能访问外网下载驱动。离线环境、内网环境或者公司网络有严格限制的情况下这套自动机制直接就失效了。整合包解决的正是这个痛点。压缩包里有一个固定版本的 Chrome 和与之匹配的 ChromeDriver两者的版本已经预先核对过。你不需要去记版本对应表也不需要担心自动更新破坏环境Chrome 是打包好的独立版本不跟随系统的自动更新走版本钉死在某一个大版本上。ChromeDriver 是同一版本的配套驱动两者出厂就是匹配的。整个环境可以复制到别的机器目录结构不变配置不丢。我一般会把整合包解压后固定放在一个工具目录里比如D:\tools\或者~/selenium/然后写脚本时显式指定这两个路径。这样做的好处是不管这台机器上还装着什么版本的官方 Chrome都不影响我脚本运行。因为 selenium 启动的是我指定的这个浏览器而不是 PATH 里那个默认的 Chrome。3. 整合包落地解压、目录规划与路径配置3.1 目录结构不规划好后面全是玄学从整合包解压出来通常就是两个大目录外加一个说明文件。我先给出一份我常用的目录规划照着摆就能少踩很多坑D:\tools\ └── selenium-env\ ├── chrome\ │ ├── chrome.exe │ ├── chrome.dll │ └── (其他运行文件) ├── chromedriver\ │ └── chromedriver.exe ├── scripts\ │ ├── demo.py │ └── check_env.py └── README.md注意几个细节。chrome\目录放的是浏览器本体里面必须有chrome.exe这个可执行文件chromedriver\目录只有几十 MB里面就一个chromedriver.exe。两个目录最好平级不要嵌套。很多人图省事把 chromedriver.exe 直接丢进 chrome 目录这在跑脚本时倒不算致命但后续维护时很难分清哪个文件属于谁。路径中不要带中文和空格这是我反复强调的一点。Windows 下虽然带空格也能运行但 selenium 的Service在解析路径时偶尔会出问题Linux 下更不用说一行路径崩整个脚本。整合包解压后第一件事就是把两个目录挪到你自己的工具目录下别在下载文件夹里直接开跑——下载文件夹路径通常既有用户名又有空格早晚出问题。3.2 三条路径各管各的别搞混这套环境里其实有三条路径长得像但作用完全不同。搞混了就是各种「找不到文件」「不是有效的 Win32 应用」的报错来源。第一条浏览器路径binary_location。指向chrome.exe所在的完整路径selenium 靠它找到要启动的浏览器程序。配置方式是options.binary_location。第二条驱动路径service。指向chromedriver.exeselenium 靠它启动一个中间代理进程驱动浏览器。现在的 Selenium 4 里用Service类传入。第三条PATH 环境变量。如果不显式指定前两条路径selenium 默认去 PATH 里找chromedriver。上面两条是精确指定第三条是兜底。先看驱动路径怎么放到 PATH 里。Windows 下打开系统环境变量编辑窗口在Path一栏点新建把D:\tools\selenium-env\chromedriver加进去——注意加到chromedriver目录那一级不是到chromedriver.exe文件那一级。这是个最典型的错误有人直接把 exe 文件完整路径加进 PATH然后怎么配都报错因为系统要求的是目录。# Windows 命令行里用 setx 设置以管理员身份运行 setx PATH %PATH%;D:\tools\selenium-env\chromedriver /M用/M参数表示修改系统级环境变量不加就是改用户级。这个命令有个众所周知的坑setx会把变量截断到 1024 字符如果你原本的 PATH 已经很长加完这一条后面的内容可能被吞掉。所以我一般先在命令行里执行echo %PATH%看一眼长度太长了就直接用图形界面改。3.3 环境变量修改后如何让新终端生效改完环境变量并不是立刻全部生效。你正在开着的那个终端窗口里面的 PATH 是启动时读进来的已经不会变了。只有新打开的终端才会拿到新值。所以配完环境变量第一件事是全部关掉终端重开不是开一个新标签页——有些终端复用进程新标签页里还是旧 PATH。验证是否生效直接执行chromedriver --version如果能输出ChromeDriver 128.0.6613.36之类的版本信息说明 PATH 生效了。如果提示“不是内部或外部命令”说明路径没配进去或者没重开终端。还有一种情况比较隐蔽命令行里设置过当前会话的 PATH比如跑过一句set PATHD:\tools\selenium-env\chromedriver;%PATH%。这个只在当前窗口有效窗口一关就没了。下次新终端里照样找不到 chromedriver。如果你在自己机器上反复出现“刚才还能跑现在又不能跑了”十有八九就是这个原因。4. Python Selenium 联动让浏览器真正跑起来4.1 先装 selenium用虚拟环境隔离依赖驱动和浏览器就位后Python 那边需要安装 selenium 库。这里强烈建议建一个虚拟环境别直接装到系统 Python 里。Selenium 迭代速度快今天装一个版本明天另一个项目需要不同版本系统级的依赖冲突会浪费你半天时间。# 在工作目录下创建并激活虚拟环境 cd D:\tools\selenium-env python -m venv venv # Windows 下激活 venv\Scripts\activate # Linux/macOS 下激活 # source venv/bin/activate # 安装 selenium指定版本更稳妥 pip install selenium4.21.0 # 导入测试 python -c import selenium; print(selenium.__version__)上面最后一条命令能打印版本号就说明安装成功。python -m venv venv会在当前目录创建一个venv子目录里面是一套独立的 Python 环境。激活后你的命令行提示符前面应该出现(venv)前缀。为什么指定版本而不是直接pip install selenium因为 selenium 大版本之间有 API 差异。比如webdriver.Chrome()里的executable_path参数在 Selenium 4 里被废弃了挪到了Service里你要是照着 Selenium 3 的老教程写代码会拿到一个 DeprecationWarning 或者直接报 TypeError。指定版本能让你的代码和教程对得上。4.2 第一个自动化脚本打开页面拿标题环境装好了写第一个脚本。这个脚本做了三件事启动浏览器、打开一个本地 HTML 页面、打印页面标题。用本地页面而不是外网页面是为了排除网络干扰——如果脚本没跑起来那一定是环境问题不是网络问题。from selenium import webdriver from selenium.webdriver.chrome.service import Service # 指定驱动和浏览器的绝对路径 service Service(rD:\tools\selenium-env\chromedriver\chromedriver.exe) options webdriver.ChromeOptions() options.binary_location rD:\tools\selenium-env\chrome\chrome.exe # 启动浏览器 driver webdriver.Chrome(serviceservice, optionsoptions) try: driver.get(file:///D:/tools/selenium-env/scripts/test.html) print(页面标题:, driver.title) finally: driver.quit()代码里Service负责管理 chromedriver 进程options.binary_location指定 Chrome 程序位置。这两行是这套环境的关键——显式指定路径绕开 PATH 和默认位置的干扰。driver.get()可以是完整 URL也可以是file:///协议开头本地文件路径。finally里的driver.quit()保证浏览器一定被关掉即使前面代码抛异常也不会留下僵尸进程。运行后你会看到浏览器窗口短暂弹出又关闭终端打印出页面标题。到这里说明浏览器、驱动、Python 三方已经打通了。4.3 无头模式与超时参数让自动化更稳实际业务中我们通常不需要每次都弹出浏览器窗口尤其跑批量任务的时候窗口弹来弹去很影响其他工作。无头模式就是让浏览器在后台运行不显示界面效率和稳定性反而更高。from selenium import webdriver from selenium.webdriver.chrome.service import Service options webdriver.ChromeOptions() options.binary_location rD:\tools\selenium-env\chrome\chrome.exe options.add_argument(--headlessnew) # 新版无头模式 options.add_argument(--disable-gpu) options.add_argument(--window-size1920,1080) service Service(rD:\tools\selenium-env\chromedriver\chromedriver.exe) driver webdriver.Chrome(serviceservice, optionsoptions) driver.set_page_load_timeout(15) # 页面加载超时控制--headlessnew是 Chrome 109 之后的推荐写法旧版的--headless参数虽然还能用但行为上有差异。--disable-gpu在 Windows 下是常见的稳定性补丁因为无头模式下 GPU 渲染没有意义还容易触发奇怪的崩溃。--window-size指定窗口尺寸有些页面在窄视口下会走响应式布局拿到的页面元素和截图会不对。set_page_load_timeout设成 15 秒防止某个页面卡住导致整个脚本无限等待。一个重要的参数取舍是无头模式和普通模式的行为并不完全一致。有些网站能检测出无头模式特征从而改变返回的页面内容。所以调试脚本时先用有头模式跑通逻辑再加无头参数跑正式任务这是我一直推荐的做法——不要一上来就--headless那样你根本看不到页面到底发生了什么。5. 避坑排查ChromeDriver 最常见的五个翻车现场配置这环境一年半载谁手里没有几笔血泪账。下面五个问题是我自己踩过、也帮别人排过无数次的按出现频率排基本覆盖了九成以上的启动故障。5.1 现象SessionNotCreatedException 报错提示驱动版本和浏览器版本不兼容报错长这样SessionNotCreatedException: This version of ChromeDriver only supports Chrome version 114。原因浏览器或驱动有一方被换了版本。最常见是 Chrome 自动更新一夜之间从 113 变成了 114你手里的 chromeDriver 还停留在 113。也可能你同事解压了一份新整合包但他的 Chrome 和你的不是同一个版本。解决第一步按照 2.2 节的方法分别查两个版本号。确认不一致后二选一要么找到和浏览器匹配的驱动要么用整合包把浏览器换回驱动对应的版本。如果你是老手想快速恢复直接把整合包里的 chromedriver 替换掉当前驱动。但我的习惯是——固定浏览器版本。把 Chrome 自动更新关掉或者干脆始终用整合包里的浏览器这样以后永远不会再遇到“一觉醒来环境坏了”的早晨。5.2 现象任务管理器里躺着好几个 chromedriver.exe机器越来越卡跑过一次脚本之后任务管理器里残留了五六个 chromedriver 进程杀都杀不完。原因脚本里调用了driver.close()而不是driver.quit()或者干脆没关。close()只关当前标签页浏览器进程和驱动进程还活着quit()才是一键全部关掉。另外脚本中途异常退出时资源没有被释放也会残留。解决代码里所有driver的结束位置必须用driver.quit()。为了让异常退出时也能执行这行必须写try/finally就像 4.2 节那样。如果已经残留了一堆进程命令行执行taskkill /F /IM chromedriver.exe全部清掉。从那以后我的所有脚本模板都长一个样创建 driver 后后面永远跟一个try/finally这是底线。5.3 现象浏览器窗口刚弹出就闪退报错说 Chrome 未能启动报错信息里能看到Process unexpectedly closed或者其他连接相关的内容窗口一闪而过。原因这类问题的典型原因有三个。第一binary_location路径写错指向了不存在的 exe 或者系统里别的 Chrome 快捷方式。第二端口被占用ChromeDriver 启动时需要找空闲端口和浏览器通信遇到占用就直接放弃。第三有个常被忽略的原因——和系统 Chrome 的冲突如果你 PATH 里能解析到另一个 Chrome两个浏览器实例会抢占用户数据目录。解决先确认binary_location是否是整合包内 chrome.exe 的绝对路径。再检查端口命令行netstat -ano | findstr 9515默认端口 9515 被谁占了找到对应 PID 杀掉。最后给浏览器配一个独立的用户数据目录加参数--user-data-dirD:\tools\selenium-env\chrome-profile能有效避开系统 Chrome 的目录锁冲突。5.4 现象chromedriver.exe 被安全软件隔离脚本报找不到驱动脚本本来跑得好好的某天突然报chromedriver路径错误到目录下一看chromedriver.exe消失了。原因杀毒软件或者 Windows Defender 把chromedriver.exe识别为可疑程序直接隔离删除。ChromeDriver 本质是个通过本地端口控制浏览器的程序行为特征和木马确实有些相似所以被误杀是家常便饭。解决把这个驱动所在的目录加入杀毒软件的白名单。Windows Defender 的操作路径是设置 → 病毒和威胁防护 → 排除项添加文件夹。另外如果你用的是从整合包里解压出来的驱动建议把整合包原文留一份备份万一被清掉可以重新解压。这种事发生一次就是宝贵经验——光备份脚本不备份驱动等于没备份。5.5 现象setx 配置了 PATH重开终端还是找不到 chromedriver执行chromedriver --version依然提示“不是内部或外部命令”但环境变量里的值明明已经加进去了。原因三个常见原因。一是setx命令把 PATH 截断了你新追加的值被系统拼接到一个被截断的字符串后面实际不生效。二是环境变量加错了位置——加到了用户变量而不是系统变量刚好你当前命令行是以管理员身份打开的读的系统变量不认用户变量。三是开了终端还是没有重开或者打开方式不对。解决先用echo %PATH%看看有没有你加的那一段。如果后面被截断放弃 setx改用“系统属性 → 环境变量”图形界面编辑手打进去稳妥得多。确认加对位置后彻底关闭所有终端窗口重新打开再执行验证命令。还有一种情况是你从开始菜单点开终端时用的不是最近的终端实例关了重开即可。6. 验证跑通一版脚本确认整套环境6.1 一条命令跑完的验证脚本所有配置都做完最后不是去跑业务脚本而是先跑一段专门验证环境的脚本。这段脚本的作用是一次性确认浏览器存在、驱动存在、Python 里 selenium 能导入、三者能协作启动。# 分别确认三个组件 chromedriver --version python -c import selenium; print(selenium, selenium.__version__)这段命令能跑完只说明组件各自就位。真正检验协作的是跑一个最小化脚本——打开本地页面拿到标题整个过程控制在三秒以内from selenium import webdriver from selenium.webdriver.chrome.service import Service import sys service Service(rD:\tools\selenium-env\chromedriver\chromedriver.exe) options webdriver.ChromeOptions() options.binary_location rD:\tools\selenium-env\chrome\chrome.exe options.add_argument(--headlessnew) driver webdriver.Chrome(serviceservice, optionsoptions) driver.set_page_load_timeout(10) driver.get(file:///D:/tools/selenium-env/scripts/test.html) assert driver.title 测试页, 标题不是测试页 print(标题:, driver.title) driver.quit() print(环境验证通过)跑完看到环境验证通过整套环境就是可用的。如果在中途某一步报错按报错位置判断Service初始化失败查 chromedriver 路径Chrome启动失败查binary_locationget超时查 test.html 是否存在。6.2 把验证写进日常习惯环境验证这件事很多人吃过亏后才想起做。我的习惯是每台新机器、每次解压新整合包、每回换版本第一件事永远是跑这条验证命令通过之后再写业务逻辑。业务脚本会变验证脚本永远是这个最小化的版本。这样做的价值在于环境出问题时你能立刻判断是环境的问题而不是跑到半路才发现白白排查一两个小时的代码逻辑。我希望这套搭建思路能帮你把 Chrome、Chromedriver、Python、Selenium 的组合一次配好把时间留给真正要做的自动化任务少在装环境上耗力气。本文还有配套的精品资源点击获取