Bowser 2.x 版本演进全解析:从 API 重写到 Client Hints 时代的浏览器检测器
开发工具【免费下载链接】bowsera browser detector项目地址https://gitcode.com/gh_mirrors/bo/bowser点击查看免费下载导读本文以 Bowser当前仓库为gh_mirrors/bo/bowser一个轻量级浏览器/平台/引擎检测库的 CHANGELOG.md 为主线逐版本还原其 2.x 时代的演进脉络——从 2.0 的 API 全面重写、到satisfies/别名/常量导出等能力沉淀、再到面向 AI 爬虫与 User-Agent Client Hints 的现代化识别。读完后你不仅能看懂每个版本号背后的变更动机还能把变更点对应到 src/ 下的真实源码实现与 test/ 中的测试用例掌握「如何阅读一个检测库的 Changelog」以及「Bowser 当前版本能做什么」。一、写在前面Changelog 与源码的对应关系CHANGELOG.md 覆盖了 Bowser 从1.4.02016 年 6 月到2.11.02020 年 9 月的全部公开版本其中 2.x 是当前架构的定型期。值得注意的是CHANGELOG 记录到 2.11.0 后便不再更新但仓库源码仍在演进例如 parser-browsers.js 中已出现GPTBot、ChatGPT-User、ClaudeBot、DuckDuckGo等新检测器以及 parser.js 中完整的 Client Hints 支持。阅读时可以遵循一个原则Changelog 给出变更意图源码给出实现事实。本文围绕以下核心脉络展开2.0 大版本重写Bowser 从「一个函数」变成「Parser 类 静态 API」2.x 增量演进别名、is、some、常量导出、Typings 补全识别能力扩张浏览器、OS、平台、引擎的逐版本补丁工程化演进构建产物、包体积、polyfill 策略未写入 Changelog 的现代化能力Client Hints 与 AI 爬虫检测。二、2.0.0API 全面重写从「检测函数」到「解析器类」CHANGELOG 中 2.0 系列alpha → beta → 正式版是最具颠覆性的一段2.0.0-alpha.12018-07-09新增Bowser.getParser()、Bowser.parse引入描述整个解析过程的Parser类改变 bowser 的返回对象并移除 bower 支持2.0.0-alpha.2将src/bowser设为主文件bundled 文件移到包根目录以便require(bowser/compiled)2.0.0-alpha.3新增Parser.some将compiled.js重命名为es5.js2.0.0-beta.1为Parser.compareVersion()和Parser.satisfies()加入宽松版本比较2.0.0 正式版2019-01-19satisfies()支持非严格相等、Android 版本命名、新增 typings 文件、支持 Googlebot 识别。2.1 源码印证双入口 API 设计这段重写在当前源码中清晰可见。src/bowser.js 提供了两个静态方法static getParser(UA, skipParsingOrHints false, clientHints null) { if (typeof UA ! string) { throw new Error(UserAgent should be a string); } return new Parser(UA, skipParsingOrHints, clientHints); } static parse(UA, clientHints null) { return (new Parser(UA, clientHints)).getResult(); }getParser()返回一个可复用的Parser实例适合需要多次查询的场景parse()是一次性调用直接返回解析结果对象文件末尾还通过export const { parse, getParser } Bowser;暴露了命名导出配合 package.json 中的exports字段实现 tree-shaking。Parser类的构造函数在 src/parser.js 中做了三件事校验 UA 非空空值直接抛错、处理(UA, clientHints)与(UA, skipParsing, clientHints)两种重载、在skipParsing ! true时立即执行parse()。解析过程由parse()串联四个子解析器src/parser.jsparse() { this.parseBrowser(); this.parseOS(); this.parsePlatform(); this.parseEngine(); return this; }这对应 Changelog 2.0.0-alpha.1 所说的「Parser 类描述解析过程」——最终结果ParsedResult包含browser、os、platform、engine四个字段。单元测试 test/unit/parser.js 逐一验证了getBrowserName、getOSName、getEngineName等访问器。2.2 宽松版本比较compareVersion的语义2.0.0-beta.1 加入的宽松比较实现在 src/parser.js 的compareVersion()中支持五类操作符操作符语义示例说明/严格大于/小于chrome: 100不匹配相等版本/非严格比较opera: 43匹配相等版本精确相等chrome: 20.1.1432只匹配特定 build~宽松相等chrome: ~20.1匹配20.1.*任意子版本数组或关系[~40, ~41]任一满足即通过底层数值比较由 src/utils.js 的compareVersions()完成先将两个版本补齐到相同精度如9→9.0再把每段数字左补零后逐段比较从而避免9 10这类字符串比较陷阱。测试 test/unit/parser.js 覆盖了42、~43.0、43.0.2442.1165及版本数组等全部用例。三、2.x 增量演进别名、is方法、常量与 Typings2.x 中后期Bowser 的 API 进入「补全期」2.2.02019-04-07为浏览器名增加短别名修复 Yandex Browser 版本检测2.2.1为 Samsung Internet 增加别名2.9.02020-01-28通过.d.ts导出更多方法与常量2.11.02020-09-12Parser#is支持别名、补充更多 typings、新增 MIUI Browser 支持。3.1 别名机制is()与satisfies()的便捷通道别名机制的核心是 src/constants.js 的BROWSER_ALIASES_MAP完整名称 → 短名与BROWSER_MAP短名 → 完整名称共约 60 个映射例如Microsoft Edge → edge、Internet Explorer → ie、Samsung Internet for Android → samsung_internet、NAVER Whale Browser → naver、QQ Browser → qq、WeChat → wechat。Parser#is(anything, includingAlias)src/parser.js会同时检查浏览器、OS、平台三类名称当includingAlias true时通过Utils.getBrowserTypeByAlias()把短名解析为完整名再比较。测试 test/unit/parser.js 验证了别名开启前后的差异// edgeParser 的 UA 是 Microsoft EdgeEdgA/41.1.35.1 t.is(edgeParser.is(edge, false), false); // 不开别名edge 不等于 Microsoft Edge t.is(edgeParser.is(edge, true), true); // 开别名短名被解析为完整名Parser#some(anythings)src/parser.js则是is()的批量版本——任一命中即返回true。satisfies()内部的浏览器匹配同样启用别名src/parser.js所以你可以写satisfies({ edge: 41.1.35.1 })测试 test/unit/parser.js 对此有专门断言。3.2 常量导出与 Typings2.9.0 之后Bowser类以静态 getter 形式暴露四张常量表src/bowser.jsBROWSER_MAP、ENGINE_MAP、OS_MAP、PLATFORMS_MAP。配合 index.d.ts 的类型声明可以写出常量驱动的检测代码test/unit/parser.jsimport Bowser from bowser; const parser Bowser.getParser(window.navigator.userAgent); parser.is(Bowser.BROWSER_MAP.opera); // 完整名 Opera parser.is(Bowser.PLATFORMS_MAP.desktop); // 平台类型 desktop parser.is(Bowser.OS_MAP.MacOS); // OS 名 macOS仓库同时提供 index.d.tsCommonJS/UMD 类型与 index.d.mtsESM 类型并通过 test/types/ 下的consumer-cjs.ts、consumer-esm.ts与check.mjs做类型冒烟验证对应 package.json 的test:types脚本。四、识别能力扩张浏览器、OS、平台与引擎的逐版本补丁CHANGELOG 中大量的[FIX]/[ADD]条目都对应着 src/parser-browsers.js约 1250 行最大的规则表、src/parser-os.js、src/parser-platforms.js、src/parser-engines.js 中具体规则的增删。下表梳理了主要条目与源码锚点版本变更源码位置2.0.0Googlebot 识别parser-browsers.jsparser-platforms.js标记为type: bot, vendor: Google2.0.0Android 版本命名src/utils.js 的getAndroidVersionName()如7.0 → Nougat8.x → Oreo2.1.0Parser.getEngineName()、ChromeOS 检测src/parser.js、src/parser-os.js 的 ChromeOS 规则2.1.1PlayStation 4 检测parser-browsers.js、parser-os.js、parser-platforms.js2.2.1Samsung Internet 别名src/constants.js2.3.0Blink 内核的 MS Edgesrc/parser-engines.js 的 Blink 规则2.5.0常量输出、Roku OSsrc/parser-os.js/Roku\/DVP/规则2.7.0QQ 浏览器、GSAGoogle Search Appsrc/parser-browsers.js/GSA/i规则2.8.0Electron、iPad 上的 Firefox、Windows 上的 WeChatsrc/parser-browsers.js/electron/i规则、src/parser-os.jsFxiOS规则2.10.0iOS 13 上的 Firefox 修复src/parser-os.js 的 Firefox-on-iOS 规则2.11.0MIUI Browsersrc/parser-browsers.js/MiuiBrowser/i规则返回name: Miui4.1 规则表的组织方式testdescribe理解这些规则的关键是 parser-browsers.js 文件头部的注释每个描述符descriptor包含test和describe两个部分且描述符的顺序至关重要——Parser按顺序逐个测试先命中的优先因此通用性强的规则如 GPTBot、各类 AI 爬虫必须放在列表前部避免把其他浏览器误判为 Chrome。test既可以是正则数组任一命中即通过也可以是接收 Parser 实例的函数例如 DuckDuckGo 的检测src/parser-browsers.js会先查 Client Hints 品牌再回退到 UA 字符串test(parser) { if (parser.hasBrand(DuckDuckGo)) { // Client Hints 优先 return true; } return parser.test(/\sDdg\/[\d.]$/i); // WebKit 平台回退到 UA }4.2 OS 版本命名的双维度输出从 1.7.0 的 Windows/macOS 版本支持到 2.0.0 的 Android 命名os结果对象如今最多有三个字段name、version、versionName。例如 Windows 的version: NT 6.3对应versionName: 8.1映射见 src/utils.js 的getWindowsVersionName()macOS 的10.14 → Mojave、13 → Ventura见getMacOSVersionName()src/utils.js。README 中的完整输出示例README.md展示了 IE 11 在 Windows 8.1 上的四段式解析结果。五、工程化演进构建产物、polyfill 与包体积Changelog 中反复出现的构建相关条目最终形成了当前 package.json 的完整导出矩阵ES5 主产物main: es5.js面向 CommonJS/script标签不含任何 polyfill2.5.1 优化 Babel 配置以缩减体积README 称 ES5 版本约 4.8kB gzippedbundled 带 polyfill 产物require(bowser/bundled)得到内置core-jspolyfill 的 ES5 版本2.8.0 为Array.find、Object.assign补充 polyfill对应 src/utils.js 中手写的map/find/assign兜底实现ESM 产物bowser.mjs配合exports的import/require条件分支实现 tree-shaking源码注释 src/parser.js 明确指出 es5.js 不打包 polyfill因此内部查找一律走Utils.find而非Array.prototype.find源码直用src/*.js全部通过exports子路径暴露可import Parser from bowser/src/parser。2.5.4 起将docs排除出 npm 包文档迁移至 GH Pages2.6.0 在 package.json 中声明module字段2.8.1 曾回滚一个破坏构建的改动——这些条目提醒我们每个版本号背后都是一次真实的质量门禁。当前仓库的构建脚本package.json由tsdown驱动配套eslint、ava、nyc覆盖率、publint、arethetypeswrong/cli等一整套质量工具。六、Changelog 之外的现代化Client Hints 与 AI 爬虫源码中还存在一批 Changelog 未记录的能力它们是理解「当前 Bowser 能做什么」的关键补充。6.1 User-Agent Client Hints现代浏览器逐步收紧 UA 字符串后README.md 明确推荐将navigator.userAgentData作为第二参数传入const browser Bowser.getParser( window.navigator.userAgent, window.navigator.userAgentData // Client Hints ); browser.getHints(); // 获取完整 hints 对象 browser.hasBrand(Google Chrome); // 品牌存在性检查大小写不敏感 browser.getBrandVersion(Google Chrome); // 取品牌版本如 131ClientHints 的字段结构brands、mobile、platform、platformVersion、architecture、model、wow64定义在 src/parser.js 与 index.d.ts。测试 test/unit/parser.js 覆盖了 DuckDuckGo、Chrome、Edge 的 hints 检测包括 GREASE 品牌变体Not_A Brand、Not-A.Brand的处理以及「hints 缺失时回退到 UA 解析」的兜底逻辑。6.2 AI 爬虫与新型浏览器src/constants.js 的别名表中已出现GPTBot、ChatGPT-User、ClaudeBot、PerplexityBot、Perplexity-User、OAI-SearchBot、Meta-ExternalFetcher、Diffbot、AmazonBot、BingCrawler、InternetArchiveCrawler等条目src/parser-platforms.js 将GPTBot/ChatGPT-User/OAI-SearchBot统一标记为type: bot, vendor: OpenAI。这意味着当前版本的 Bowser 不仅能识别浏览器还能区分搜索引擎爬虫与 AI 内容抓取机器人对反爬统计、流量分析场景尤为实用。七、实战把 Changelog 变成可验证的检测代码最后用一段完整的示例串联全文。以 Opera 43 的 UA 为例与 test/unit/parser.js 同一字符串import Bowser from bowser; const UA Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 OPR/43.0.2442.1165; const parser Bowser.getParser(UA); parser.getBrowserName(); // Opera2.x 描述符顺序保证 Opera 优先于 Chrome parser.getBrowserVersion(); // 43.0.2442.1165 parser.getOSName(); // macOS parser.getEngineName(); // Blink parser.satisfies({ opera: 42 }); // truebeta.1 引入的宽松比较 parser.is(Bowser.BROWSER_MAP.opera); // true2.9.0 常量导出验证方式仓库已内置完整测试体系可运行pnpm testava nyc执行 test/unit/ 下的单元测试pnpm test:package运行 test/package/ 的产物冒烟测试pnpm test:types校验 index.d.ts 类型。若想扩充检测规则test/acceptance/useragentstrings.yml 是官方维护的 UA 语料库[src/constants.js](https://link.gitcode.com/i/5ff5285ab9ab6929dcf154a99149881c)的注释明确要求浏览器列表必须与该文件保持同步——这正是 Bowser 每个版本都能「改一个检测、补一串测试」的质量保障机制。赞分享开发工具【免费下载链接】bowsera browser detector项目地址https://gitcode.com/gh_mirrors/bo/bowser点击查看免费下载相关推荐Wox 2.x 版本演进全览从跨平台重写到原生 UI 换代的技术脉络Wox 2.x 版本演进全览从跨平台重写到原生 UI 换代的技术脉络 Wox 是一个跨平台桌面启动器launcher其设计目标是simply work桌面应用AI 应用插件系统OverlayScrollbars 2.x 版本演进全解从 TypeScript 重写到 2.16 的滚动条插件现代化之路OverlayScrollbars 2.x 版本演进全解从 TypeScript 重写到 2.16 的滚动条插件现代化之路 本文以 OverlayScrollUI组件前端PPT Master从一份 PDF 到可编辑 PPT 只要10分钟零额外订阅费PPT Master从一份 PDF 到可编辑 PPT 只要10分钟零额外订阅费 周五晚上九点桌上摊着一沓 PDF明早十点要给老板做季度汇报。你手头的 AAI 技能人工智能AI 应用上一篇SMOTE-variants模型选择攻略交叉验证与参数调优的最佳实践下一篇node-elm接口性能对比REST与GraphQL性能测试创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

FDFullscreenPopGesture 源码级解析:用 AOP 为 UINavigationController 开启全屏滑动返回

FDFullscreenPopGesture 源码级解析:用 AOP 为 UINavigationController 开启全屏滑动返回

移动开发UI组件 【免费下载链接】FDFullscreenPopGesture A UINavigationControllers category to enable fullscreen pop gesture with iOS7 system style. 项目地址: https://gitcode.com/gh_mirrors/fd/FDFullscreenPopGesture 点击查看 免费下载 FDFullscreenP…

2026/10/15 2:18:18 阅读更多 →
为什么视频AI这么贵?一份关于“省钱“技术的全景调查

为什么视频AI这么贵?一份关于“省钱“技术的全景调查

你有没有想过,为什么手机上的视频AI助手总是卡顿,或者干脆不支持太长的视频?答案很简单,也很扎心:视频太贵了。不是钱包意义上的贵,是计算意义上的贵。一段一分钟的视频,按每秒抽一帧算,也有60张图。每张图…

2026/10/15 2:18:18 阅读更多 →
紫铜韵致筑院墅 以铝代木承江南雅韵

紫铜韵致筑院墅 以铝代木承江南雅韵

在温州的高端低密墅区,一方苏式院墅藏着江南栖居的理想模样。白墙黛瓦间,紫铜色廊柱挺拔温润,万字挂落玲珑精巧,飞檐翘角下雀替雕花细腻,连廊栏杆、檐下构件处处彰显东方雅致。这座极具质感的中式院墅,并未采用昂贵的纯铜或易损的实木打造,而是以仿铜铝代木构件体系实现 —— 以…

2026/10/15 2:18:18 阅读更多 →

最新新闻

ESXi 升级到 8.0 后 VM 快照删不掉?一篇讲透 “in progress“ 死循环的 3 种解法

ESXi 升级到 8.0 后 VM 快照删不掉?一篇讲透 “in progress“ 死循环的 3 种解法

本文适用版本:ESXi 7.0 U3 → 8.0 U2 升级场景(vSphere 6.7 升级也会遇到) 阅读时长:约 8 分钟 难度:⭐⭐⭐(操作不可逆,生产 VM 强烈建议先备份再动)一、为什么写这篇文章?最近私信里又有几位网友问:ESXi 7.0 升到 8.0 之后,VM 的快照怎么都删不掉,vSphere Client 里一直显示…

2026/10/15 2:48:27 阅读更多 →
ESXi ping 得通但连不上 vCenter?一篇讲透 hostd 假死的全套救法

ESXi ping 得通但连不上 vCenter?一篇讲透 hostd 假死的全套救法

本文适用版本:ESXi 7.0 U3 / 8.0 U2 / 9.0 GA 阅读时长:约 7 分钟 难度:⭐⭐(SSH 能进就能修,但要分清是 hostd 还是 vpxd 的锅)一、为什么写这篇文章?最近私信里又陆续收到几位网友问:ESXi 能 ping 通、SSH 也能进、DCUI 也正常,但 vCenter 里主机显示"未响应"或&q…

2026/10/15 2:48:27 阅读更多 →
前端XSS防御实战:xss-filters上下文转义库详解

前端XSS防御实战:xss-filters上下文转义库详解

简介:前端开源库-xss-filters是一份面向前端开发者与安全入门者的XSS防护工具源码包,聚焦于解决用户输入回显场景下的跨站脚本注入风险。资源共30个文件,以20个js源码与测试脚本为主体,辅以3个json配置、3个md说明文档&#xff0c…

2026/10/15 2:48:27 阅读更多 →
ESXi 装系统报错 “bootbank is corrupted“ 怎么办?一篇讲透三种根治方案

ESXi 装系统报错 “bootbank is corrupted“ 怎么办?一篇讲透三种根治方案

本文适用版本:ESXi 7.0 U3 / 8.0 U2 / 9.0 GA(三版统一报错,解决方案略有差异) 阅读时长:约 8 分钟 难度:⭐⭐⭐(需在 DCUI/物理机前操作,不建议生产机远程盲操作)一、为什么写这篇文章? 最近陆续有几位网友私信问同一个问题:装 ESXi 的时候跑到一半,屏幕突然卡住,报 bootbank…

2026/10/15 2:48:27 阅读更多 →
React Native position 定位详解:relative 与 absolute 实战指南

React Native position 定位详解:relative 与 absolute 实战指南

1. 为什么 position 定位值得单独拎出来讲做 React Native 开发的人,迟早都会在布局上栽跟头。Flexbox 那一套东西,flexDirection、justifyContent、alignItems三板斧抡完,大部分界面确实能搭出来。但总有一些场景,光靠 Flex 流式…

2026/10/15 2:48:27 阅读更多 →
从零开发聚合9大视频网站的桌面App:技术选型与发布运营复盘

从零开发聚合9大视频网站的桌面App:技术选型与发布运营复盘

前阵子我在一个技术交流群里发了句感叹:“现在做桌面应用,是不是有点逆潮流?”结果有个朋友直接回我:“你做一个有用的桌面工具试试,用户在乎的是好不好用,又不是你用什么平台。”我当时不以为然&#xff0…

2026/10/15 2:47:27 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →