Python 把 .h5 文件转成 CSV:TaoToken 辅助排查转换报错与字段映射
1. 从 .h5 到 CSV为什么你的转换脚本总在报错如果你在做深度学习实验尤其是联邦学习、模型压缩或者 Kaggle 比赛.h5这个后缀一定不陌生。Keras/TensorFlow 保存模型权重用它很多实验框架保存训练日志也用它。它本质是 HDF5 格式一种层级化的二进制容器你可以把它理解成「硬盘里的文件夹结构」里面有 group组group 下面还有 dataset数据集dataset 才是真正存数组的地方。问题就出在这个层级结构上。很多人第一次写转换脚本直接pd.DataFrame(f)或者f[accuracy]结果要么报KeyError要么读出来是一堆看不懂的嵌套对象要么内存直接爆掉。我见过最典型的情况是一个 2GB 的.h5文件里面存了 50 轮训练的完整权重脚本一跑MemoryError机器直接卡死。这篇内容就是解决这件事的。我会带你走完 Python 读取.h5并导出 CSV 的完整流程先用h5py把文件结构摸清楚再用pandas做字段映射和编码处理最后给出可复制的脚本。同时针对转换过程中最容易出现的三类报错——KeyError、MemoryError、编码异常——我会给出具体的定位步骤。另外当你需要批量校验字段名或者确认某个数据集到底叫什么时可以用 TaoToken 统一 Key 调用辅助接口做一次快速验证避免在本地反复试错。适合谁看正在跑实验、手里有一堆.h5结果文件、想把它们转成 CSV 做可视化或进一步分析的人。不需要你是 HDF5 专家但需要你会基本的 Python 和 pandas 操作。先说结论.h5转 CSV 的核心不是「转换」这个动作而是「先看清结构再决定取哪一层」。下面按步骤来。2. 前置准备h5py、pandas 与 TaoToken 统一 Key 的定位在动手写脚本之前先把环境和工具理清楚。这一节不涉及复杂配置主要是让你知道每个工具负责什么以及 TaoToken 在这个流程里扮演什么角色。2.1 安装依赖h5py 和 pandas 是主力读取.h5文件最常用的两个库是h5py和pandas。h5py负责底层读取能让你像操作字典一样遍历 HDF5 的层级结构pandas负责把读出来的数组转成 DataFrame 并写出 CSV。另外tables这个库在某些.h5文件尤其是 PyTables 格式上是必需的建议一起装上。pip install h5py pandas tables如果你用的是 conda 环境也可以conda install h5py pandas pytables装完之后用下面这行快速验证import h5py import pandas as pd print(h5py.__version__, pd.__version__)能正常打印版本号说明环境没问题。2.2 TaoToken 在这里做什么字段校验与结构确认TaoToken 是一个统一 API 接入平台官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。它的作用是当你面对一个陌生的.h5文件不确定里面的 group 和 dataset 命名规律时可以把h5py打印出来的结构信息整理成文本通过 TaoToken 的模型对话接口做一次语义校验比如确认「这个 key 是不是代表训练准确率」「字段命名是否符合常见框架习惯」。API 地址是 https://taotoken.net/api 统一 Key 在控制台的 API Keys 页面获取https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。拿到 Key 之后你可以在脚本里加一段辅助校验逻辑也可以在调试阶段手动调用。需要强调的是TaoToken 不是用来替代h5py读取的它不直接读你的.h5文件。它的定位是「辅助判断」——当你对字段含义拿不准时用模型对话快速确认减少反复试错的时间。模型对话入口https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。2.3 一个容易忽略的点文件路径与编码.h5文件本身是二进制格式不涉及文本编码。但导出 CSV 时如果字段名或数据里包含中文、特殊符号就会遇到编码问题。建议统一用utf-8-sig这样 Excel 打开不会乱码。这个细节后面在排错章节会展开。前置准备就这些。接下来进入核心可复制的读取与导出配置。3. 可复制配置h5py 读取、层级选择与 CSV 导出脚本这一节是全文的核心。我会给出一个完整的脚本从打开.h5文件、遍历结构、选择 dataset、到导出 CSV每一步都配上说明。你可以直接复制到 Jupyter 或.py文件里跑。3.1 第一步先看清结构别急着转很多人一上来就pd.DataFrame(data).to_csv()结果报错。正确做法是先打印结构。下面这段代码会递归遍历所有 group 和 dataset输出它们的名称、形状和类型import h5py filename Mnist_FEDL_0.003_0_10u_20b_5_avg.h5 def print_h5_structure(name, obj): if isinstance(obj, h5py.Dataset): print(f[Dataset] {name} | shape{obj.shape} | dtype{obj.dtype}) elif isinstance(obj, h5py.Group): print(f[Group] {name}) with h5py.File(filename, r) as f: print( 顶层 Keys ) print(list(f.keys())) print(\n 完整结构 ) f.visititems(print_h5_structure)跑完之后你会看到类似这样的输出 顶层 Keys [accuracy, loss, weights] 完整结构 [Dataset] accuracy | shape(50,) | dtypefloat32 [Dataset] loss | shape(50,) | dtypefloat32 [Group] weights [Dataset] weights/conv1 | shape(32, 1, 3, 3) | dtypefloat32看到这个结构你就知道该取哪一层了。accuracy和loss是直接可转 CSV 的一维数组weights下面的 dataset 是模型参数通常不需要转 CSV除非你要做权重分析。3.2 第二步选择 dataset 并转成 DataFrame假设你要导出accuracy、loss和训练准确率。根据结构顶层有accuracy和loss训练准确率可能在另一个 group 下。下面是一个通用的导出函数import h5py import pandas as pd import numpy as np def h5_to_csv(filename, dataset_path, output_csv, columnsNone): 从 .h5 文件中读取指定 dataset 并导出为 CSV :param filename: .h5 文件路径 :param dataset_path: dataset 路径如 accuracy 或 train/acc :param output_csv: 输出 CSV 路径 :param columns: 列名列表可选 with h5py.File(filename, r) as f: if dataset_path not in f: raise KeyError(f路径 {dataset_path} 不存在请检查结构) data f[dataset_path][()] # 处理不同维度 if data.ndim 1: df pd.DataFrame(data, columnscolumns or [value]) elif data.ndim 2: df pd.DataFrame(data, columnscolumns) else: # 高维数据先展平 df pd.DataFrame(data.reshape(data.shape[0], -1)) df.to_csv(output_csv, indexFalse, encodingutf-8-sig) print(f已导出 {dataset_path} - {output_csv}形状 {df.shape}) return df # 使用示例 h5_to_csv(filename, accuracy, accuracy.csv, columns[accuracy]) h5_to_csv(filename, loss, loss.csv, columns[loss])这段代码的关键点有三个一是用f[dataset_path][()]把数据完整读进内存注意[()]不能省否则拿到的是 dataset 对象而不是数组二是根据维度决定 DataFrame 的构造方式三是统一用utf-8-sig编码写出。3.3 第三步批量导出多个 dataset如果你有多个 dataset 要导出可以写一个循环targets { accuracy: global_accuracy.csv, loss: train_loss.csv, train/acc: train_accuracy.csv, } for path, out in targets.items(): try: h5_to_csv(filename, path, out) except KeyError as e: print(f跳过 {path}: {e})这样即使某个路径不存在也不会中断整个流程。3.4 第四步用 TaoToken 做字段校验可选但推荐当你面对一个命名不规范的.h5文件比如 key 叫res_0、res_1、res_2你无法确定哪个是准确率、哪个是损失。这时候可以把结构信息整理成文本通过 TaoToken 的模型对话接口做一次语义判断。调用方式Python 示例import requests API_URL https://taotoken.net/api API_KEY 你的统一Key # 从 https://taotoken.net/console/api-keys 获取 def check_fields(structure_text): headers { Authorization: fBearer {API_KEY}, Content-Type: application/json } payload { model: gpt-4o-mini, messages: [ {role: system, content: 你是HDF5结构分析助手根据dataset名称和形状判断其含义。}, {role: user, content: f以下是一个.h5文件的结构请判断每个dataset最可能代表什么\n{structure_text}} ] } resp requests.post(f{API_URL}/v1/chat/completions, headersheaders, jsonpayload) return resp.json()[choices][0][message][content] structure [Dataset] res_0 | shape(50,) | dtypefloat32 [Dataset] res_1 | shape(50,) | dtypefloat32 [Dataset] res_2 | shape(50,) | dtypefloat32 print(check_fields(structure))返回结果通常会告诉你res_0可能是全局准确率、res_1是训练准确率、res_2是训练损失。这样你就能准确映射字段而不是靠猜。如果你需要长期做这类辅助校验可以考虑 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 适合需要频繁调用接口做批量处理的场景。配置部分到这里。下面进入验证环节。4. 验证请求与成功结果确认 CSV 内容正确脚本跑完不代表任务结束。你需要验证导出的 CSV 内容是否和.h5里的数据一致。这一节给出具体的验证方法。4.1 读取 CSV 并对比形状最直接的方式是把导出的 CSV 读回来对比行数和数值范围import pandas as pd import h5py # 读回 CSV df_csv pd.read_csv(accuracy.csv) print(CSV 形状:, df_csv.shape) print(前5行:) print(df_csv.head()) # 对比原始 h5 with h5py.File(filename, r) as f: original f[accuracy][()] print(原始形状:, original.shape) print(原始前5个值:, original[:5]) print(CSV 前5个值:, df_csv[accuracy].values[:5]) print(是否一致:, np.allclose(original, df_csv[accuracy].values))如果np.allclose返回True说明数值没有丢失或错位。4.2 检查字段映射是否正确字段映射错误是常见问题。比如你把loss导成了accuracy.csv数值看起来正常但含义完全错了。验证方法是看数值范围准确率通常在 0 到 1 之间损失值可能大于 1。如果accuracy.csv里出现了 2.5 这样的值那大概率映射错了。print(accuracy 范围:, df_csv[accuracy].min(), df_csv[accuracy].max())4.3 用 TaoToken 做二次校验如果你对某个字段的含义仍然不确定可以把 CSV 的统计信息和原始结构一起发给 TaoToken让它帮你判断summary f dataset: res_0 shape: (50,) min: {df_csv[value].min():.4f} max: {df_csv[value].max():.4f} mean: {df_csv[value].mean():.4f} print(check_fields(summary))模型会根据数值范围给出判断比如「min 0.1、max 0.98、mean 0.85符合准确率特征」。4.4 成功结果的标志一次成功的转换应该满足以下条件检查项预期结果CSV 行数与 dataset 第一维一致数值范围符合字段语义准确率 0-1损失 0编码Excel 打开无乱码列名与预期字段映射一致无缺失值df.isnull().sum()全为 0全部通过说明转换成功。接下来看排错。5. 常见报错排查KeyError、MemoryError、编码异常这一节针对三类高频报错给出具体的定位步骤和解决方案。每个报错都配上真实错误信息和修复代码。5.1 KeyError: 路径不存在错误信息KeyError: Unable to open object (object train_acc doesnt exist)原因你写的 dataset 路径和实际结构不一致。HDF5 是大小写敏感的Accuracy和accuracy是两个不同的 key。定位步骤with h5py.File(filename, r) as f: def find_keys(name, obj): if isinstance(obj, h5py.Dataset): print(name) f.visititems(find_keys)把所有 dataset 路径打印出来复制准确的路径。注意 group 和 dataset 之间用/分隔比如train/accuracy。修复把脚本里的路径改成实际存在的路径。如果路径是动态的加一层判断if train_acc in f: data f[train_acc][()] elif train/acc in f: data f[train/acc][()] else: raise KeyError(未找到训练准确率字段)5.2 MemoryError: 内存不足错误信息MemoryError: Unable to allocate 2.5 GiB for an array with shape (800000000,) and data type float32原因.h5文件里的 dataset 太大一次性读进内存导致溢出。常见于模型权重或大规模特征矩阵。定位步骤with h5py.File(filename, r) as f: for key in f.keys(): if isinstance(f[key], h5py.Dataset): print(key, f[key].shape, f[key].dtype)找到 shape 特别大的 dataset计算内存占用shape[0] * shape[1] * 4 / 1024**3GBfloat32 是 4 字节。解决方案一分块读取。def h5_to_csv_chunked(filename, dataset_path, output_csv, chunk_size10000): with h5py.File(filename, r) as f: dset f[dataset_path] n dset.shape[0] first True for start in range(0, n, chunk_size): end min(start chunk_size, n) chunk dset[start:end] df pd.DataFrame(chunk) df.to_csv(output_csv, modea, headerfirst, indexFalse, encodingutf-8-sig) first False print(f分块导出完成: {output_csv})解决方案二只导出需要的列或切片。# 只取前1000行 data f[large_dataset][:1000]解决方案三如果 dataset 是高维的先 reshape 再决定是否全量导出。5.3 编码异常中文乱码或 UnicodeDecodeError错误信息UnicodeDecodeError: utf-8 codec cant decode byte 0xd3 in position 12或者 CSV 用 Excel 打开后中文变成乱码。原因.h5里的字符串数据可能是bytes类型或者 CSV 写出时用了默认编码。定位步骤with h5py.File(filename, r) as f: for key in f.keys(): obj f[key] if isinstance(obj, h5py.Dataset) and obj.dtype.kind S: print(f{key} 是 bytes 类型需要解码)修复对 bytes 类型做解码。data f[labels][()] if data.dtype.kind S: data np.array([x.decode(utf-8) for x in data])CSV 写出时统一用utf-8-sigdf.to_csv(output.csv, indexFalse, encodingutf-8-sig)5.4 其他常见问题报错原因解决OSError: Unable to open file文件路径错误或文件损坏检查路径用h5py.File试打开ValueError: cannot reshape维度不匹配先打印 shape 再 reshapeTypeError: Object dtype dtype(O) has no native HDF5 equivalent存了不支持的类型转换前先转成数值或字符串local proxy failed网络请求配置问题检查 API 地址和网络环境401 UnauthorizedTaoToken Key 无效重新从控制台获取 Keyreading choices相关错误接口返回格式异常检查请求体 JSON 格式如果你在调用 TaoToken 接口时遇到401先去 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 确认 Key 是否正确。遇到local proxy failed检查本地网络设置确保 API 地址是https://taotoken.net/api。排错部分到这里。最后说一下工具入口。6. 工具入口与后续建议整个流程走下来核心就是三步先用h5py看清结构再用pandas做映射和导出最后验证数值一致性。.h5转 CSV 本身不复杂复杂的是面对不规范的文件结构时如何快速定位。如果你需要频繁做字段校验TaoToken 的模型对话接口可以帮你省去反复试错的时间https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。API Key 在控制台获取https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你在做长期的实验数据处理需要批量调用接口做字段映射和校验可以看看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。最后一个实用技巧转换完成后把 CSV 的列名和.h5的 dataset 路径做一个映射表存下来下次遇到同框架产出的文件直接复用映射关系不用重新遍历结构。这个习惯能帮你省下大量重复劳动。

相关新闻

风机选型工具安装部署与选型参数复核实战指南

风机选型工具安装部署与选型参数复核实战指南

简介:昆仑风机选型工具V3.2.6面向暖通、环保、冶金与电力行业的工程技术人员,聚焦风机初选、参数校核与方案比对的常见场景,支持输入风量、风压、功率、转速等关键参数,并通过内置厂商数据库和选型逻辑自动匹配可用的适配型号及基…

2026/10/17 21:44:48 阅读更多 →
物质点法边坡大变形模拟实战:Anura3d滑坡全过程仿真与参数分析

物质点法边坡大变形模拟实战:Anura3d滑坡全过程仿真与参数分析

开头部分,我先交代一下这个项目的来龙去脉。去年课题组接到某山区公路边坡的稳定性评估任务,坡体长期受降雨影响,表面已经出现了明显的裂缝和局部溜坍迹象,传统极限平衡法算出来的安全系数恰好卡在规范值边缘,但业主想…

2026/10/17 21:44:48 阅读更多 →
软件需求规格说明书模板:让开发测试甲方不再各说各话

软件需求规格说明书模板:让开发测试甲方不再各说各话

简介:这份文档是一份内容详尽的软件需求规格说明书(SRS)模板,主要面向软件开发人员、需求分析师及项目管理者,用于解决需求文档结构混乱、要素缺失、难以评审验收等常见问题。文档以移动办公系统为贯穿案例&#xff0c…

2026/10/17 21:44:48 阅读更多 →

最新新闻

PPT作为数据工程文档:提取嵌入式指标、SQL与血缘的实战指南

PPT作为数据工程文档:提取嵌入式指标、SQL与血缘的实战指南

简介:本资源是一份面向高校计算机、信息管理及相关专业师生的大数据分析入门课件,系统讲解大数据时代背景、核心特征与技术应用路径。PPT内容紧扣教学需求,完整覆盖大数据的‘4V’特征(体量、多样性、速度、价值密度)、…

2026/10/17 22:25:25 阅读更多 →
OpenSSL C++生成含中文DN的证书请求CSR完整指南

OpenSSL C++生成含中文DN的证书请求CSR完整指南

1. 为什么要让DN支持中文:场景与核心难点只要公司注册名里带中文,做证书请求(CSR)就注定绕不开"中文DN"这个坎。用OpenSSL的命令行一把梭虽然简单,但到了C工程化集成的场景,比如你要在服务端程序…

2026/10/17 22:25:25 阅读更多 →
密码分析学:从差分特征到S盒安全验证的实战方法论

密码分析学:从差分特征到S盒安全验证的实战方法论

1. 这门课到底在讲什么:从“破译”到“设计”的思维翻转“第五讲 密码分析学”——光看标题,很多人第一反应是:这不就是教人怎么黑进系统、怎么破解别人密码的“黑客速成班”?其实恰恰相反。我带过几届某高校信息安全方向的实践课…

2026/10/17 22:25:25 阅读更多 →
Coppersmith攻击实战:已知p高位比特分解RSA模数

Coppersmith攻击实战:已知p高位比特分解RSA模数

假设你手里有一份泄露出来的日志片段,上面只有几行十六进制字符串,其中一行恰好是某个RSA公钥的模数n,另一行则是p的前半段比特。看起来好像没什么用——毕竟只知道一半,剩下的512位不还是要跑穷举?但如果你懂Coppersm…

2026/10/17 22:25:25 阅读更多 →
有道翻译API接入实战:从签名到批量翻译的完整指南

有道翻译API接入实战:从签名到批量翻译的完整指南

1. 从零上手有道翻译API:一个后端开发者的接入实录翻译能力几乎是现代应用开发的标配需求。无论是做跨境电商的商品描述本地化、做在线教育平台的课件多语言适配,还是做一个简单的浏览器插件帮用户快速看懂外文资料,背后都绕不开一个稳定可靠…

2026/10/17 22:25:25 阅读更多 →
AI赋能企业变革:人才先行落地路径与避坑指南

AI赋能企业变革:人才先行落地路径与避坑指南

简介:一份关于2025年AI赋能企业变革与人才先行的专题PDF,面向企业管理层、HR专家、部门经理及一线骨干,解决AI转型中“技术易得、人才难配”的核心痛点。内容引用麦肯锡预测,到2030年AI将为中国关键产业创造超6000亿美元价值&…

2026/10/17 22:24:24 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 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/16 21:54:38 阅读更多 →
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/16 14:23:36 阅读更多 →