sk_filter读取IP地址崩溃复盘:BPF偏移与VLAN陷阱
那天下午内部群里突然甩进来一条消息“sk_filter 读 IP 的 BPF 上线之后采集服务崩了连接也断了一批谁看下”我第一反应是“这又是哪个程序没校验 helper 返回值”结果拉上内核日志和用户态 core 一看问题比想象中深一点一个看起来人畜无害的 socket filter在特定报文下读出来的“IP 地址”根本不是 IP 地址而是被错位解析后的垃圾数据一路传到了用户态直接把哈希表相关逻辑打崩了。这篇文章就把整个事故从现象到根因、再到修复和回归的链路完整复盘一遍。当时我们把这类 BPF 程序叫“sk_filter 读取 IP 地址崩溃”排查完才发现根子不在于 eBPF 本身有多危险而在于我们对 socket filter 的执行上下文和报文锚点理解不够。适合刚开始写BPF_PROG_TYPE_SOCKET_FILTER的开发者以及被“BPF 程序导致线上故障”这类问题折磨过的排查人员。文章里我会把正确的偏移算法、可复现的测试矩阵和几条保命经验都写出来尽量让你少走一圈弯路。1. sk_filter 不是你想的“一个过滤器”那么简单先回到基础sk_filter在 Linux 网络栈里的真实身份是挂在 socket 上的 eBPF 程序类型是BPF_PROG_TYPE_SOCKET_FILTER用户态通过setsockopt(fd, SOL_SOCKET, SO_ATTACH_BPF, prog_fd, sizeof(prog_fd))挂上去。挂上之后这个 socket 收到的每一个报文都会在协议栈内部经过这段 BPF 逻辑返回值决定了报文是被放行还是被丢弃。这里有一个九十年代就存在的经典用法tcpdump 的经典 BPF 过滤表达式底层就是这类 socket filter 的 cBPF 形态。现在换成 eBPF 写能做的事更多了比如按 IP 黑白名单过滤、按四元组做流量统计、在 socket 层做轻量观测。听起来很简单但问题恰恰出在“轻量”两个字上——它运行在软中断上下文里不能睡眠不能调用大部分内核函数你能碰的只有 helper 函数和一块 512 字节的栈空间。1.1__sk_buff和struct sk_buff不是同一个东西新手最容易踩的坑就是把 eBPF 程序入口参数里的struct __sk_buff *skb当成内核里那个完整的struct sk_buff。这是两个完全不同的结构体。__sk_buff是一个面向 BPF 的字段投影只暴露len、data、data_end、mark、protocol、cb等少量字段。你在程序里写skb-data得到的其实是一个偏移量/地址数值不是可以直接解引用的真实指针。很多线上“崩溃”案例的起点就在这里有人写了类似char *data (char *)skb-data; struct iphdr *ip (struct iphdr *)(data 14);的代码。在部分程序类型下 verifier 会直接拒绝这种直接解引用但在某些上下文或者某些内核版本里你侥幸通过了加载运行时的行为却和“解引用一个不可控地址”没有本质区别。真正的稳定写法是调用bpf_skb_load_bytes这类 helper 把报文内容拷贝到栈上而不是拿data去做指针运算。1.2 “data 指向哪”直接决定你的 IP 偏移从几开始这次事故里最隐蔽的问题是大家都默认“offset 0 就是以太网头”。但 socket filter 是挂在 socket 层面的报文的skb-data到底指向哪一层取决于你挂的是哪种 socket以及在协议栈哪个处理阶段被调用。我整理了一张简化对照表这也是排查时的第一张地图挂载场景skb-data 锚点读 IPv4 源地址的偏移AF_PACKET / SOCK_RAW socketL2 以太网头14以太网头 12IP 头内 saddr 偏移AF_INET / SOCK_STREAMTCP socket多数情况已到 L3/L4 交界锚点不稳定需要以实际抓包为准不能写死XDP 程序旁路参考L2 以太网头14 12tc 程序旁路参考L2 以太网头视bpf_skb_load_bytes的 offset 语义而定注意 AF_INET 那行别以为“AF_INET 下 offset 0 就是 IP 头”。在 TCP 收包路径上调用 socket filter 时 skb 可能已经被 IP 层剥掉了部分头部skb-data不一定指着 IP 头起点。这也就是为什么同一个“读 IP 地址”的 BPF 程序在 A 环境正常、在 B 环境读出来的是一堆错位字节。1.3 协议栈对 VLAN 的处理让“固定 14 字节”彻底失效另一个隐患是 VLAN。很多人代码里写死ETH_HLEN 14觉得以太网头永远是 14 字节。实际上带 802.1Q 标签的帧L2 头是 18 字节。但更坑的是协议栈在收包时经常已经把 VLAN tag 剥离出来放进了skb-vlan_tci字段此时skb-data里并没有 VLAN 头而在某些 offload 未开启或驱动路径特殊的情况下VLAN 头又真实存在。于是同一个过滤器在这个网卡上偏移 14 能读到 IP换个网卡偏移 14 就读到了 VLAN tag 后的错误字节。业务代码不能只写ETH_HLEN至少得判断skb-protocol ETH_P_8021Q或者用bpf_skb_load_bytes先读前两个字节看是不是 VLAN 协议号。当时事故现场的过滤器就是这里漏了后面会展开。2. 那起“读取 IP 地址导致崩溃”的事故复盘2.1 现象不是必现是特定报文触发事故的直接影响是采集服务崩溃同时一堆业务连接异常。第一轮排查时所有人都盯着 dmesg 看有没有内核 Oops结果内核日志里干干净净没有 panic也没有 memory fault。这就排除了“BPF 程序直接把内核搞崩”的剧本。随后用户态 core 文件的栈回溯显示崩溃点在哈希表查找函数里传入的 key 明显不是一个正常四元组端口号大得离谱IP 地址也有 0xffffffff 这种值。再往上游看这个 key 来自 BPF 程序通过 ring buffer 上报的报文摘要。也就是说BPF 程序把自己解析出来的“源 IP、源端口、目的 IP、目的端口”打包发给用户态用户态拿这个摘要做哈希统计哈希表实现在异常 key 下触发了段错误。提示BPF 程序里“读出来一个数”和“读出来一个正确的数”之间隔着一整套协议偏移规则。这一层错了崩溃往往发生在下游消费者身上。2.2 用 bpftool 反向定位到具体 BPF 指令因为崩溃点不在内核先看 BPF 程序本身。确认加载状态bpftool prog list | grep socket找到对应程序 ID 后导出它的指令级代码和 JIT 后的汇编bpftool prog dump xlated id id bpftool prog dump jited id idxlated 输出的是 eBPF 字节码翻译后的指令能看到每条指令对应的 C 代码行号前提是编译时保留了 BTF 和调试信息。我们很快发现一个可疑分支程序在读 IP 头之前只判断了“偏移 14 处是不是 0x0800IPv4”如果读到的前两字节不是 IPv4就直接返回 0 放行。看起来没问题但问题在于“偏移 14”在带 VLAN 的帧上读到的根本不是协议号而是 VLAN 头里的一部分。把现场报文的协议号打印出来之后确认了触发条件流量里混入了一批带 802.1Q 标签的报文程序按 14 字节偏移去读“以太网类型”读到的值落在了 VLAN 头内部于是走了错误的分支。坏地址、坏端口全部由此产生。2.3 三层错误叠加才最终酿成“崩溃”复盘下来这是一个三层错误叠加的典型事故第一层锚点判断错误。程序挂在 AF_PACKET 的 raw socket 上skb-data指向 L2 头代码却用了一个从 AF_INET socket 场景抄来的偏移逻辑。第二层VLAN 处理缺失。即使锚点没错写死 14 字节也无法应对 802.1Q 标签帧协议号读取直接错位。第三层helper 返回值被忽略。bpf_skb_load_bytes读取失败时返回负数代码没检查继续使用栈上的旧值或未初始化区域最终把垃圾数据当成 IP 地址传了出去。这三个问题单独拎出来每一个都不至于让进程崩溃。但叠加在一起就变成了“BPF 给用户态喂毒用户态无力反抗”。这也是我后来在团队里反复强调的一句话eBPF 程序里的每一次读取失败都是给下游消费者埋雷。2.4 错误代码长什么样给出一段高度还原事故现场的简化代码SEC(socket) int filter_wrong(struct __sk_buff *skb) { __u16 proto; __u32 saddr; __u32 sport; long ret; // 错误一假定 skb-data 一定指向 L2 头且以太网类型固定偏移 14 ret bpf_skb_load_bytes(skb, 14, proto, 2); if (ret 0) return 0; // 这里没有处理 VLAN也没有处理字节序 if (proto ! 0x0008) // 本意是 ETH_P_IP但字节序和偏移都错了 return 0; // 错误二忽略 14 字节 L2 头只对纯 IPv4 成立 ret bpf_skb_load_bytes(skb, 14 12, saddr, 4); ret bpf_skb_load_bytes(skb, 14 20, sport, 2); // 错误三没有检查 retsaddr/sport 可能完全没被更新 // 直接把 saddr/sport 拼进 ringbuf 事件 struct event e {}; e.saddr saddr; e.sport sport; bpf_ringbuf_output(events, e, sizeof(e), 0); return 0; }这段代码里有三个典型气味固定偏移、忽略返回值、没处理协议版本。后面我们逐一拆掉。3. 从崩溃现场反推IP 头偏移到底该怎么算3.1 第一步确定你的锚点不要猜不要抄。在 BPF 程序里用bpf_skb_load_bytes读第一个字节直接看内容推断当前锚点是最稳的如果第一字节高四位是0x4说明skb-data已经指向 IPv4 头。如果第一字节高四位是0x6说明已经指向 IPv6 头。如果前 6 字节看起来像 MAC 地址例如0x开头但高四位是0x3、0x0等混合值说明还停在 L2。更可靠的做法是在加载前就把挂载场景定死并在代码注释里写明。比如我们这次最终决定统一挂在 AF_PACKET raw socket那么锚点固定为 L2所有偏移都从以太网头开始算。3.2 第二步兼容 IPv4 / IPv6 / VLAN 的动态偏移一份能过 verifier 并且能扛住边界报文的解析逻辑大致长这样。注释里标注了每一步“为什么这么写”。#include linux/bpf.h #include linux/if_ether.h #include linux/ip.h #include linux/ipv6.h #include bpf/bpf_helpers.h #define ETH_P_8021Q 0x8100 SEC(socket) int filter_ip(struct __sk_buff *skb) { __u8 buf[sizeof(struct ipv6hdr)]; __u16 proto; __u64 offset 0; long ret; // 锚点固定挂 AF_PACKETskb-data 指向 L2 头 // 先读以太网头里的协议类型字段 ret bpf_skb_load_bytes(skb, 12, proto, 2); if (ret 0) return 0; // 字节序统一转为主机序再比较 proto bpf_ntohs(proto); // 处理 VLAN 标签如果是 802.1Q以太网类型字段往后挪 4 字节 if (proto ETH_P_8021Q) { ret bpf_skb_load_bytes(skb, 12 4, proto, 2); if (ret 0) return 0; proto bpf_ntohs(proto); offset 4; // 后续 L3 头起点多了 4 字节 } if (proto ETH_P_IP) { // IPv4: L3 头从 L2 14 offset 开始 // 读第一个字节高 4 位版本号低 4 位 IHL __u8 vihl; ret bpf_skb_load_bytes(skb, 14 offset 0, vihl, 1); if (ret 0) return 0; // IHL 单位是 4 字节至少是 5最大 15 __u8 ihl vihl 0x0f; if (ihl 5 || ihl 15) return 0; __u32 saddr, daddr; // saddr 在 IPv4 头内偏移 12daddr 偏移 16 ret bpf_skb_load_bytes(skb, 14 offset 12, saddr, 4); if (ret 0) return 0; ret bpf_skb_load_bytes(skb, 14 offset 16, daddr, 4); if (ret 0) return 0; // 这里 saddr/daddr 已经是网络字节序按需 bpf_ntohl // 做你的事黑白名单 / 统计 / 上报 return 1; } if (proto ETH_P_IPV6) { // IPv6 头固定 40 字节 ret bpf_skb_load_bytes(skb, 14 offset 8, buf, 16); if (ret 0) return 0; // buf 里是源地址 128 bit按需处理 return 1; } return 1; // 其他协议放行 }这段代码解决了两件事一是 VLAN 标签导致偏移变化二是 IPv4 头长度可变IHL 字段没有再用“固定 20 字节”的假设去读地址。单纯读 saddr/daddr 其实不受 IHL 影响因为它们在 IPv4 头的前 20 字节内固定位置但如果你后续要读 TCP/UDP 端口就必须先算ip_header_len ihl * 4再做14 offset ip_header_len 端口偏移不然带 IP options 的报文会直接读错。3.3 用bpf_skb_load_bytes而不是裸解引用ctx-data你可能想问既然ctx-data可以直接拿到报文地址为什么非要用 helper 拷到栈上原因有三层verifier 对 socket filter 的直接数据访问控制很严格。直接data offset解引用很容易触发invalid mem access拒绝加载或者需要在代码里维护复杂的data_end边界判断。报文可能不是线性存储的。内核 skb 的数据可能分片在多个 page 里ctx-data只覆盖线性数据区。bpf_skb_load_bytes内部会调用skb_copy_bits这样的函数把数据完整拷贝出来帮你处理非线性区。栈拷贝的开销在 socket filter 场景完全可接受。读取 IP 头最多 40 字节一次 helper 调用纳秒级远不至于成为瓶颈。一句话helper 是经过验证的安全路径裸解引用是自己给自己挖坑。能不用就不用。3.4 别忘了签名和字节序这次事故还有一个小插曲代码里if (proto ! 0x0008)就是一个典型的字节序错误。以太网类型字段在网络字节序下 IPv4 是0x0800在小端主机上按__u16直接读出来是0x0008。正确写法是先用bpf_ntohs转成主机序再和ETH_P_IP比较。同理IPv4 地址在网络字节序里是“大端”在 x86 上要用bpf_ntohl才能得到直觉上“1.2.3.4 对应 0x01020304”的值。不要为了省一次 helper 调用而把字节序搞混否则统计出来全是反的。4. 边界报文测试矩阵把“不崩”变成可验证的修复完代码上线前必须做回归。我们的做法是构造一批边界报文逐一验证 BPF 程序解析结果是否和预期一致。这里的“预期”不只是“不崩”还包括读出来的 IP、端口、协议必须和真实报文一致。4.1 测试用例设计用例编号报文特征期望行为实际行为修复后T01普通 IPv4 UDP 报文正确读到 saddr/daddr通过T02带 802.1Q VLAN 标签的 IPv4 报文正确跳过 VLAN 额外 4 字节通过T03IPv4 带 8 字节 IP optionssaddr/daddr 仍正确读端口用动态 IHL通过T04IPv6 普通报文正确读到 128 位源地址通过T05ARP 报文走“其他协议放行”分支不读 IP通过T06超短畸形报文长度 以太网头 IP 头helper 返回负值程序安全返回通过T07802.1Q IPv6 组合正确识别 VLAN 后再识别 IPv6通过构造这些报文我一般用 Python 的 scapy 直接发到测试 socket 上同时用 tcpdump 抓包确认发出去的内容。不需要搞复杂的流量发生器重点是构造准确。from scapy.all import Ether, IP, UDP, Dot1Q, IPv6, Raw, sendp # T01 普通 IPv4 UDP pkt Ether(dst00:11:22:33:44:55, srcaa:bb:cc:dd:ee:ff) / \ IP(src1.2.3.4, dst5.6.7.8) / \ UDP(sport12345, dport54321) / Raw(btest) sendp(pkt, ifaceeth0) # T02 带 VLAN 标签的 IPv4 pkt_vlan Ether(dst00:11:22:33:44:55, srcaa:bb:cc:dd:ee:ff) / \ Dot1Q(vlan100) / \ IP(src1.2.3.4, dst5.6.7.8) / \ UDP(sport12345, dport54321) / Raw(bvlan-test) sendp(pkt_vlan, ifaceeth0)4.2 用BPF_PROG_TEST_RUN做离线注入如果不想在真实网卡上发包eBPF 还提供了离线测试通道bpftool prog run。它能把一个构造好的 skb 直接喂给某个 BPF 程序执行适合验证“解析逻辑是否正确”不需要真实协议栈参与。bpftool prog run pinned /sys/fs/bpf/filter_ip \ data_in sample_pkt.bin \ data_out out.bin \ repeat 100data_in是原始报文二进制文件repeat是重复次数。跑完看返回值和data_out。这个方式特别适合自动化和 CI 集成把用例矩阵变成脚本的一部分。4.3 实测中的意外用户态解析结构体没同步还有一次让我们“崩”得莫名其妙的问题和 BPF 本身无关BPF 程序里struct event新增了一个字段ringbuf 上报的数据变长了但用户态程序还在用旧的sizeof(struct event)解析直接把后续内存越界读爆了。这个属于版本同步问题但和 BPF 事故混在一起很容易被误判成“BPF 程序写崩了”。建议BPF 程序和用户态共享的结构体严格定义在一个头文件里编译时用同一个版本。结构体变更必须编译检查用户态代码不能只改内核侧。5. 写 socket filter 的几条工程化建议事故修完我把自己踩过的、团队踩过的坑整理成了一张内部检查清单。写得比较直白每条都是真实教训。5.1 每个 helper 返回值都必须检查bpf_skb_load_bytes失败返回负值此时目标栈内存不会被更新。如果你不检查就会沿用栈上的旧值——在 BPF 里可能表现为 verifier 允许但你拿到的内容完全随机。轻则漏报误报重则把坏数据喂给下游。不要觉得“多一个分支影响性能”性能瓶颈从来不在这一条判断上。正确姿势是“先判断再使用”ret bpf_skb_load_bytes(skb, offset, val, sizeof(val)); if (ret 0) return 0; // 或者走错误统计分支5.2 不要用ctx-data做指针算术总有人觉得ctx-data就是报文起点直接data ETH_HLEN访问 IPv4 头最简单。但 socket filter 的 verifier 限制、非线性 skb、VLAN 偏移每一个都是坑。老老实实用bpf_skb_load_bytes把需要的字节拷到栈上。如果追求极致性能考虑用BPF_LD_ABS这类指令但前提是你真的清楚边界语义而且有测试覆盖。5.3 字节序统一用 helper 转bpf_ntohs、bpf_ntohl或__builtin_bswap16/32取决于内核版本都用起来。不要在代码里和“0x0008”裸比较。字节序问题不会导致崩溃但会让你的过滤器在大小端不同的机器上行为完全不同这是一个典型的“换台机器就出事”的隐患。5.4 协议解析只取必要字节IP 头加 TCP/UDP 头最多几十字节单次 helper 调用就能读完。不要写循环逐字段读也不要一次读取超大块比如把整个 payload 拷到栈上。栈总共 512 字节报文可能远大于这个数。准确、克制的读取才是稳定的。5.5 上线前跑一遍边界报文矩阵开发环境跑通“普通 IPv4”不算完成。把 VLAN、IPv6、带 options、短包、ARP 至少都跑一遍。用bpftool prog run把离线用例写进 CI每次改完 BPF 程序自动回归。这次事故如果当时有这套用例根本不会流到线上。5.6 观测手段首选 ringbuf别用 bpf_trace_printk排查现场临时用bpf_trace_printk没问题但生产环境长期开着会拖慢收包路径。更好的方式是定义好struct event通过bpf_ringbuf_output把关键字段解析出的协议、偏移、源目地址、helper 返回值打给用户态用户态负责聚合和日志。这样 BPF 侧保持最小开销排查时也有据可查。另外老内核上 helper 集可能不全加载前用bpftool feature probe检查一下当前环境的 helper 可用性别等上线了才发现bpf_ringbuf_output不存在。回过头看这次事故没有特别高深的技术门槛所有问题都出在“对 sk_filter 执行上下文理解不精确”上。我后来把这套排查链路和测试矩阵做成了团队内部的 BPF 程序上线检查表从那以后同类问题基本绝迹。如果你正在写 socket filter或者准备在上线前给 BPF 程序做一次体检希望这篇文章能帮你省掉一次线上“崩溃”的代价。

相关新闻

运维安全新思路:用联盟链实现不可篡改的审计与权限治理

运维安全新思路:用联盟链实现不可篡改的审计与权限治理

运维这活,干久了谁心里都憋着一肚子火。系统出故障,明明是需求方临时改配置,验收时指标不达标,最后复盘全变成“运维操作不规范”;数据库被误删,搞了半天发现是某位同事拿管理员账号练手,但翻遍…

2026/10/11 18:41:00 阅读更多 →
汇编语言实战案例精讲:从指令到数据流的心智构建

汇编语言实战案例精讲:从指令到数据流的心智构建

简介:这份汇编语言实战教程以100个案例贯穿x86-64汇编核心知识,从最小的退出程序、经典的Hello World到寄存器数据移动,逐步深入到流程控制、函数与栈帧、内存与数据结构、字符串操作、系统调用、浮点与SIMD、与C交互及性能优化、加密算法实现…

2026/10/11 18:41:00 阅读更多 →
Android医疗系统源码解析:从环境搭建到挂号接口联调实战

Android医疗系统源码解析:从环境搭建到挂号接口联调实战

简介:这是一套面向高校安卓课程设计与移动应用开发学习者的完整项目资料,源自大三学期课程作业,由两人协作约两个月完成,涵盖Android客户端、后端数据接口与简易Web管理后台三部分,适合作为课程设计参考、毕业设计雏形…

2026/10/11 18:41:00 阅读更多 →

最新新闻

地下2米土壤墒情监测:管式监测仪如何改变灌溉决策

地下2米土壤墒情监测:管式监测仪如何改变灌溉决策

这大概是不少果园主、农场主都遇到过的怪事:叶片中午蔫下去,你赶紧浇水,浇了一小时,第二天反而更蔫。挖开土一看,表层10厘米明明是湿的,可往下翻到30厘米,手指甲都掐不进去的干土块,…

2026/10/11 20:13:02 阅读更多 →
ONNXRuntime 部署 PP-MattingV2 实时人像抠图:Python 与 C++ 推理实战

ONNXRuntime 部署 PP-MattingV2 实时人像抠图:Python 与 C++ 推理实战

简介:这份资源面向深度学习部署与计算机视觉方向的开发者,提供在ONNXRuntime上运行PaddleSeg实时人像抠图模型PP-MattingV2的完整实践材料,可用于社交媒体、视频编辑、虚拟现实等场景中发丝级人像分离的落地验证。压缩包共7个文件&#xff0c…

2026/10/11 20:13:02 阅读更多 →
AI File Sorter 文档分析指南:5 个步骤让 PDF/Office 文件自动获得清晰文件名

AI File Sorter 文档分析指南:5 个步骤让 PDF/Office 文件自动获得清晰文件名

AI 应用大模型本地部署桌面应用 【免费下载链接】ai-file-sorter Cross-platform desktop application for content-aware file organization and renaming. Supports local and remote LLMs, preview-based workflows, and fully user-controlled changes. 项目地址&#xff1…

2026/10/11 20:13:01 阅读更多 →
5分钟上手Minari:离线RL数据集安装、下载与加载快速入门

5分钟上手Minari:离线RL数据集安装、下载与加载快速入门

【免费下载链接】Minari A standard format for offline reinforcement learning datasets, with popular reference datasets and related utilities 项目地址: https://gitcode.com/gh_mirrors/mi/Minari 点击查看 免费下载 Minari 是一个专为**离线强化学习&…

2026/10/11 20:13:01 阅读更多 →
openJiuwen agent-core 文档解析器基类 Parser 深度解析:从抽象接口到多格式自动路由的完整实现

openJiuwen agent-core 文档解析器基类 Parser 深度解析:从抽象接口到多格式自动路由的完整实现

人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习 【免费下载链接】agent-core openJiuwen agent-core可提供AI Agent开发、运行、调优与演进相关的全套SDK能力 项目地址: https://gitcode.com/openJiuwen/agent-core 点击查看 免费下载 导读 Parser…

2026/10/11 20:13:01 阅读更多 →
Flink/PyFlink CSV读写实战:Schema声明与参数配置避坑

Flink/PyFlink CSV读写实战:Schema声明与参数配置避坑

先说个我上个月接手的真实任务:一批传感器历史数据以 CSV 文件存在对象存储里,需要灌进 Flink 流作业做实时指标计算。文件不大,三十来个分区,每分区几万行,字段也就四五个。我当时觉得这是最没技术含量的一步&#xf…

2026/10/11 20:12:01 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

2026/10/11 0:00:27 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/11 0:00:27 阅读更多 →

月新闻

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