上网家长控制软件工程拆解:DNS过滤、SNI嗅探与eBPF高性能识别
简介这是一份面向家长与家庭教育场景的上网控制软件源码资源用于帮助父母管理孩子的网络访问行为解决网址过滤、上网时长限制与设备管控等实际问题适合具备一定C#基础的开发者学习或二次开发。压缩包共40个文件约4.11MB以cs源码文件为主配合resx资源、ico图标、exe可执行程序、dll与pdb调试文件以及csproj、sln工程配置和settings、manifest等辅助文件构成一套可编译运行的完整工程。内容围绕网址检测、锁屏与系统操作等模块展开包含窗体设计、资源定义与程序入口等结构便于读者理解家长控制类工具的功能划分与实现思路。目前已有454人学习下载可作为网络行为管理、桌面端监控类项目的参考范例帮助开发者快速掌握过滤规则、时段控制与界面交互的落地方式。1. 上网家长控制软件从“能拦”到“拦得准”的工程拆解很多家长第一次装上网家长控制软件诉求都很朴素别让孩子刷到不该看的东西别在写作业时偷偷打游戏。但真到自己动手做一套或者给家里那台旧路由器刷个固件时才发现事情没那么简单。拦不住、误拦、被绕过是三个最常翻车的点。这套软件本质上是一套跑在网关或终端上的流量识别与策略执行系统核心能力就三块识别谁在上网、识别在访问什么、决定放行还是阻断。它适合两类人一类是想给自己家搭一套可控环境的开发者另一类是需要在产品里集成家长控制模块的工程师。下面按“先跑通最小闭环再抠识别精度最后处理绕过与性能”的顺序讲。2. 最小可用闭环DNS 过滤加时间窗策略怎么落地2.1 为什么第一版不建议直接上深度包检测新手最容易犯的错是一上来就想做全流量深度包检测DPI觉得只有看清每一个包才叫控制。实际落地时DPI 对硬件要求高家用网关那点 CPU 跑不动而且加密流量占比越来越高硬解只会让设备发热、延迟飙升。更务实的路径是分层第一层用 DNS 过滤挡住绝大多数域名级访问第二层用时间窗策略控制“能不能上网”第三层才在必要时对特定应用做特征识别。DNS 过滤的好处是成本极低一个树莓派或者旧笔记本就能跑而且对 HTTPS 站点同样有效因为域名解析这一步是绕不开的。我一般会先搭一个 DNS 转发加过滤的服务把家里所有设备的 DNS 都指到它上面。这样不需要在每台设备装客户端也不用改路由器固件改一下 DHCP 下发的 DNS 地址就行。下面是一个基于 Python 的最小 DNS 过滤示例用 dnslib 库实现逻辑是查白名单和黑名单命中黑名单就返回一个空地址。# dns_filter.py # 依赖: pip install dnslib from dnslib import DNSRecord, RR, QTYPE, A from dnslib.server import DNSServer, BaseResolver # 黑名单命中则返回 0.0.0.0相当于阻断 BLOCKLIST { example-game.com, example-video.net, } # 白名单优先级高于黑名单用于放行必要服务 ALLOWLIST { school-example.edu, } class ParentalResolver(BaseResolver): def resolve(self, request, handler): reply request.reply() qname str(request.q.qname).rstrip(.).lower() qtype QTYPE[request.q.qtype] # 只处理 A 记录其他类型直接转发或忽略 if qtype ! A: return reply if qname in ALLOWLIST: # 白名单直接返回一个占位地址实际应转发到上游 reply.add_answer(RR(qname, QTYPE.A, rdataA(192.168.1.1), ttl60)) return reply if qname in BLOCKLIST: # 返回 0.0.0.0 表示阻断客户端会连接失败 reply.add_answer(RR(qname, QTYPE.A, rdataA(0.0.0.0), ttl60)) return reply # 未命中任何名单返回一个默认地址实际应转发 reply.add_answer(RR(qname, QTYPE.A, rdataA(192.168.1.1), ttl60)) return reply if __name__ __main__: resolver ParentalResolver() server DNSServer(resolver, port53, address0.0.0.0) server.start()这段代码的关键参数有三个BLOCKLIST和ALLOWLIST是策略集合实际生产中应该从数据库或配置文件加载而不是硬编码ttl60控制缓存时间设短一点能让策略变更更快生效但会增加查询量返回0.0.0.0是一种阻断方式优点是客户端立刻失败缺点是有些应用会重试导致日志刷屏。更优雅的做法是返回一个内网 Web 服务器的地址弹一个提示页但那就需要额外跑一个 HTTP 服务。2.2 时间窗策略用 cron 还是自己写调度时间窗是家长控制里最实用的功能比如“周一到周五 19:00 到 21:00 允许上网其余时间阻断”。实现方式有两种一种是用系统 cron 在特定时间点切换防火墙规则或 DNS 过滤开关另一种是在过滤服务里内置一个时间判断每次查询时检查当前是否在允许时段。cron 的优点是简单缺点是粒度粗切换瞬间可能有连接残留内置判断更灵活但每次查询都要算一次时间高频查询下要注意性能。我一般会选内置判断因为可以做到秒级精度而且方便做“临时加时”这种交互。下面是一个时间窗判断的片段配合上面的 DNS 过滤器使用。# time_window.py from datetime import datetime, time # 定义允许上网的时间段周一到周五 19:00-21:00周末 9:00-21:00 WEEKDAY_WINDOW (time(19, 0), time(21, 0)) WEEKEND_WINDOW (time(9, 0), time(21, 0)) def is_allowed_now(nowNone): now now or datetime.now() weekday now.weekday() # 0 是周一6 是周日 current now.time() if weekday 5: start, end WEEKDAY_WINDOW else: start, end WEEKEND_WINDOW return start current end # 在 resolver 里调用 # if not is_allowed_now(): # return block_response()这里要注意时区问题datetime.now()取的是系统本地时间如果设备时区设错策略就会错乱。另外跨天的时间段比如 22:00 到次日 6:00需要额外处理不能简单用start current end得判断current start or current end。这个坑我在第一次做的时候踩过孩子半夜还能上网查了半天才发现是时间窗写反了。3. 识别精度域名匹配、SNI 嗅探与误拦处理3.1 域名匹配不是字符串相等那么简单DNS 过滤的核心是域名匹配但实际域名千奇百怪。比如www.example.com和example.com是不是同一个策略a.b.example.com要不要继承example.com的规则还有 CDN 域名同一个 IP 对应几百个域名按 IP 封会误伤一大片。我一般会实现三级匹配精确匹配、后缀匹配、关键词匹配。精确匹配用于白名单后缀匹配用于黑名单比如封example.com连带封所有子域关键词匹配作为兜底但容易误伤要谨慎用。下面是一个域名匹配的示例用后缀树的方式做高效匹配。# domain_matcher.py class DomainMatcher: def __init__(self): self.exact set() self.suffix set() self.keywords [] def add_exact(self, domain): self.exact.add(domain.lower()) def add_suffix(self, domain): # 去掉开头的点统一格式 self.suffix.add(domain.lower().lstrip(.)) def add_keyword(self, kw): self.keywords.append(kw.lower()) def match(self, domain): domain domain.lower().rstrip(.) if domain in self.exact: return exact # 后缀匹配example.com 能匹配 www.example.com parts domain.split(.) for i in range(len(parts)): candidate ..join(parts[i:]) if candidate in self.suffix: return suffix for kw in self.keywords: if kw in domain: return keyword return None参数说明exact集合用于精确放行比如学校域名suffix集合用于封禁整个域比如游戏平台keywords是最后手段比如封含“game”的域名但会误伤example.com/game这种正常路径所以只建议在域名层面用不要对 URL 路径用。匹配顺序必须是精确优先、后缀其次、关键词最后否则白名单会被黑名单覆盖。3.2 SNI 嗅探加密流量下还能看到什么DNS 过滤只能挡域名解析如果设备直接用 IP 访问或者用了 DoHDNS over HTTPSDNS 层就失效了。这时候需要看 TLS 握手时的 SNI 字段。SNI 是明文传输的里面包含目标域名可以在网关抓包解析。但要注意SNI 嗅探需要处理性能千兆网线下每秒几万个包用 Python 抓包会丢包得用 C 或者 eBPF。我一般会在 Linux 网关上用tcpdump配合tshark做离线分析线上则用nDPI或Suricata这类成熟库。下面是一个用scapy解析 SNI 的示例只适合低流量场景做验证。# sni_sniffer.py # 依赖: pip install scapy from scapy.all import sniff, TCP, IP, Raw def extract_sni(payload): # TLS ClientHello 的 handshake type 是 0x01 if len(payload) 6: return None if payload[0] ! 0x16: # handshake return None # 跳过 record 头找 handshake 类型 if payload[5] ! 0x01: return None # 简化解析实际要按 TLS 结构逐层偏移 # 这里只做演示生产环境用 nDPI try: # 找到 server_name 扩展的偏移不同实现有差异 idx payload.find(b\x00\x00) # 仅示意 if idx 0: return payload[idx4:idx420].decode(utf-8, errorsignore) except Exception: return None return None def handle_packet(pkt): if pkt.haslayer(TCP) and pkt.haslayer(Raw): sni extract_sni(bytes(pkt[Raw])) if sni: print(SNI:, sni) # 只抓 443 端口避免全量抓包 sniff(filtertcp port 443, prnhandle_packet, store0)这段代码的extract_sni是简化版真实 TLS 解析要按record - handshake - client hello - extensions逐层读长度字段偏移算错就会读出乱码。参数上filtertcp port 443能减少干扰但 DoH 走 443 也会被看到只是 SNI 可能是 CDN 域名需要结合 IP 反查。性能上sniff默认用 libpcap高流量下会丢包建议用count限制包数或改用nDPI的 C 接口。3.3 误拦处理白名单怎么设计才不背锅误拦是家长控制软件最容易被投诉的点。孩子说“老师发的链接打不开”一查是关键词匹配把example-school.com封了。避免误拦的核心是白名单要覆盖三类教育类域名、常用工具类域名、支付类域名。教育类包括学校官网、在线作业平台工具类包括搜索引擎、地图、文档协作支付类包括银行、支付平台这些被封会导致家长自己也没法用。白名单的优先级必须高于黑名单而且白名单要支持通配符比如*.edu.cn。我一般会维护一个allowlist.txt每行一个域名支持*.前缀表示子域通配。加载时解析成后缀集合匹配时先查白名单再查黑名单。另外白名单要允许家长手动添加并且添加后立即生效不能等重启。实现上可以用文件监听inotify或者定时重载我倾向用inotify因为延迟低。4. 绕过与对抗DoH、代理和 MAC 随机化怎么破4.1 DoH 让 DNS 过滤失效怎么补DoHDNS over HTTPS把 DNS 查询加密后走 443 端口传统的 DNS 过滤完全看不到。孩子只要在浏览器里开启“安全 DNS”或者装个支持 DoH 的浏览器DNS 过滤就废了。应对方式有三种一是封禁已知的 DoH 服务器 IP 和域名比如cloudflare-dns.com、dns.google但这是猫鼠游戏二是在网关上做 SNI 嗅探发现 DoH 流量就阻断三是强制所有设备用指定的 DNS通过防火墙规则把 53 端口和 853 端口的流量重定向到自己的 DNS 服务。我一般会组合用先封常见 DoH 域名再用 iptables 把 53 和 853 重定向。下面是一个 iptables 示例。# 把局域网内所有设备的 DNS 查询重定向到本地 DNS 服务 # 假设本地 DNS 服务监听 192.168.1.2:53 iptables -t nat -A PREROUTING -i br0 -p udp --dport 53 -j DNAT --to-destination 192.168.1.2:53 iptables -t nat -A PREROUTING -i br0 -p tcp --dport 53 -j DNAT --to-destination 192.168.1.2:53 # 封禁 DoT 的 853 端口 iptables -A FORWARD -p tcp --dport 853 -j DROP iptables -A FORWARD -p udp --dport 853 -j DROP参数说明-i br0是局域网网桥接口不同系统可能是eth0或br-lanDNAT把目标地址改成自己的 DNS这样即使设备手动设了 8.8.8.8 也会被劫持DROP853 端口会阻断 DoT但有些应用会回退到普通 DNS所以重定向 53 是关键。注意如果家长自己需要用 DoH得把家长的设备 MAC 加入白名单跳过重定向。4.2 MAC 随机化与设备识别现代手机默认开启 MAC 随机化每次连 Wi-Fi 都换一个 MAC导致基于 MAC 的策略全部失效。识别设备不能只看 MAC要结合 DHCP 指纹、主机名、User-Agent 等多维度。我一般会在 DHCP 服务里记录hostname和client-id然后和 MAC 做关联。即使 MAC 变了hostname通常不变可以据此识别。如果hostname也被改那就只能靠行为特征比如访问的域名集合但这复杂度就高了。下面是一个 DHCP 指纹记录的示例用dnsmasq的日志解析。# dnsmasq 日志格式示例 # dnsmasq-dhcp: DHCPACK(br0) 192.168.1.100 aa:bb:cc:dd:ee:ff hostname # 用 awk 提取 MAC 和 hostname 的对应关系 awk /DHCPACK/ {print $4, $5, $6} /var/log/dnsmasq.log | sort -u这个命令输出IP MAC hostname三列可以导入数据库做设备档案。参数上$4是 IP$5是 MAC$6是主机名但不同 dnsmasq 版本字段位置可能不同要先head看几行确认。如果主机名是android-xxxx这种随机串那就只能靠 IP 段或者时间段来区分了。5. 避坑与排查那些让我熬夜的翻车现场5.1 现象策略改了但不生效重启才好原因DNS 缓存没刷新客户端和本地 DNS 都缓存了旧记录。解决把 TTL 设短同时在策略变更后主动清空本地 DNS 缓存或者给响应加no-cache头。更彻底的做法是策略变更时发一个SIGHUP给 DNS 服务让它重载配置。5.2 现象孩子说“网速变慢”测速只有原来一半原因DNS 过滤服务性能不足或者 iptables 规则太多导致包处理变慢。解决用top看 DNS 进程 CPU如果跑满就换 C 实现或者加缓存iptables 规则用iptables -L -n -v看命中计数把高频规则放前面低频的用ipset合并。5.3 现象某些 App 完全用不了但网页正常原因App 不走系统 DNS而是自己内置 DoH 或者直接连 IP。解决抓包看 App 的流量特征如果是固定 IP就封 IP如果是 DoH就按 4.1 的方法重定向。注意封 IP 可能误伤同 IP 的其他服务要谨慎。5.4 现象白名单加了学校域名但还是打不开原因学校网站引用了第三方 CDN 的 JS 和 CSS这些域名不在白名单里。解决用浏览器开发者工具看 Network 面板把关键第三方域名也加白。或者更省事对教育类流量做“宽松模式”只封黑名单不限制其他。5.5 现象日志里大量0.0.0.0查询设备疯狂重试原因返回0.0.0.0后有些应用会不断重试导致日志爆炸和电量消耗。解决改成返回一个内网提示页的 IP或者返回NXDOMAIN让客户端认为域名不存在减少重试。NXDOMAIN在 dnslib 里可以用reply.header.rcode RCODE.NXDOMAIN设置。6. 进阶技巧用 eBPF 做高性能流量识别与验证当设备多了、流量大了用户态抓包和 iptables 匹配会成为瓶颈。我后来把核心识别逻辑迁到了 eBPF在 XDP 层做初步过滤只把可疑流量送到用户态。这样千兆网线下 CPU 占用从 80% 降到 15% 左右。下面是一个 eBPF 程序的骨架用bcc编写功能是统计每个 IP 的 DNS 查询次数超过阈值就告警。# dns_monitor.py # 依赖: pip install bcc from bcc import BPF program r #include uapi/linux/ptrace.h #include net/sock.h #include bcc/proto.h BPF_HASH(dns_count, u32, u64); int kprobe__udp_sendmsg(struct pt_regs *ctx, struct sock *sk, struct msghdr *msg, size_t len) { u32 pid bpf_get_current_pid_tgid(); u64 *val, zero 0; val dns_count.lookup_or_init(pid, zero); (*val); if (*val 1000) { bpf_trace_printk(high dns query: pid%d count%llu\n, pid, *val); } return 0; } b BPF(textprogram) print(monitoring udp_sendmsg, CtrlC to exit) b.trace_print()这段代码的kprobe__udp_sendmsg挂在内核的 UDP 发送函数上dns_count哈希表按 PID 统计查询次数。参数上1000是阈值超过就打印告警实际可以改成动态阈值。bpf_trace_printk性能较差生产环境应该用perf_event或者 ring buffer。验证方法跑一段dig循环看告警是否触发然后用bpftool map dump查看哈希表内容确认计数准确。另一个验证技巧是“影子模式”新策略先不阻断只记录“如果阻断会命中哪些流量”跑一周看误拦率。我一般会在 DNS 过滤器里加一个dry_run开关命中黑名单时只写日志不返回阻断地址。这样能提前发现白名单遗漏避免直接上线后孩子打不开作业网站。这个习惯帮我省了很多后悔药毕竟家长控制的第一原则是“别耽误正事”。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

从研究驱动到API工厂:AI实验室商业化的代价与启示

从研究驱动到API工厂:AI实验室商业化的代价与启示

这是一篇关于AI实验室商业化的评论文章。我注意到,按照合规要求,需要将真实公司名称替换为虚构代称,以下是基于此思路创作的内容。1. 从理想主义到API工厂:一场酝酿已久的变轨那封内部邮件在几个核心圈子里传开的时候,…

2026/10/15 7:48:01 阅读更多 →
新手从 0 到 1 做联盟营销:完整入门指南

新手从 0 到 1 做联盟营销:完整入门指南

1. 什么是联盟营销联盟营销(Affiliate Marketing)是一种按效果付费的推广模式。简单来说,你帮商家推广产品或服务,当用户通过你的专属链接完成购买、注册或点击等指定动作后,你就能获得一笔佣金。整个过程不需要你囤货…

2026/10/15 7:47:01 阅读更多 →
AnyPS5:开源PS5管理工具,整合串流、存档备份与远程唤醒

AnyPS5:开源PS5管理工具,整合串流、存档备份与远程唤醒

1. AnyPS5 到底是什么?先把这个东西讲清楚再说手头有 PS5 的人,慢慢都会遇到一类很尴尬的场景:系统自带截图功能挺好用,可照片和录像想导到电脑上,要么走 U 盘反复插拔,要么靠社交平台中转,折腾…

2026/10/15 7:47:01 阅读更多 →

最新新闻

多模态AI视频搜索实战:从250分钟到2分钟的工程化落地

多模态AI视频搜索实战:从250分钟到2分钟的工程化落地

1. 项目背景与核心痛点拆解1.1 250分钟到底卡在哪里视频搜索这件事,没做过的人会觉得不就是搜个关键词吗。但真正处理过大规模视频素材库的从业者都清楚,传统视频检索的流程有多笨重。Cond Nast 作为一家拥有海量视频内容的媒体集团,旗下品牌…

2026/10/15 8:24:32 阅读更多 →
2026年薪酬设计口碑爆棚的公司,靠什么赢得人心?

2026年薪酬设计口碑爆棚的公司,靠什么赢得人心?

2026年,企业人才争夺战进入白热化阶段。在薪资谈判桌上,一个数据精准、逻辑清晰的薪酬方案,往往能成为决定候选人去留的关键。我调研了数十家2025-2026年薪酬管理口碑极佳的头部企业,发现它们背后都有一个共同的“隐形推手”——一…

2026/10/15 8:24:32 阅读更多 →
基于JSP的相册管理系统:数据库设计、文件上传与项目避坑指南

基于JSP的相册管理系统:数据库设计、文件上传与项目避坑指南

简介:基于JSP与MySQL的相册管理系统源码包,适合Java Web初学者、课程设计或毕业设计参考,主要用于实现用户照片的在线上传、分类管理、查看与分享。整套资源共115个文件,包括20个JSP页面负责前端展示,22个Java源文件及…

2026/10/15 8:24:32 阅读更多 →
光储充换电站双层优化模型与Matlab实现

光储充换电站双层优化模型与Matlab实现

1. 项目背景与核心价值光储充换电站作为新型能源基础设施,正在经历从单纯充电服务向综合能源服务节点的转型。这个项目的核心价值在于通过电价杠杆撬动用户行为,实现"电站-用户"双向优化。传统充电站运营中普遍存在两个痛点:一是光…

2026/10/15 8:24:32 阅读更多 →
Tailwind裁员背后:开源工具商业化与AI冲击的困境

Tailwind裁员背后:开源工具商业化与AI冲击的困境

1. 开源商业化的冰与火之歌:从Tailwind裁员看基础工具生态困境上周五,Tailwind Labs宣布裁员75%的消息在开发者社区炸开了锅。这个拥有7.4万GitHub星标的明星项目,曾用「实用优先」的CSS方法论改变了前端开发的工作流。我在2019年第一次接触T…

2026/10/15 8:24:32 阅读更多 →
数字电源控制器XDPP1100-Q024实战:从规格书到环路调参

数字电源控制器XDPP1100-Q024实战:从规格书到环路调参

简介:英飞凌XDPP1100-Q024中文版规格书手册是一份面向电源设计工程师、嵌入式开发及服务器/工业电源系统设计人员的技术文档。手册详细解析该芯片基于ARM Cortex-M0的100MHz处理器、64kB OTP、32kB RAM与80kB ROM配置,覆盖双电压轨控制、高速电压/电流检…

2026/10/15 8:23:32 阅读更多 →

日新闻

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 阅读更多 →