解决ChromeDriver版本不匹配:从手动到自动驱动管理实战
搞自动化测试的朋友估计都经历过这么一幕——昨晚还跑得稳稳当当的Selenium用例今天早上一来一跑全红了。控制台里躺着一行熟悉得让人血压升高的报错session not created: This version of ChromeDriver only supports Chrome version 118。低头一看Chrome不知道什么时候半夜自动更新到了120驱动还停在118。那一刻的心情比手机半夜自动更新还复杂。这个问题的本质就是Chrome驱动版本匹配。Chrome和ChromeDriver之间像锁和钥匙主版本号对不上钥匙就插不进锁孔。很多人第一反应是手动去下载一个匹配的驱动但麻烦的是每次Chrome一更新你又得重复一次。时间长了维护成本高到让人怀疑人生。今天这篇就集中解决这件事。用Python搭配Selenium跑自动化的同学看完这套方案之后基本可以告别手动查版本、手动下载驱动的日子。驱动跟着浏览器走缺哪个版本就自动下载哪个版本跑测试的时候再也不用为了环境问题停下来。1. Chrome驱动版本匹配到底在匹配什么1.1 版本不对会出哪些幺蛾子ChromeDriver本质上是一个独立的可执行文件它负责把Selenium的指令翻译成Chrome能理解的DevTools协议调用。Chrome和ChromeDriver走的是私有协议这个协议在不同版本之间会有调整所以Google给它们设计了严格的版本对应规则。版本匹配失败最典型的有这么几种报错报错内容原因This version of ChromeDriver only supports Chrome version 118驱动版本低于浏览器大版本SessionNotCreatedException: Message: session not created版本差异太大驱动还是太老unknown error: DevToolsActivePort file doesnt exist驱动与浏览器之间没有正常握手多数也是版本冲突chromedriver.exe crashed驱动本身的二进制文件被系统拦截或者不兼容系统架构注意最后一种驱动崩溃有时不完全是版本问题也可能是杀毒软件把临时目录里的驱动给隔离了这个我在后面排查部分再展开说。1.2 为什么Chrome更新总是打爆你的测试环境很多测试团队用Selenium做UI自动化跑得好好的突然某一天用例大面积失败查来查去最后发现只是Chrome偷偷更新了。Chrome的自动更新策略就决定了这件事没法完全避免。用户本机的Chrome默认开启自动更新一旦新版发布后台就直接替换了本地文件。你以为浏览器还是昨天那个其实它已经不是了。而Selenium这边你原来下载的ChromeDriver是匹配旧版本的两者版本号对不上协议就崩了。这是一个很典型的依赖管理问题。其他依赖比如Python库我们可以锁requirements.txt但浏览器本身没法锁版本除非你做内网管控统一分发固定版本的浏览器给测试机。大多数中小团队根本管不到这一层所以更划算的做法其实是让驱动去适配浏览器而不是反过来要求浏览器别更新。1.3 版本号对应关系可以这样快速判断Chrome的版本号长这样131.0.6778.86一共四段。ChromeDriver版本号几乎同步也需要四段都能匹配上才稳。大版本第一段不同必然报错直接没法用。第一段相同小版本号不同多数情况能跑但偶尔会出现奇怪的警告比如部分API行为变了但驱动没跟上。四段完全一致最稳妥官方推荐。因此在下面的方案里我们的目标就是拿到当前Chrome的完整版本号然后根据这个版本号去拉取完全相同的ChromeDriver版本。这不是我拍脑袋定的规则Google官方维护的Chrome for Testing项目就是这么配套的。2. 两条路让驱动自动匹配版本的主流方案2.1 方案A引入webdriver-manager一行代码自动匹配先给结论如果你用的是标准的Python环境可以直接用第三方库webdriver-manager。它的工作逻辑不复杂核心就三步读取你本机或远程机器上实际安装的Chrome版本号。在Google的Chrome for Testing接口里找到对应版本号的驱动下载地址。把驱动下载到本地一个固定缓存目录解压返回可执行文件路径给你。这个库帮我们省掉了“手动查版本”和“手动下载”这两件事换来的是每次启动测试时如果检测到浏览器版本变了就自动去拉新版驱动。安装它一条命令pip install webdriver-manager然后在代码里这么用from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager service Service(ChromeDriverManager().install()) driver webdriver.Chrome(serviceservice) driver.get(https://example.com) print(driver.title) driver.quit()就这么简单。我第一次在项目里把原来写死的驱动路径替换成ChromeDriverManager().install()之后最大的感触是“这事终于不用我操心了”。测试机重新做的同事也不用再问我要驱动压缩包自己跑一遍脚本驱动全部配好。2.2 方案B自研驱动自动下载脚本不依赖第三方库当然不是所有团队都有条件随意引入第三方库。有的公司内部代码审核严格有的Python环境是离线内网pip install都费劲。这种时候把自动下载逻辑自己写一遍是最可控的。自研脚本的核心思路和webdriver-manager几乎一样拿到当前Chrome的完整版本号。请求Google官方的版本接口找到对应版本驱动的下载地址。下载驱动压缩包解压到指定目录。设置Selenium的service路径启动浏览器。这个方案最大的好处是你可以完全掌握每一步在干嘛出了问题也好排查。你甚至可以把驱动版本下载的逻辑单独抽成一个函数供整个测试框架复用。2.3 两种方案怎么选对比维度webdriver-manager自研脚本接入成本极低一行代码需要自己维护约100行逻辑离线环境兼容性稍差但支持预置缓存灵活可对接内网源可定制性一般很高日常维护库作者维护自己维护出错排查需要理解库的缓存机制逻辑透明问题直观我的建议是能装库就装库省事不能装库就抄下面的自研方案逻辑也不难。3. 实操完整代码与关键环节解析3.1 第一步确认本机Chrome版本怎么拿无论用哪种自动方案第一步都是拿到浏览器版本。这里有一个很容易踩的坑Chrome版本不止一种拿法不同操作系统差异很大。最简单的办法是直接在Chrome地址栏输入chrome://version页面上会显示完整的版本号。但自动化脚本里不可能每次手动看所以要让代码自己去读取。Windows下Chrome安装时会写注册表最稳的路径是HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon这里的version字段就是完整版本号。用Python的winreg模块就能读import winreg def get_chrome_version_windows(): try: key winreg.OpenKey( winreg.HKEY_CURRENT_USER, rSoftware\Google\Chrome\BLBeacon, 0, winreg.KEY_READ ) value, _ winreg.QueryValueEx(key, version) winreg.CloseKey(key) return value except OSError: return NonemacOS或Linux下注册表这套不管用可以直接调用Chrome可执行文件并解析输出/Applications/Google Chrome.app/Contents/MacOS/Google Chrome --version google-chrome --version输出类似Google Chrome 131.0.6778.86用正则把版本号抠出来就行。有一点要提醒有些Linux发行版会先打开图形界面的chrome而不是输出版本号这时要看进程或包管理器信息但大多数情况下上面的命令是管用的。3.2 第二步根据Chrome版本找到驱动下载地址拿到Chrome版本号之后下一步是找驱动下载地址。Google官方维护了一个JSON接口里面列出了所有已知的Chrome版本和对应驱动下载链接https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json这个接口的数据结构大致是{ versions: [ { version: 131.0.6778.86, releases: [ { platform: win64, url: https://storage.googleapis.com/chrome-for-testing-public/... } ] } ] }Python代码里先根据Chrome版本号去遍历versions数组找到相同项。找不到就退而求其次匹配版本号前两段相同的最接近版本。不过实测下来Google发布驱动和发布Chrome基本同步大概率能找到完全一致的版本。有个细节要注意接口里的平台参数有坑。win32代表Windows 32位win64代表Windows 64位macOS还区分mac-arm64Apple Silicon和mac-x64Intel。很多人会忽略这点代码里直接写死win64结果在M系列芯片的Mac上跑半天也下不对文件。正确做法是用platform模块动态判断。3.3 第三步完整自研脚本实现下面这段代码是我平时在项目里用的一个简化版本覆盖了Windows、macOS、Linux三类常用系统。这个脚本的核心思路就是版本读取、网址解析、下载解压、路径缓存每一步都留了清晰的提示信息。import json import os import platform import re import subprocess import sys import tarfile import urllib.request import zipfile def get_chrome_version(): system platform.system() if system Windows: try: import winreg key winreg.OpenKey( winreg.HKEY_CURRENT_USER, rSoftware\Google\Chrome\BLBeacon, ) version, _ winreg.QueryValueEx(key, version) winreg.CloseKey(key) return version except OSError: raise RuntimeError(未能从注册表读取Chrome版本) elif system Darwin: result subprocess.run( [/Applications/Google Chrome.app/Contents/MacOS/Google Chrome, --version], capture_outputTrue, textTrue ) return result.stdout.strip().split( )[-1] else: result subprocess.run( [google-chrome, --version], capture_outputTrue, textTrue ) return result.stdout.strip().split( )[-1] def get_driver_download_url(chrome_version): url https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json with urllib.request.urlopen(url, timeout30) as resp: data json.load(resp) for item in data[versions]: if item[version] chrome_version: target_version item[version] releases item[releases] break else: raise RuntimeError(f在官方列表中没有找到匹配版本: {chrome_version}) system platform.system() if system Windows: platform_key win64 if sys.maxsize 2**32 else win32 elif system Darwin: platform_key mac-arm64 if platform.machine() arm64 else mac-x64 else: platform_key linux64 for release in releases: if release[platform] platform_key: return release[url] raise RuntimeError(f该版本没有对应的{platform_key}平台驱动下载地址) def download_driver(download_url, save_dir): os.makedirs(save_dir, exist_okTrue) file_name download_url.split(/)[-1] local_file os.path.join(save_dir, file_name) if not os.path.exists(local_file): print(f正在下载驱动: {download_url}) urllib.request.urlretrieve(download_url, local_file) if file_name.endswith(.zip): with zipfile.ZipFile(local_file, r) as zf: zf.extractall(save_dir) elif file_name.endswith(.tar.gz): with tarfile.open(local_file, r:gz) as tf: tf.extractall(save_dir) driver_path None for root, dirs, files in os.walk(save_dir): for f in files: if f chromedriver or f chromedriver.exe: driver_path os.path.join(root, f) break if not driver_path: raise RuntimeError(解压后未找到驱动可执行文件) if not platform.system() Windows: os.chmod(driver_path, 0o755) return driver_path def ensure_driver(): chrome_version get_chrome_version() print(f当前Chrome版本: {chrome_version}) cache_dir os.path.join(os.path.expanduser(~), .chrome_driver_cache) version_dir os.path.join(cache_dir, chrome_version) if os.path.exists(version_dir) and os.listdir(version_dir): for root, dirs, files in os.walk(version_dir): for f in files: if f chromedriver or f chromedriver.exe: return os.path.join(root, f) download_url get_driver_download_url(chrome_version) return download_driver(download_url, version_dir) if __name__ __main__: driver_path ensure_driver() print(f驱动路径: {driver_path})这段脚本里我特意做了版本目录缓存。每次启动浏览器前先检查~/.chrome_driver_cache/对应的版本号里有没有驱动有就直接用没有再下载。这样既保证版本匹配又不会每次启动都白下载一遍。3.4 用Selenium连接自动匹配的驱动无论是自研脚本还是webdriver-manager最后都要把驱动路径交给Selenium。在较新版本的Selenium里推荐用Service对象from selenium import webdriver from selenium.webdriver.chrome.service import Service from src.driver_utils import ensure_driver # 自研脚本或webdriver-manager封装 driver_path ensure_driver() service Service(executable_pathdriver_path) driver webdriver.Chrome(serviceservice) driver.get(https://example.com) print(driver.title) driver.quit()这里有一个细节值得展开说如果你同时配置了service又传了executable_path参数那是旧版Selenium的写法新版本已经废弃。统一用Service最稳代码也简洁。4. 实战中踩过的坑与排查速查表4.1 webdriver-manager缓存机制别被“版本没变”骗了用webdriver-manager跑了一段时间之后可能会遇到一种情况Chrome更新了但驱动还是旧的。这不是库失效而是默认缓存路径里的版本没有更新。webdriver-manager会检查已下载的驱动版本是否匹配当前Chrome版本正常情况下能自动识别并下载新版。但如果你曾经手动把驱动文件放进了缓存目录或者缓存目录的权限不对它就可能读取不到真实Chrome版本报错信息也容易让人误会是网络问题。此时直接删掉默认缓存目录最简单粗暴Windows下是C:\Users\你的用户名\.wdmmacOS/Linux下是~/.wdm删掉之后重新跑测试它会老老实实重新下载匹配的驱动。4.2 下载驱动超时或失败不一定是代码问题webdriver-manager默认从Google官方存储空间下载驱动。国内网络正常访问时有波动经常超时。改镜像源是最有效的方案但要注意官方接口和下载域名是分开的只镜像其中一个还不够。对自研脚本来说下载那一步可以加一个重试机制。Python标准库里没直接封装好的重试简单点用循环import time for i in range(3): try: urllib.request.urlretrieve(download_url, local_file) break except Exception as e: if i 2: raise print(f下载失败重试第{i1}次) time.sleep(3)如果你在公司内网还可以把驱动文件提前下载好放到版本目录里脚本检测到文件存在就直接跳过下载。这个方式对离线环境特别友好先把缓存机器准备好测试机直接从共享目录拷贝即可。4.3 macOS首次运行会提示无法打开chromedrivermacOS上有严格的Gatekeeper保护从网上下载的未签名可执行文件首次运行时会被拦截。即使你在Python代码里已经把路径设置好了OS层面还是可能出现一个弹窗或者直接报cannot be opened because the developer cannot be verified。手工处理的办法是在终端执行xattr -d com.apple.quarantine /path/to/chromedriver更一劳永逸的做法是在自动化环境搭建文档里写清楚这一步让每个新同事配环境时都执行一次。我试过把这个命令写进自动化初始化脚本里但xattr命令本身也需要权限所以最终还是保留在文档里人工执行。4.4 Linux服务器上驱动文件没有执行权限Linux服务器上运行Selenium经常遇到的情况是驱动下载成功了、路径也对了但报Permission denied。原因很简单解压出来的chromedriver文件默认没有可执行权限。自研脚本里我特意加了os.chmod(driver_path, 0o755)这行代码就是干这个的。如果你用手动方式下载驱动记得解压后自己加一下权限chmod x chromedriver4.5 杀毒软件把驱动当病毒隔离这个坑在Windows环境特别常见。ChromeDriver是一个独立的exe文件某些杀毒软件会对这类自动化工具敏感下载下来或者解压出来的一瞬间就给隔离了然后Selenium就报exec format error或者binary not found。排查思路是先去杀毒软件的隔离区看看有没有chromedriver.exe如果有恢复并把驱动缓存目录加入白名单。webdriver-manager默认下载到用户目录~/.wdm自研脚本的缓存目录在代码里自己定义你可以给杀毒软件指定一个明确的目录让她放心。4.6 排查速查表现象直接原因处理办法This version of ChromeDriver only supports Chrome version 118驱动版本过旧更新驱动最稳妥是用自动匹配方案DevToolsActivePort file doesnt exist驱动与浏览器握手失败确认版本匹配杀掉残留chrome进程Permission denied驱动没有执行权限chmod x chromedriver下载速度极慢或超时网络到Google存储不稳定内网预置缓存或加镜像Windows杀毒隔离驱动杀毒误报恢复文件并加白名单macOS无法打开驱动Gatekeeper拦截执行xattr -d com.apple.quarantine5. 最后再分享一点实际使用的心得如果非要我在不同方案里选一个最推荐的我还是会先推荐webdriver-manager因为它确实省心日常代码就一行。但如果你是在一个环境管理很严格的团队或者测试机是离线、带内网的那自研脚本的主动权更让你心里有底。两条路都走通之后你手里相当于多了一套“驱动自动校准”的解决方案。我自己在实际操作中的习惯是自研脚本搭一套但把它包装成和webdriver-manager一样的函数接口以后团队用哪个都行切换成本极低。每次Chrome大更新的时候脚本自动感知新版本不再需要半夜爬起来救火。这一套方案不止解决Selenium的问题你用Playwright、Puppeteer这类工具也会有类似的版本驱动问题思路其实是通用的。以后哪怕换了工具再遇到“浏览器更新导致工具链断裂”的情况你知道第一步永远是先获取浏览器版本再去官方渠道同步工具版本。工具会变但这个排查思路不会过时。

相关新闻

Godot 2D游戏战斗系统实战:状态机、敌人AI与血条实现

Godot 2D游戏战斗系统实战:状态机、敌人AI与血条实现

1. 系列回顾与本节目标没想到这个系列这么快就写到第5篇了。前四篇我们把Godot 2D游戏开发的地基打了一遍:安装Godot编辑器、理解场景树和节点概念、用GDScript写最简单的打印脚本、给一个方块物体加上键盘移动控制。如果你是从系列第一篇一直跟下来的,此…

2026/10/18 23:44:38 阅读更多 →
语音消息为何让人心累?接收成本与文字化中间层解析

语音消息为何让人心累?接收成本与文字化中间层解析

1. 收到语音先叹气不是矫情,是“接收成本”在作祟1.1 听语音前的三秒心理建设,到底在建设什么我最近在忙一个项目评审,手机在桌上连着震了好几次。拿起来一看,是一位长辈发来的三段语音,每段都在五十秒上下。坐在旁边的…

2026/10/18 23:43:38 阅读更多 →
网易云QQ音乐歌词批量下载:163MusicLyrics 从单曲到歌单一次搞定

网易云QQ音乐歌词批量下载:163MusicLyrics 从单曲到歌单一次搞定

网易云QQ音乐歌词批量下载:163MusicLyrics 从单曲到歌单一次搞定 【免费下载链接】163MusicLyrics 云音乐歌词获取处理工具【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 先说结论:如果你受够了一首一首复…

2026/10/18 23:43:38 阅读更多 →

最新新闻

Diagram as Code:用可执行图表构建系统逻辑骨架

Diagram as Code:用可执行图表构建系统逻辑骨架

1. 项目概述:这不是画图,是构建可执行的系统逻辑骨架“diagram-design”这个标题乍看像一个设计类工具操作,但在我过去十年带过的几十个跨领域项目里,它从来不是美术课——而是工程师、产品负责人、运维人员和业务方坐在一起&…

2026/10/19 5:53:33 阅读更多 →
diagram-design:用结构化图形重建信息表达逻辑

diagram-design:用结构化图形重建信息表达逻辑

1. 项目概述:这不是画图,是用结构化思维重建信息表达的底层逻辑“diagram-design”这个词组乍看像一个工具名或功能按钮,但在我带过的十几个跨领域协作项目里,它从来不是指“用Visio拖几个矩形框”,而是指一套完整的信…

2026/10/19 5:53:33 阅读更多 →
从布尔到时间盲注:SQL注入无回显场景的完整实战指南

从布尔到时间盲注:SQL注入无回显场景的完整实战指南

如果你在靶场里手动测过SQL注入,一定会经历一个非常分裂的阶段:刚开始觉得注入特别简单,参数后面丢一个单引号,看报错、看回显,再union select一撞,数据就哗啦啦全出来了,像开卷考试。但很快你就…

2026/10/19 5:53:33 阅读更多 →
diagram-design:从草图到可维护系统的图表设计实战指南

diagram-design:从草图到可维护系统的图表设计实战指南

1. 从一张草图到一套系统:diagram-design 到底在解决什么问题第一次看到 diagram-design 这个词,很多人会以为它只是一个画图工具的别名,或者某个设计模板库的代号。但真正在工程团队里待过几年的人会明白,它指向的是一套远比“画…

2026/10/19 5:53:33 阅读更多 →
DCMTK 3.6.5 Windows预编译包:开箱即用的DICOM工程解决方案

DCMTK 3.6.5 Windows预编译包:开箱即用的DICOM工程解决方案

简介:本资源是面向医学影像开发人员、生物医学工程研究人员及DICOM系统集成工程师的DCMTK 3.6.5 Windows 64位预编译工具包,专为免编译快速上手DICOM数据处理而优化,解决Windows环境下源码构建复杂、依赖配置繁琐等实际痛点。压缩包共238个文…

2026/10/19 5:53:33 阅读更多 →
基于最佳簇半径的无线传感器网络分簇路由算法详解

基于最佳簇半径的无线传感器网络分簇路由算法详解

做无线传感器网络这块也有几年了,前前后后调过不少路由协议,从最开始的洪泛、LEACH,到后来各种改进的PEGASIS、TEEN、EEUC都摸过一遍。说实话,分簇路由这个方向看着简单,就是把节点分成一组一组的,选个簇头…

2026/10/19 5:52:33 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →