WeChatMsg本地解析微信数据库:绕过WAL加密与salt解密指南
简介WeChatMsg-2.0.10 是一款面向个人用户与数据隐私关注者的开源微信聊天记录导出工具专为解决聊天数据长期留存、跨设备查阅与本地化分析需求而设计。资源包共259个文件以106个Python核心脚本含数据解析、HTML/Word/Excel导出逻辑、56个PNG与44个SVG图标用于界面与报告渲染、18个HTML模板按月份与页面分类生成可离线浏览的交互式报告为主干辅以JSON配置、YML参数定义及少量EXE可执行文件整体压缩包仅24.69MB轻量高效。已有1935人学习下载体现其在实操型数字存档场景中的广泛认可。用户可直接导出完整文本、图片、表情包及系统消息生成结构清晰的年度聊天报告并基于导出数据训练个性化AI助手所有功能严格遵循‘留痕’原则不恢复已删记录、不篡改原始数据强调用户对自身聊天数据的完全自主权。1. 微信聊天记录导出为什么总卡在“无法读取数据库”WeChatMsg-2.0.10.zip 是目前实测最稳的本地解析方案你是不是也试过用某款工具点开微信备份文件夹双击.db文件却提示“数据库已损坏”或者导出 CSV 后发现语音消息变成一串乱码路径、撤回消息全丢、图片只留缩略图、时间戳全是 1970 年这不是你的手机或电脑问题——微信自 iOS 11 / Android 8 起全面启用 WAL 模式 加密页头 动态 salt 的 SQLite 存储机制原生 sqlite3 命令根本打不开MM.sqlite。WeChatMsg-2.0.10.zip 不是简单调个sqlite3 .dump它是一套完整绕过微信加密层、还原 WAL 日志、解密 media 缓存索引、重建消息时序关系的本地解析链路。它不依赖手机调试、不调用微信官方 API、不上传任何数据到服务器所有操作在你本机完成。适合需要做个人数字归档、法律证据固定、家庭聊天整理、或研究微信消息结构的开发者与普通用户。如果你刚从微信 PC 端导出backup.db或从 iOS 备份中提取出MM.sqlite这个 zip 包就是你接下来 20 分钟内能跑通的最小可行入口。2. 从解压到首次成功导出三步走通 WeChatMsg-2.0.10 最小工作流WeChatMsg 是一个 Python 工具集核心逻辑是先识别微信数据库类型iOS/Android/PC 备份再加载对应解密密钥若需接着解析 WAL 日志恢复未提交事务最后按消息 ID 重建会话树并导出为可读格式。2.0.10 版本关键升级在于支持 iOS 16 的新 WAL 格式和 Android 13 的 media 表字段变更同时内置了常见机型的默认 salt 表。下面以最典型的 iOS 备份场景为例带参数讲清每一步。2.1 解压后直接运行确认环境与基础依赖WeChatMsg-2.0.10.zip 解压后目录结构如下无需安装WeChatMsg-2.0.10/ ├── wechatmsg.py # 主程序入口 ├── config/ # 配置模板与 salt 映射表 │ ├── salt_table.json # 各 iOS 版本 设备型号对应 salt 值含 iOS 16.6/17.0 │ └── default_config.json ├── output/ # 默认导出目录首次运行自动创建 └── README.md提示该工具仅依赖 Python 3.8 和标准库无需 pip install 任何包。但必须确保系统已安装pycryptodome用于 AES-CBC 解密和Pillow用于缩略图转原图。执行前请先验证python -c import Crypto.Cipher.AES; from PIL import Image; print(✅ 依赖就绪)若报错ModuleNotFoundError: No module named Crypto请运行pip install pycryptodome Pillow注意必须用pycryptodome不是pycrypto已停更且不兼容 Python 3.10Pillow用于后续将thumb目录下缩略图反向匹配原图尺寸非必需但强烈建议装上。2.2 准备微信数据库iOS 备份中定位 MM.sqlite 的真实路径iOS 备份是加密的.tar或文件夹但 WeChatMsg不处理备份加密层——它只处理已解密的MM.sqlite。所以你必须先用第三方工具如 iMazing、iBackupBot 或开源的iphone_backup_decrypt解密备份再找到微信数据库。常见路径如下以 macOS 为例备份类型典型路径解密后说明iTunes 备份~/Library/Application Support/MobileSync/Backup/backup_id/3d/3d0d7e5fb2ce288813306e406a36b41311404937/3d0d7e5...是微信 App Bundle ID 的 SHA1 前缀文件名固定为MM.sqliteFinder 备份macOS 13~/Library/Application Support/com.apple.MobileSync/Backup/backup_id/3d/.../MM.sqlite路径结构一致关键动作把MM.sqlite连同同目录下的MM.sqlite-wal和MM.sqlite-shm三个文件一起复制到一个空文件夹如~/wechat_db/缺任一文件都会导致消息丢失。WAL 文件里存着未写入主库的最新消息比如你刚发完还没同步到电脑的那条这是 WeChatMsg-2.0.10 相比旧版工具的核心优势。2.3 执行导出命令带 salt 参数跑通第一条消息进入 WeChatMsg-2.0.10 目录执行python wechatmsg.py \ --db-path ~/wechat_db/MM.sqlite \ --output-dir ~/wechat_export \ --platform ios \ --ios-salt a1b2c3d4e5f67890 \ --export-format html参数说明--db-path指向你复制好的MM.sqlite必须含-wal和-shm同级文件--output-dir导出目标文件夹自动创建建议用绝对路径--platform ios明确指定平台避免自动识别错误Android/PC 备份结构差异大--ios-saltiOS 设备的加密 salt。2.0.10 内置了常见组合但首次运行建议手动指定。salt 获取方式见第 4 章。--export-format html支持html/csv/json/mdHTML 格式带消息气泡、头像、时间轴和可点击图片最适合人工查阅。成功运行后~/wechat_export/下会生成index.html总览页列出所有聊天对象contacts/每个联系人独立 HTML 文件含全部消息图片嵌入media/还原后的原图、语音、视频按 msgId 命名非微信原始名逻辑说明wechatsmsg.py 启动后先校验 WAL 文件完整性 → 尝试用传入 salt 解密数据库页头 → 若失败则尝试 config/salt_table.json 中匹配机型 → 成功后逐条读取Message表关联Contact表补全昵称 → 对Type3图片、Type34语音等消息解析ImgPath/VoicePath字段从备份 media 文件夹中提取对应资源 → 最终按时间排序渲染为 HTML。3. salt 怎么找iOS 设备型号、系统版本、微信版本三者如何交叉匹配WeChatMsg-2.0.10 的最大门槛不是代码而是 salt。微信对MM.sqlite使用 AES-128-CBC 加密其 key 由设备唯一 salt 固定字符串拼接后 SHA256 生成。salt 不是随机的它和设备硬件、iOS 版本强绑定。2.0.10 版本将常见组合固化在config/salt_table.json中但你需要知道怎么查自己设备的对应项。3.1 快速查 salt三步定位你的设备组合第一步确认 iOS 版本与设备型号打开 iPhone「设置 → 通用 → 关于本机」记下iOS 版本如16.6.1型号如iPhone 13,4—— 注意不是“iPhone 13 Pro”而是底层代号提示iPhone 13,4 iPhone 13 ProiPhone 14,2 iPhone 14 Pro完整映射见 The iPhone Wiki 。WeChatMsg 的 salt_table.json 里用的就是这种代号。第二步确认微信版本打开微信「我 → 设置 → 关于微信」记下版本号如8.0.45。注意微信 8.0.40 开始使用新 salt 生成逻辑旧版 salt 无效。第三步查 config/salt_table.json打开WeChatMsg-2.0.10/config/salt_table.json搜索你的组合。例如{ iPhone 13,4: { iOS 16.6.1: { wechat_8.0.45: a1b2c3d4e5f67890, wechat_8.0.44: b2c3d4e5f67890a1 }, iOS 16.5: { wechat_8.0.43: c3d4e5f67890a1b2 } } }若完全匹配直接复制 salt 值填入--ios-salt若无精确匹配如你用的是 iOS 16.6.1 微信 8.0.46则取最接近的旧版 salt如wechat_8.0.45尝试——WeChatMsg 会自动 fallback 并提示是否继续。3.2 salt 手动提取当 config 表里没有你的组合时如果salt_table.json里没你的组合比如刚升 iOS 17.1就得自己提取。原理是salt 存在 iOS 备份的Manifest.plist中但被加密。WeChatMsg 提供了辅助脚本extract_salt.py位于根目录python extract_salt.py \ --backup-path ~/Library/Application Support/MobileSync/Backup/abc123... \ --device-id iPhone 13,4 \ --ios-version 17.1该脚本会解析Manifest.plist中的BackupKeyBag数据利用 iOS 设备密钥派生算法PBKDF2 device UID还原 salt输出 16 字节 hex 字符串如a1b2c3d4e5f67890注意此操作需你电脑已信任该 iPhone即曾点过“信任此电脑”否则无法读取加密备份密钥。若失败换一台曾同步过该手机的电脑重试。3.3 为什么不能跳过 salt——一次血泪经验某开发者曾试图用空 salt--ios-salt 强行运行结果所有文本消息正常导出因为部分明文字段未加密但所有图片、语音、视频路径全为空ImgPath字段解密失败返回 NULL撤回消息、红包、位置信息全部丢失这些字段强制加密导出 HTML 中图片显示为红叉语音无法播放原因微信只对敏感字段媒体路径、加密消息体、联系人手机号做 AES 加密但 key 生成强依赖 salt。没有正确 salt等于拿错钥匙开保险柜——能撬开柜门但抽屉里的东西全锁死了。salt 不是可选参数是解密前提。4. 常见问题排查5 条真实翻车现场与当场修复法WeChatMsg-2.0.10 虽稳定但在实际批量处理中仍会遇到几类高频故障。以下是我在帮某高校实验室归档 200 份 iOS 备份时踩过的坑按现象→原因→解决三步写清不甩锅、不模糊。4.1 现象Error: database disk image is malformed原因MM.sqlite-wal文件损坏或不完整。常见于 iTunes 备份中断、iMazing 导出时未勾选“包含 WAL 文件”、或 macOS Finder 备份因权限问题未复制-wal。解决删除当前MM.sqlite-wal和MM.sqlite-shm用sqlite3 MM.sqlite PRAGMA integrity_check;检查主库完整性若返回ok运行sqlite3 MM.sqlite PRAGMA journal_modeWAL;重建 WAL再次执行 wechatmsg.py此时会生成新 WAL但可能丢失最后几分钟消息4.2 现象导出 HTML 中图片显示为media/xxx.jpg但文件夹为空原因WeChatMsg 找不到 media 文件夹。它默认在MM.sqlite同级目录找Media/或Documents/但 iOS 备份解密后 media 实际在Media/PhotoData/Thumbnails/或Media/Message/下。解决用--media-path显式指定python wechatmsg.py --db-path ... --media-path ~/wechat_db/Media/Message/提示先用find ~/wechat_db -name *.jpg | head -5确认 media 实际路径WeChatMsg 会自动遍历子目录匹配MsgId。4.3 现象中文昵称/群名显示为方块或乱码原因SQLite 数据库编码为 UTF-16LE但 Python 读取时未指定编码导致Contact.NickName字段解析错误。解决在wechatmsg.py第 120 行附近conn sqlite3.connect(db_path)后插入conn.text_factory lambda x: x.decode(utf-16-le) if isinstance(x, bytes) else x血泪经验此问题在 macOS 上高频在 Linux/Windows 较少因系统默认 locale 差异。4.4 现象导出 CSV 时时间戳全是1970-01-01 08:00:00原因微信时间戳是 64 位微秒级 Unix 时间如678901234567890而旧版 pandas 或 csv 模块误当秒级处理。解决WeChatMsg-2.0.10 已内置修复但需确保你用的是--export-format csv而非手动pandas.read_sql。若仍出错加参数--timestamp-unit us强制指定单位。4.5 现象运行时报ValueError: IV must be 16 bytes long原因传入的 salt 不是 16 字节 hex 字符串如写了a1b2c3只有 6 字节或混入空格。解决用 Python 快速校验python -c sa1b2c3d4e5f67890; print(len(s), ✅ if len(s)16 and all(c in 0123456789abcdef for c in s) else ❌)输出16 ✅才有效。若含大写字母统一转小写echo A1B2C3D4E5F67890 | tr A-F a-f。5. 进阶技巧批量处理 100 备份、过滤敏感词、生成统计报告当你已跑通单个备份下一步往往是规模化处理——比如某公司法务部要归档 200 名员工的微信记录或某研究者要分析 50 个家庭群的沟通模式。WeChatMsg-2.0.10 原生支持批量但需配合 Shell 脚本和少量定制。5.1 批量导出用 for 循环 日志隔离每个备份假设你有 200 个解密后的备份文件夹路径为~/backups/backup_001/,~/backups/backup_002/…每个都含MM.sqlite。写一个batch_export.sh#!/bin/bash BACKUP_ROOT~/backups OUTPUT_ROOT~/wechat_exports LOG_FILE~/batch_export.log for dir in $BACKUP_ROOT/backup_*; do if [ -f $dir/MM.sqlite ]; then backup_id$(basename $dir) echo 开始处理 $backup_id | tee -a $LOG_FILE python WeChatMsg-2.0.10/wechatmsg.py \ --db-path $dir/MM.sqlite \ --output-dir $OUTPUT_ROOT/$backup_id \ --platform ios \ --ios-salt $(jq -r .\iPhone 13,4\.\iOS 16.6.1\.\wechat_8.0.45\ WeChatMsg-2.0.10/config/salt_table.json) \ --export-format html \ $OUTPUT_ROOT/$backup_id/export.log 21 if [ $? -eq 0 ]; then echo ✅ $backup_id 完成 | tee -a $LOG_FILE else echo ❌ $backup_id 失败查看 $OUTPUT_ROOT/$backup_id/export.log | tee -a $LOG_FILE fi fi done关键设计每个备份单独日志export.log避免 200 份日志混在一起tee -a实时追加到总日志方便监控进度失败时明确提示查哪个子日志不让你大海捞针5.2 敏感词过滤导出前自动脱敏手机号、身份证、银行卡WeChatMsg 支持导出前注入自定义清洗函数。编辑WeChatMsg-2.0.10/config/default_config.json添加{ text_filters: [ { pattern: \\b1[3-9]\\d{9}\\b, replace: [手机号已隐藏], field: Content }, { pattern: \\b\\d{17}[0-9Xx]\\b, replace: [身份证已隐藏], field: Content } ] }然后运行时加--config-path WeChatMsg-2.0.10/config/default_config.json。正则会在Content字段渲染 HTML 前执行不影响原始数据库。5.3 生成统计报告用导出的 JSON 数据算出谁最爱发语音、谁撤回最多WeChatMsg 导出的json格式是标准消息数组每条含Type,CreateTime,Status,IsSender,Content。用以下 Python 脚本快速统计# analyze_stats.py import json import glob from collections import Counter stats {voice_count: 0, revoke_count: 0, sender_msg: 0, receiver_msg: 0} type_map {34: 语音, 43: 视频, 10000: 系统消息} for json_file in glob.glob(~/wechat_exports/*/messages.json): with open(json_file) as f: msgs json.load(f) for m in msgs: if m.get(Type) 34: stats[voice_count] 1 if m.get(Status) 5: # 微信撤回状态码为 5 stats[revoke_count] 1 if m.get(IsSender): stats[sender_msg] 1 else: stats[receiver_msg] 1 print(f共处理 {len(glob.glob(~/wechat_exports/*/messages.json))} 个聊天) print(f语音消息总数{stats[voice_count]}) print(f撤回消息总数{stats[revoke_count]}) print(f你发送/接收比例{stats[sender_msg]} / {stats[receiver_msg]})这个脚本跑完只要 2 秒但能立刻告诉你过去一年你发了 1273 条语音对方撤回了 89 次——比看 100 页 HTML 快得多。我坚持用 WeChatMsg 而不是其他 GUI 工具是因为它把“可控性”刻进了基因salt 可配、media 路径可指、导出字段可筛、加密逻辑可 debug。去年帮某跨平台系统做微信数据迁移时正是靠修改wechatmsg.py里第 412 行的get_media_path()函数才把分散在 7 个子目录的语音文件全找齐。工具的价值不在多炫而在你遇到黑匣子时能亲手拧开盖子看齿轮怎么转。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

音频节奏检测实战:谱通量原理与librosa参数调优指南

音频节奏检测实战:谱通量原理与librosa参数调优指南

简介:音频节奏检测(Onset Detection)代码示例压缩包,面向音频处理与音乐信息检索开发者,以可运行的Java示例演示节拍起始点的识别流程,帮助理解从预处理、能量计算、STFT特征提取到阈值设定与事件后处理的完…

2026/10/12 22:57:46 阅读更多 →
基于Spring Boot的台球厅人员与设备管理系统设计与实现

基于Spring Boot的台球厅人员与设备管理系统设计与实现

每年一到课程设计、毕业设计的节点,总能看到大量“XX管理系统”的选题。说实话,管理系统这个大类早已被写烂了,但“基于Spring Boot的校园台球厅人员与设备管理系统”这类题目,反而是我认为性价比很高的一类。它看起来常规&#x…

2026/10/12 22:57:46 阅读更多 →
Cellebrite Inseyets PA 10.4取证数据分析实战:从原始数据到完整证据链

Cellebrite Inseyets PA 10.4取证数据分析实战:从原始数据到完整证据链

做数字取证这些年,我越来越觉得,真正耗时间的不是“提取”这一步,而是“分析”这一步。不管你用的是哪家的设备提取工具,只要手机能解锁、能被识别,总能拿到一堆数据;但拿到的是SQLite数据库、系统配置文件…

2026/10/12 22:56:46 阅读更多 →

最新新闻

Java 设计模式之 Template View:用模板视图分离静态布局与动态内容,打造可复用网页渲染骨架

Java 设计模式之 Template View:用模板视图分离静态布局与动态内容,打造可复用网页渲染骨架

示例工程教程 【免费下载链接】java-design-patterns Design patterns implemented in Java 项目地址: https://gitcode.com/GitHub_Trending/ja/java-design-patterns 点击查看 免费下载 导读:Template View(模板视图)是一种面向…

2026/10/14 2:05:18 阅读更多 →
电力弹簧技术在主动配电网中的关键应用与优化

电力弹簧技术在主动配电网中的关键应用与优化

1. 电力弹簧技术背景与配电网痛点电力弹簧(Electric Spring)作为第三代柔性电力电子装置,本质上是一种具备快速响应能力的电压/电流双模式补偿器。与传统STATCOM、SVG等无功补偿设备相比,其独特之处在于能够通过智能控制算法主动调…

2026/10/14 2:05:18 阅读更多 →
OpenClaw 会话工具(Session Tools)完全指南:sessions_list / sessions_history / sessions_send / sessions_spawn

OpenClaw 会话工具(Session Tools)完全指南:sessions_list / sessions_history / sessions_send / sessions_spawn

人工智能大模型LLM 网关AI Agent即时通讯 【免费下载链接】openclaw-zero-token OpenClaw: Use All Major AI Models NO API Token! Claude/ChatGPT/Gemini/DeepSeek/Doubao/Grok/Qwen/Manus/Kimi 项目地址: https://gitcode.com/gh_mirrors/op/openclaw-zero-token…

2026/10/14 2:05:18 阅读更多 →
T3 Stack实战:t3code如何实现端到端类型安全的全栈开发

T3 Stack实战:t3code如何实现端到端类型安全的全栈开发

t3code 这个名字,乍一看确实有点抽象。但如果你这几年一直混在 Next.js 和 TypeScript 的圈子里,看到 t3 前缀,大概率会想到那个火得一塌糊涂的 T3 Stack——Next.js、TypeScript、tRPC、Prisma、Tailwind 再加上 NextAuth 的组合。t3code 其…

2026/10/14 2:05:18 阅读更多 →
仓颉框架 CJoy 配置模块测试设计:从 config-tests 规格到测试用例实现

仓颉框架 CJoy 配置模块测试设计:从 config-tests 规格到测试用例实现

后端Web框架MCP 服务 【免费下载链接】cjoy 一个高性能、可扩展、轻量、省心的仓颉应用开发框架。IoC,Rest,宏路由,Json,中间件,参数绑定与校验,文件上传下载,OAuth2,MCP...... 项目…

2026/10/14 2:05:18 阅读更多 →
voidImageViewer 项目内 WebP 规范文档生成指南:用 kramdown 从 Markdown 文本源构建 Container Spec HTML

voidImageViewer 项目内 WebP 规范文档生成指南:用 kramdown 从 Markdown 文本源构建 Container Spec HTML

桌面应用图像处理 【免费下载链接】voidImageViewer Lightweight image viewer for Windows with animated GIF/WEBP support 项目地址: https://gitcode.com/gh_mirrors/vo/voidImageViewer 点击查看 免费下载 本篇技术指南讲解 voidImageViewer 仓库所集成的 lib…

2026/10/14 2:04:18 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →