☰
ChromeDriver与Chrome版本对齐实战:Win64环境配置与避坑指南
2026/10/3 14:52:39 网站建设 项目流程

简介:本资源为Windows 64位系统下的ChromeDriver与Chrome浏览器配套安装包,面向使用Selenium框架开展Web自动化测试的开发者与测试工程师,可解决浏览器驱动与浏览器版本不匹配导致的兼容性问题。压缩包共84个文件,约150.08MB,包含chromedriver.exe驱动主程序、chrome.exe等6个可执行文件、11个dll动态链接库、58个pak语言与界面资源文件,以及json、bin、manifest等配置与快照文件,覆盖驱动与浏览器运行所需的完整组件。其中ChromeDriver版本为123.0.6312.122,与配套Chrome版本严格对应,便于直接部署到测试环境。已有324人学习下载。读者可据此快速搭建稳定的自动化测试环境,省去逐一下载与版本比对的时间,并借助目录结构理解Chrome运行所需的核心文件构成,为后续编写脚本、排查驱动启动失败等问题提供参考。

1. ChromeDriver+Chrome(win64):版本对齐这件事,比装驱动本身更要命

在 Windows 64 位机器上跑 Selenium,十次启动失败里有七次不是代码写错了,而是 ChromeDriver 和 Chrome 浏览器的版本没对上。你敲下webdriver.Chrome(),控制台甩出一行session not created: This version of ChromeDriver only supports Chrome version XX,然后整个自动化流程卡死在第一行。这个场景做爬虫、做 UI 自动化、做 RPA 的人都遇到过。

ChromeDriver 是 Chrome 官方提供的 WebDriver 实现,本质是一个独立进程,Selenium 通过它向 Chrome 发送 DevTools 协议指令。它和 Chrome 之间是强版本绑定关系:Chrome 136 需要 ChromeDriver 136,Chrome 154 需要 ChromeDriver 154,主版本号必须一致,次版本号尽量贴近。win64 这个限定意味着你要拿的是chromedriver-win64.zip,而不是 32 位或 Mac 版。这篇内容解决的就是:在 Windows 64 位环境下,怎么把 ChromeDriver 和 Chrome 配成一对能稳定干活的组合,包括下载、版本匹配、路径配置、参数调优和翻车排查。

2. 版本匹配:ChromeDriver 对应版本到底怎么查、怎么选

2.1 先搞清楚你机器上的 Chrome 是哪个版本

很多人上来就去搜「chromedriver 下载」,结果下了一个和本机 Chrome 对不上的版本。第一步永远是先确认本机 Chrome 的精确版本号。打开 Chrome,地址栏输入chrome://version/,第一行就是完整版本,比如136.0.7103.114。这个号要完整记下来,主版本 136 决定了你该下哪个大版本的 ChromeDriver。

如果你是在服务器或 CI 环境里跑,Chrome 可能是静默安装的,没有图形界面。这时候用命令行查:

# 方法一:查注册表(Windows) reg query "HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon" /v version # 方法二:直接查 Chrome 可执行文件的版本信息 wmic datafile where name="C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" get Version /value

注册表查询走的是BLBeacon键,这个键在 Chrome 安装时写入,记录当前用户级别的版本号。wmic那条走的是文件版本信息,适合 Chrome 装在非默认路径的情况。两条命令拿到的版本号应该一致,如果不一致,说明你机器上有多份 Chrome 安装,后面配置路径时要特别小心。

2.2 ChromeDriver 下载地址与版本选择策略

确认了 Chrome 版本之后,去 ChromeDriver 的官方发布页找对应版本。常见做法是访问 Chrome for Testing 的版本索引,那里按版本号列出了所有可下载的 ChromeDriver 包。文件名格式是chromedriver-win64.zip,解压后得到chromedriver.exe。

版本选择有个原则:主版本必须完全一致,次版本尽量一致,补丁版本可以略有差异。比如你的 Chrome 是136.0.7103.114,那 ChromeDriver 选136.0.7103.x最稳。如果找不到完全一致的补丁版本,选同主版本里最新的那个通常也能跑,但偶尔会遇到协议不兼容的玄学问题。

Chrome 版本推荐 ChromeDriver 版本风险等级
136.0.7103.114136.0.7103.x低
136.0.7103.114136.0.7049.x中,可能报协议错误
136.0.7103.114135.x.x.x高,大概率启动失败
136.0.7103.114137.x.x.x高,方向反了同样失败

还有一种情况:你的 Chrome 设置了开机自启,后台悄悄更新到了新版本,而你本地 ChromeDriver 还是旧的。这种「Chrome 自己偷偷升级」是自动化脚本突然挂掉的头号嫌疑。建议在 CI 环境里锁定 Chrome 版本,关闭自动更新。

2.3 用 Python 代码自动做版本匹配

手动查版本、手动下载、手动解压,做一次可以,做十次就是浪费时间。我一般会写一个启动脚本,自动检测 Chrome 版本并匹配合适的 ChromeDriver。核心逻辑是用subprocess读注册表拿版本号,然后去本地缓存目录找对应的 driver,找不到再触发下载。

import subprocess import re import os import zipfile import urllib.request def get_chrome_version(): """从 Windows 注册表读取 Chrome 版本号""" try: output = subprocess.check_output( ['reg', 'query', r'HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon', '/v', 'version'], stderr=subprocess.DEVNULL ).decode() # 输出格式: " version REG_SZ 136.0.7103.114" match = re.search(r'REG_SZ\s+([\d.]+)', output) if match: return match.group(1) except subprocess.CalledProcessError: pass return None def get_major_version(full_version): """提取主版本号,136.0.7103.114 -> 136""" return full_version.split('.')[0] def find_local_driver(major_version, cache_dir='./drivers'): """在本地缓存目录查找匹配的 chromedriver""" driver_path = os.path.join(cache_dir, f'chromedriver_{major_version}.exe') if os.path.exists(driver_path): return driver_path return None def download_driver(major_version, cache_dir='./drivers'): """下载指定主版本的 ChromeDriver win64 包""" os.makedirs(cache_dir, exist_ok=True) # Chrome for Testing 的版本索引地址 base_url = f'https://storage.googleapis.com/chrome-for-testing-public' # 实际使用时需要先请求 known-good-versions 接口拿到精确版本号 # 这里展示的是下载和解压的核心逻辑 zip_path = os.path.join(cache_dir, f'chromedriver-win64-{major_version}.zip') # urllib.request.urlretrieve(download_url, zip_path) with zipfile.ZipFile(zip_path, 'r') as zf: # 包内路径是 chromedriver-win64/chromedriver.exe zf.extract('chromedriver-win64/chromedriver.exe', cache_dir) src = os.path.join(cache_dir, 'chromedriver-win64', 'chromedriver.exe') dst = os.path.join(cache_dir, f'chromedriver_{major_version}.exe') os.rename(src, dst) return dst if __name__ == '__main__': ver = get_chrome_version() print(f'本机 Chrome 版本: {ver}') major = get_major_version(ver) driver = find_local_driver(major) if driver: print(f'使用本地缓存驱动: {driver}') else: print(f'本地无 {major} 版本驱动,需要下载')

这段代码的关键点有三个:get_chrome_version走注册表而不是文件路径,避免 Chrome 装在非默认目录时找不到;find_local_driver用主版本号做缓存键,同一个大版本下换小版本不用重新下载;download_driver里解压后的路径是chromedriver-win64/chromedriver.exe,这是官方包的固定结构,不要搞错层级。

参数方面,cache_dir建议放在项目根目录下的drivers/里,不要放系统临时目录,否则 CI 每次跑都要重新下。major_version只取主版本号是权衡后的选择——补丁版本差异通常不影响运行,但主版本差异一定出问题。

3. 环境配置:把 chromedriver.exe 放到正确的位置

3.1 三种路径配置方式与优先级

拿到chromedriver.exe之后,怎么让 Selenium 找到它,有三种做法,优先级从高到低:

第一种,在代码里显式指定executable_path。这是最直接的方式,不依赖系统环境变量,适合多版本共存的项目。

from selenium import webdriver from selenium.webdriver.chrome.service import Service # 显式指定驱动路径,最可控 service = Service(executable_path=r'D:\projects\drivers\chromedriver_136.exe') options = webdriver.ChromeOptions() driver = webdriver.Chrome(service=service, options=options)

第二种,把chromedriver.exe所在目录加到系统PATH环境变量里。这样代码里不用写路径,但多版本切换时容易搞混。

第三种,放到 Chrome 安装目录下。这是最不推荐的做法,因为 Chrome 自动更新时可能覆盖或清理这个目录。

我一般用第一种,路径写死在配置里,配合前面的自动下载脚本,每次启动前确保路径指向正确的 driver。

3.2 ChromeOptions 必调参数:让自动化跑得更像人

光把 driver 跑起来还不够,默认配置下的 Chrome 会暴露很多自动化特征,而且窗口大小、下载行为、弹窗处理都不受控。下面这几个参数是我每个项目都会加的:

from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options options = Options() # 禁用自动化特征栏,避免被检测 options.add_argument('--disable-blink-features=AutomationControlled') options.add_experimental_option('excludeSwitches', ['enable-automation']) options.add_experimental_option('useAutomationExtension', False) # 窗口与显示 options.add_argument('--window-size=1920,1080') options.add_argument('--start-maximized') # 无头模式(CI 环境常用,调试时关掉) # options.add_argument('--headless=new') # 禁用 GPU 和沙箱,Windows 上一般不需要,但容器里必须加 # options.add_argument('--no-sandbox') # options.add_argument('--disable-gpu') # 设置下载目录,避免弹窗 prefs = { 'download.default_directory': r'D:\downloads', 'download.prompt_for_download': False, 'download.directory_upgrade': True, 'safebrowsing.enabled': True } options.add_experimental_option('prefs', prefs) # 设置用户数据目录,保持登录状态 # options.add_argument(r'--user-data-dir=D:\chrome_profiles\auto_profile') service = Service(executable_path=r'D:\projects\drivers\chromedriver_136.exe') driver = webdriver.Chrome(service=service, options=options) # 进一步隐藏 webdriver 特征 driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', { 'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})' })

--disable-blink-features=AutomationControlled这个参数的作用是关掉 Chrome 对自动化控制的显式标记,配合excludeSwitches里的enable-automation,能让地址栏不再显示「Chrome 正受到自动测试软件的控制」。useAutomationExtension设为False是关掉旧版自动化扩展。

prefs里的download.default_directory要写绝对路径,反斜杠用 raw string 或者双反斜杠。download.prompt_for_download设为False才能让下载不弹窗。

--user-data-dir这个参数要特别小心。如果你指向了日常使用的 Chrome 用户数据目录,而 Chrome 正在运行,会直接报错「user data directory is already in use」。正确做法是给自动化单独建一个 profile 目录,或者每次启动前复制一份。

3.3 验证驱动是否真正生效

配置完之后,别急着跑业务代码,先用一段最小验证脚本确认 driver 能启动、能导航、能拿到页面标题:

from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By service = Service(executable_path=r'D:\projects\drivers\chromedriver_136.exe') driver = webdriver.Chrome(service=service) try: driver.get('https://www.example.com') print(f'页面标题: {driver.title}') print(f'当前 URL: {driver.current_url}') print(f'Chrome 版本: {driver.capabilities["browserVersion"]}') print(f'Driver 版本: {driver.capabilities["chrome"]["chromedriverVersion"]}') finally: driver.quit()

driver.capabilities里同时包含浏览器版本和驱动版本,打印出来一眼就能看出是否匹配。如果browserVersion是 136 而chromedriverVersion是 135,说明你路径指错了。这段脚本跑通,后面的业务代码才有意义。

4. 避坑与排查:ChromeDriver 启动失败的 5 个高频翻车现场

4.1 报错 session not created,版本不匹配

现象:SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 135,但你本机 Chrome 是 136。

原因:Chrome 后台自动更新了,ChromeDriver 还是旧的。或者你下载时看错了版本号,下了相邻大版本的驱动。

解决:重新查chrome://version/确认当前版本,下载对应主版本的 ChromeDriver。如果 CI 环境频繁出现,考虑锁定 Chrome 版本或每次构建时动态下载匹配驱动。

4.2 报错 chromedriver executable needs to be in PATH

现象:WebDriverException: Message: 'chromedriver' executable needs to be in PATH。

原因:Selenium 4.x 之后,如果不传Service对象,它会去系统 PATH 里找chromedriver。你没配 PATH,或者配了但没生效。

解决:要么在代码里显式传Service(executable_path=...),要么把驱动目录加到系统环境变量。改完 PATH 后要重启终端或 IDE,否则读的还是旧环境。

4.3 报错 user data directory is already in use

现象:InvalidArgumentException: Message: user data directory is already in use, please specify a unique value for --user-data-dir argument。

原因:你指定的--user-data-dir对应的 Chrome 实例正在运行。Chrome 不允许两个进程共用同一个用户数据目录。

解决:给自动化单独建 profile 目录,不要复用日常 Chrome 的目录。如果必须复用登录态,先复制一份 profile 到临时目录,再用--user-data-dir指向副本。

4.4 驱动启动了但页面空白或元素找不到

现象:driver.get()没报错,但find_element一直超时,截图发现页面是空白的。

原因:常见有三种——页面用了 iframe 嵌套,元素在 iframe 里;页面是 JS 动态渲染,元素还没出来你就去找了;Chrome 版本和驱动版本虽然主版本一致但次版本差异导致渲染协议不兼容。

解决:先加显式等待WebDriverWait(driver, 10).until(EC.presence_of_element_located(...));再检查是否需要driver.switch_to.frame();最后确认版本号是否精确匹配。

4.5 无头模式下行为不一致

现象:有界面时跑得好好的,加了--headless就各种失败,元素定位不到、截图空白、下载不触发。

原因:旧版--headless和 Chrome 的渲染路径不同,部分 CSS 和 JS 行为有差异。另外无头模式下默认窗口尺寸是 800x600,很多响应式页面会渲染成移动端布局。

解决:用--headless=new(Chrome 112+ 支持),并且显式设置--window-size=1920,1080。下载行为在无头模式下需要额外配置download.default_directory和download.prompt_for_download。

5. 进阶技巧:用 Chrome DevTools Protocol 绕过 Selenium 的局限

Selenium 的 WebDriver 协议能覆盖大部分操作,但有些场景它力不从心:拦截网络请求、修改响应内容、模拟弱网、精确控制下载。这些能力在 Chrome DevTools Protocol(CDP)里都有,而 Selenium 4 提供了execute_cdp_cmd让你直接调 CDP。

我常用的一个技巧是用 CDP 拦截特定 URL 的请求,直接返回 mock 数据,避免依赖后端接口的稳定性:

from selenium import webdriver from selenium.webdriver.chrome.service import Service service = Service(executable_path=r'D:\projects\drivers\chromedriver_136.exe') driver = webdriver.Chrome(service=service) # 启用网络拦截 driver.execute_cdp_cmd('Network.enable', {}) # 设置请求拦截规则,匹配特定 URL 模式 driver.execute_cdp_cmd('Network.setRequestInterception', { 'patterns': [{'urlPattern': '*api/data*', 'resourceType': 'XHR', 'interceptionStage': 'HeadersReceived'}] }) # 注册事件监听,拦截到请求后返回 mock 数据 driver.execute_cdp_cmd('Runtime.evaluate', { 'expression': ''' window.__mockData = {"code": 0, "data": [1,2,3]}; ''' }) # 实际项目中需要配合 execute_cdp_cmd 的 Fetch 域做请求暂停和继续 # 这里展示的是 CDP 调用的基本模式 driver.get('https://www.example.com')

CDP 调用的核心模式是:先enable某个域(Network、Fetch、Page 等),再设置拦截规则或监听事件,最后在页面加载过程中处理事件。Network.setRequestInterception在较新版本中已被Fetch.enable取代,后者更灵活,可以暂停请求、修改请求头和响应体。

另一个实用技巧是用 CDP 截图,比 Selenium 自带的save_screenshot更可控:

# 全页面截图(包括滚动区域) screenshot = driver.execute_cdp_cmd('Page.captureScreenshot', { 'format': 'png', 'captureBeyondViewport': True, 'fromSurface': True }) import base64 with open('full_page.png', 'wb') as f: f.write(base64.b64decode(screenshot['data']))

captureBeyondViewport设为True时,Chrome 会渲染整个页面而不只是可视区域,适合做长图截取。fromSurface控制是否从合成器表面捕获,一般保持True。

最后一个习惯:每次调试新脚本时,我会在driver.quit()之前加一句input('按回车关闭浏览器...'),让浏览器停住,方便我打开 DevTools 看网络请求和控制台报错。这个习惯帮我省下了大量猜测时间——很多问题在 DevTools 里一眼就能看到,比看 Selenium 的报错信息高效得多。版本对齐这件事,说到底就是细心加自动化,把重复劳动交给脚本,把判断力留给自己。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询