做 Web 自动化的人,恐怕都经历过这种场面:Selenium 装好了,Chrome 也在正常用,结果webdriver.Chrome()一跑,直接给我抛一个SessionNotCreatedException,或者干脆提示cannot find ChromeDriver binary。去网上搜 ChromeDriver 下载链接,出来的页面一个比一个乱,版本号和我本机的 Chrome 又永远对不上。这篇文章就把 ChromeDriver 各版本下载链接这件事一次性讲透,从版本匹配逻辑、官方目录结构到链接拼写规律、脚本批量取地址,按实战顺序走一遍。
1. 版本匹配是第一步:别让 Chrome 和 ChromeDriver 各说各话
很多人找不到正确的下载链接,根本原因是没搞明白 Chrome 和 ChromeDriver 的版本关系。这两者不是同一个软件,ChromeDriver 可以理解成 Chrome 的“遥控器”,Selenium 通过这个遥控器去指挥浏览器。既然是遥控器,频道必须对得上。
1.1 版本号四段位到底怎么对应
Chrome 的版本号通常是四段,比如114.0.5735.110或者128.0.6613.137。ChromeDriver 的版本号同样是四段。二者的对应规则并不复杂:
- 主版本号(第一段)必须一致。Chrome 是 114,ChromeDriver 就应该是 114.x.x.x,这是最基础的匹配条件。
- 后面三段尽量靠拢。Chrome 是
114.0.5735.110,ChromeDriver 用114.0.5735.90通常也没问题,因为补丁号差异一般不影响 WebDriver 协议。 - 如果找不到完全一样的版本,优先选主版本号相同、后面三位数最大的 ChromeDriver,而不是去跨版本下载。
我把常见匹配情况整理成了一张表,方便对照:
| 本机 Chrome 版本 | 理想 ChromeDriver 版本 | 兼容程度 |
|---|---|---|
| 114.0.5735.110 | 114.0.5735.90 | 推荐,多数场景可用 |
| 128.0.6613.137 | 128.0.6613.137 | 最省心 |
| 117.0.5938.149 | 116.x.x.x | 不推荐,可能有兼容问题 |
| 118.0.5993.70 | 117.0.5865.xx | 不建议 |
有些老教程建议“ChromeDriver 版本可以比 Chrome 低一个版本”,这在极少数旧版本里碰巧能跑,但遇到新版浏览器基本都会翻车。我自己的原则是:下载前先确认主版本号,主版本一致再谈其他。
1.2 三分钟确认本机 Chrome 版本
找到正确下载链接的第一步,是知道自己浏览器的版本。方法有几种:
- 在 Chrome 地址栏输入
chrome://version,第一行就是完整版本号。 - 点击右上角三个点,进入“帮助—关于 Chrome”,也能看到。
- Linux 下可以直接执行
google-chrome --version,macOS 执行/Applications/Google Chrome.app/Contents/MacOS/Google Chrome --version,Windows 的 Chrome 安装在C:\Program Files\Google\Chrome\Application\chrome.exe,可以直接看文件属性里的版本信息。
这里有个特别容易被忽略的地方:Chrome 默认开启自动更新。你今天查到的版本是127.0.6533.119,过两周可能就变成了131.0.6778.86。所以不要把版本号写死在笔记里,每次搭环境都要重新确认一遍。
1.3 版本不匹配时会看到什么
版本不匹配的报错很有辨识度,最常见的两类:
SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 116 Current browser version is 131.0.6778.86 with binary path ...另一种是:
WebDriverException: Message: unknown error: cannot find Chrome binary前一种说明 ChromeDriver 和 Chrome 主版本不一致,后一种说明 ChromeDriver 找到了,但找不到 Chrome 本体,属于路径配置问题。这两种问题的下载策略完全不同,前者要换 ChromeDriver 版本,后者要检查binary_location。
2. 官方下载链接的目录演进:115 版本是个分水岭
很多教程还在讲旧的下载地址,等你点进去一看,页面目录根本没有新版文件。这不能怪教程,ChromeDriver 的官方下载结构确实有过一次比较大的调整。
2.1 旧版目录:对应 115 之前的 ChromeDriver
在 Chrome 115 之前,ChromeDriver 的下载入口主要是官方文档页chromedriver.chromium.org/downloads,实际文件则托管在chromedriver.storage.googleapis.com下。打开这个地址能看到按版本号排列的目录,比如114.0.5735.90/、109.0.5414.74/。
旧版目录里没有平台子目录,平台标识直接体现在 zip 文件名中。比如:
chromedriver_win32.zip chromedriver_linux64.zip chromedriver_mac64.zip也就是说,如果你要下载的是 ChromeDriver 114 的 Windows 版本,对应的完整下载链接是这个形态:
https://chromedriver.storage.googleapis.com/114.0.5735.90/chromedriver_win32.zip注意文件名是chromedriver_win32.zip,用的是下划线,不是中划线。很多人在拼链接时就栽在这个细节上,复制文档里的 URL 没问题,自己手写就容易写错。
2.2 新版目录:115 及之后基本都在这里
从 Chrome 115 开始,官方把 ChromeDriver 归入了 Chrome for Testing 项目,下载地址也整体迁移。现在 115 之后的版本,主要从两个地址获取:
- 版本清单和最新版本号:
https://googlechromelabs.github.io/chrome-for-testing/ - 文件本体:
https://storage.googleapis.com/chrome-for-testing-public/
新版目录的结构比旧版清晰一些,先按版本号分目录,再按平台分子目录,最后才是 zip 包。比如:
https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/win64/chromedriver-win64.zip这里的路径规律非常明确:
https://storage.googleapis.com/chrome-for-testing-public/{版本号}/{平台目录}/chromedriver-{平台目录}.zip平台目录的值包括win32、win64、linux64、mac-x64、mac-arm64。注意新版文件名用的是中划线,和旧版的下划线不一样。
2.3 新老目录怎么选择
如果你追的浏览器版本比较新,直接用新版目录。如果你的项目还在维护老旧的自动化脚本,用的 Chrome 是 110 甚至更早,那就得去旧版目录找。有一点值得注意:新版目录理论上也覆盖了一部分旧版本资产,但老项目为了稳定,我建议优先用老版本对应的原始链接,不要轻易混用。
从目录演进能看出一个趋势:官方越来越希望用户通过版本清单接口去拿链接,而不是手动翻目录页。这也引出了后面要讲的脚本化下载思路。
3. 手工拼链接的技巧:一份链接格式速查表
即使官方给了页面,手动点击下载依然很费劲,尤其是要替不同同事下载不同版本时。学会拼链接之后,整个过程可以压缩到几十秒。
3.1 旧版通用链接格式
旧版 ChromeDriver 的链接格式非常固定:
https://chromedriver.storage.googleapis.com/{完整版本号}/chromedriver_{平台}.zip平台部分按操作系统填写:
- Windows:
win32 - Linux:
linux64 - macOS 英特尔:
mac64
举例:
https://chromedriver.storage.googleapis.com/114.0.5735.90/chromedriver_win32.zip https://chromedriver.storage.googleapis.com/114.0.5735.90/chromedriver_linux64.zip https://chromedriver.storage.googleapis.com/114.0.5735.90/chromedriver_mac64.zip3.2 新版通用链接格式
新版格式多了一层平台子目录:
https://storage.googleapis.com/chrome-for-testing-public/{完整版本号}/{平台}/chromedriver-{平台}.zip平台取值和旧版不同,要特别留意:
| 操作系统 | 平台目录 | 文件名 |
|---|---|---|
| Windows 32 位 | win32 | chromedriver-win32.zip |
| Windows 64 位 | win64 | chromedriver-win64.zip |
| Linux 64 位 | linux64 | chromedriver-linux64.zip |
| macOS 英特尔 | mac-x64 | chromedriver-mac-x64.zip |
| macOS Apple Silicon | mac-arm64 | chromedriver-mac-arm64.zip |
举例:
https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.86/linux64/chromedriver-linux64.zip https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.86/mac-arm64/chromedriver-mac-arm64.zip一个容易搞混的地方是:新版目录里版本号后面紧跟平台目录,但平台目录名和 zip 文件名几乎一样,只差一个中划线或下划线。写链接时不要凭感觉,拿一个已知链接对比着改。
3.3 用 curl 直接拉取压缩包
拼好链接后,用curl下载最省事。以新版 Linux 64 位为例:
curl -L -o chromedriver.zip \ "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.86/linux64/chromedriver-linux64.zip"Windows 上如果安装了 curl,同样可以执行。-L参数不能省,因为storage.googleapis.com的请求经常会有 301 跳转,少了这个参数会下载到空文件或重定向提示页。
PowerShell 用户也可以用Invoke-WebRequest:
$url = "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.86/win64/chromedriver-win64.zip" Invoke-WebRequest -Uri $url -OutFile chromedriver.zip下载完成后别急着解压,先看一眼文件大小。正常 zip 包在几 MB 到十几 MB 之间,如果只有几百字节,八成是链接拼错了。
4. 用公开 JSON 批量获取各版本下载地址
手动拼链接适合一次性下载,但如果你在维护一套测试环境,隔三差五就要换个版本,那就得让操作自动化。Chrome for Testing 项目其实已经提供了机器可读的版本清单,不需要写爬虫去抓网页。
4.1 known-good-versions-with-downloads.json 里有什么
官方维护了一个 JSON 文件,记录了各版本的下载地址:
https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json这个文件比较大,因为它包含的版本数非常多。整体结构类似下面这样:
{ "timestamp": "2025-01-15T03:42:11.753Z", "versions": [ { "version": "131.0.6778.86", "revision": "1234567", "downloads": { "chrome": [], "chromedriver": [ { "platform": "linux64", "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.86/linux64/chromedriver-linux64.zip" } ] } } ] }注意downloads对象里除了chromedriver,还有chrome字段。如果你不想用本机装的 Chrome,可以直接从这个 JSON 里拿“配套版 Chrome”的下载链接,这样就完全不用考虑自动更新带来的版本漂移问题了。
4.2 用 Python 脚本查版本、拼链接、直接下载
我一般用 Python 写个短脚本,先读 JSON,再按主版本号过滤。下面这个例子会列出 131 开头的所有 ChromeDriver 下载地址:
import json import urllib.request url = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json" data = json.load(urllib.request.urlopen(url)) for version_item in data["versions"]: version = version_item["version"] if version.startswith("131."): for driver in version_item["downloads"].get("chromedriver", []): print(version, driver["platform"], driver["url"])如果只想取 131 主版本里最新的那一个,可以在循环里记录第一个匹配项后break,因为接口返回的版本列表默认按时间倒序排列,最前面的就是最新版本。
拿到 URL 后,可以直接结合上一节的 curl 思路,把下载和解压一起处理。下面是一个更完整的 Linux 示例脚本:
#!/usr/bin/env bash set -e MAJOR=$1 DRIVER_VERSION=$(curl -s "https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_${MAJOR}") echo "当前 ${MAJOR} 主版本的最新 ChromeDriver 版本号:${DRIVER_VERSION}" DOWNLOAD_URL="https://storage.googleapis.com/chrome-for-testing-public/${DRIVER_VERSION}/linux64/chromedriver-linux64.zip" curl -L -o chromedriver.zip "$DOWNLOAD_URL" unzip -o chromedriver.zip sudo mv chromedriver-linux64/chromedriver /usr/local/bin/ chmod +x /usr/local/bin/chromedriver这个脚本里用到了LATEST_RELEASE_${MAJOR}这个接口。它的存在很有用,比如我想拿 130 主版本的最新 ChromeDriver,直接访问:
https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_130返回的是一行文本,比如130.0.6723.91,非常适合用于自动化安装。另有LATEST_RELEASE_STABLE可以获取当前全局稳定版版本号。
4.3 为什么我建议固定版本而不是追“最新”
很多自动化项目习惯每次运行前拉取最新版 ChromeDriver,这样确实能省去维护成本,但也带来了新的不稳定因素:浏览器更新后,页面渲染行为可能变化,测试结果会出现“刚才还过,现在挂”的假性失败。
我的做法是:每个项目锁一个 ChromeDriver 版本,比如固定130.0.6723.91,同时让 Chrome 使用 Chrome for Testing 里同版本的包,两头都固定。升级版本是主动行为,而不是被动等浏览器自动更新。这样做不是怕新技术,而是让每次环境变化都处在可控状态。
5. 下载之后的验证与排错:解压只是开始
链接拿到了,压缩包也下载好了,但这只是开始。很多人卡在“下载完却仍然启动失败”,往往不是版本问题,而是操作系统层面的路径或权限问题。
5.1 不同系统的解压和路径配置
Windows
解压 zip 后得到一个chromedriver.exe,我习惯放在固定目录,比如C:\webdriver\。不需要把整个 zip 内容分散到系统目录,只要让 selenium 能找到 exe 路径就行。最稳妥的方式是把C:\webdriver加入系统环境变量 PATH,这样代码里不用写绝对路径。
配置 PATH 后务必重新打开命令行窗口,否则新配置不生效,这是个特别容易踩的坑。
Linux
Linux 下解压后需要手动加执行权限:
unzip chromedriver-linux64.zip sudo mv chromedriver-linux64/chromedriver /usr/local/bin/ sudo chmod +x /usr/local/bin/chromedriver如果不执行chmod +x,启动时会提示权限不够,看起来像版本不匹配,其实是文件没有执行权限。
macOS
macOS 新版系统对非 App Store 应用有隔离属性。下载后双击解压,第一次运行可能提示“无法验证开发者”。遇到这种情况,可以右键点“打开”一次,或者手动移除隔离属性:
xattr -d com.apple.quarantine /usr/local/bin/chromedriver5.2 版本和启动验证命令
不管什么系统,解压后的第一件事是跑chromedriver --version,看看输出的版本号是否和预期一致:
chromedriver --version正常输出类似:
ChromeDriver 131.0.6778.86 (0000000000000000000000000000000000000000-refs/branch-heads/6778@{#1})如果这个命令都跑不通,说明 PATH 或文件本身有问题,和 selenium 代码无关,先把这一步解决。
接下来再写一个最小化脚本验证浏览器能真正起来:
from selenium import webdriver from selenium.webdriver.chrome.service import Service service = Service("/path/to/chromedriver") driver = webdriver.Chrome(service=service) driver.get("https://example.com") print(driver.title) driver.quit()如果这段能跑通,说明 ChromeDriver 下载、解压、路径配置全部没问题。
5.3 实测过程中最常见的 5 个坑
我在不同操作系统上帮别人排查过太多次类似问题,总结出下面几个高发原因:
| 现象 | 直接原因 | 解决办法 |
|---|---|---|
启动报This version of ChromeDriver only supports Chrome version 116 | ChromeDriver 与 Chrome 主版本不一致 | 下载匹配的 ChromeDriver 版本 |
启动报cannot find Chrome binary | ChromeDriver 找到但找不到 Chrome 本体 | 在代码里指定binary_location |
卡在Timed out waiting for driver server to start | chromedriver 路径错误、权限不足或端口被占用 | 检查文件路径、加执行权限、关闭残留进程 |
| 有多个 ChromeDriver 在 PATH 中 | 不同项目装了不同版本,命令解析到了旧版本 | 用which chromedriver定位,按项目单独指定路径 |
| 自动化跑一段时间后突然全部失败 | Chrome 自动更新,版本号变了 | 固定 Chrome for Testing 版本或重新下载匹配 driver |
关于端口占用要特别说明:ChromeDriver 默认监听9515端口,如果前一个脚本异常退出,端口可能被残留进程占用。Windows 下可以用任务管理器结束chromedriver.exe,Linux 下执行:
pkill -f chromedriver然后再跑脚本。
6. 几个让我少走弯路的日常习惯
最后聊几个实际操作层面的习惯。它们不复杂,但能避免大量无效下载和排查时间。
第一个习惯是永远不要只把下载链接存在浏览器收藏夹里。收藏夹里的链接很可能只是当时那个版本的页面,Chrome 一旦自动更新,链接马上失效。我现在的做法是维护一个简单的版本速查文档,里面记录当前项目依赖的 Chrome 版本、ChromeDriver 版本和对应下载地址格式,每次只改版本号,不重新找链接。
第二个习惯是尽量用脚本而不是手动下载。哪怕是单次部署,我也会先执行一条 curl 或 Python 命令拿到版本号,再下载。这样一旦出问题,历史命令里能看到当时用的是哪个版本,方便回溯。下面这个命令可以直接查看当前稳定版 ChromeDriver 版本号:
curl -s "https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_STABLE"第三个习惯是不要在一个环境里同时放置多个主版本的 ChromeDriver。多个版本文件同时存在于 PATH 中,很容易取到错误的那个。如果你的项目需要同时跑不同版本的浏览器,我建议在 selenium 代码里显式指定executable_path,而不是依赖系统 PATH。这也解释了为什么在 CI 环境里,我更倾向于写一个下载脚本来按项目需求精确布置对应版本,而不是让所有任务都去找同一个路径下的单一 chromedriver。
还有一点值得提醒:ChromeDriver 是持续更新的,新版本会修复一些协议兼容问题,但也会调整默认行为。如果你在升级 ChromeDriver 后遇到从未见过的报错,先不要急着怀疑浏览器,仔细核对chromedriver --version输出和 chromechrome://version的版本号,通常问题都出在这里。