基于npcap与Qt的抓包工具开发:从环境搭建到协议解析实战
简介这是一份基于npcap与Qt开发的网络抓包工具源码面向具备一定网络编程与C基础、希望深入理解数据包捕获原理或需要将抓包能力集成到自有系统中的开发者。它模仿Wireshark的界面与操作方式借助npcap访问底层网络流量实现数据包捕获、过滤与解码并利用Qt的信号槽机制与丰富控件构建图形界面相比现成工具具备更高的定制性与可扩展性。压缩包共86个文件约2.48MB以cpp与h源码、obj与tlog等编译中间文件、vcxproj与sln工程配置、qrc与ui界面资源以及png图标为主另含少量日志与说明文本工程结构完整可直接用Visual Studio打开编译。目前已有378人学习下载。读者可从中掌握npcap接口调用、Qt界面搭建、数据包解析与过滤规则的实现思路并参考其工程组织方式为二次开发或集成到更大监控系统提供可复用的代码基础。1. 拿到 sniffer.zip 先别急着编译这套 npcapQt 抓包工具到底能干什么很多人第一次看到「模仿 Wireshark 的抓包工具」这几个字第一反应是「又一个套壳」。但如果你手上正好有个需求——要把抓包能力嵌进自己的 Qt 客户端、要按自己的协议格式实时解析、要在界面上只显示业务关心的那几个字段——你就会发现 Wireshark 反而不好用它太完整了完整到你没法轻易裁剪。sniffer.zip 这套源码的价值就在这里它用 npcap 做底层抓包、Qt 做界面把「抓包 → 过滤 → 解析 → 展示」这条链路完整地摊开给你看你可以直接在上面改解析逻辑、加自己的协议树、把结果对接进现有系统。它适合两类人一是想搞懂抓包工具内部怎么运转的 C/Qt 开发者二是需要快速搭一个定制化网络监控界面的工程师。解压后能看到 sniffer.sln 和 x64 目录说明是 Visual Studio 工程Windows 平台原生编译不绕弯子。2. 环境搭不起来后面全是白费npcap SDK、Qt 版本与 VS 工程的对接2.1 为什么底层选 npcap 而不是 WinPcap在 Windows 上做抓包绕不开驱动层。WinPcap 是上一代方案已经停止维护多年在 Win10/Win11 上安装经常遇到签名和兼容性问题。npcap 是它的继任者由 Nmap 团队维护支持 Windows 10/11 的 NDIS 6.x 驱动模型安装时可以选择「WinPcap API 兼容模式」这样老代码里的pcap_xxx调用基本不用改就能跑。sniffer 这套源码用的就是 npcap 提供的pcap.h接口核心调用链是pcap_findalldevs枚举网卡 →pcap_open_live打开设备 →pcap_next_ex循环取包 →pcap_compilepcap_setfilter做 BPF 过滤。选 npcap 的另一个实际理由是它自带 SDK 安装选项装完之后WpdPack风格的 Include 和 Lib 目录直接可用不用自己去编 libpcap。需要特别注意的是npcap 分「运行库」和「SDK」两部分。只装运行库你的程序能跑但编不了只装 SDK 不装驱动编出来运行时报「未找到适配器」。正确做法是安装时勾选「Install Npcap in WinPcap API-compatible Mode」并且把 SDK 目录记下来后面配工程要用。2.2 Qt 版本选择与工程配置的实操步骤这套工程是 VS 工程sniffer.sln不是 .pro 文件所以 Qt 的接入方式走的是 Qt VS Tools 插件那条路。我一般会这么配第一步装 Qt。建议用 Qt 5.14.2 或 Qt 5.15.x 的 MSVC 版本位数必须和你的 VS 工程一致工程里有 x64 目录说明是 64 位。Qt 6 也能用但 Qt 6 把QRegExp等一批类移到了兼容模块老工程直接迁会报一堆错新手别给自己找麻烦。第二步在 VS 里装 Qt VS Tools 扩展然后在Extensions → Qt VS Tools → Qt Versions里把 qmake.exe 的路径填进去。第三步配置 npcap 的头文件和库路径。右键工程 → 属性# 在「VC 目录 → 包含目录」加入 npcap SDK 的 Include C:\npcap-sdk\Include # 在「VC 目录 → 库目录」加入 npcap SDK 的 Lib\x64 C:\npcap-sdk\Lib\x64 # 在「链接器 → 输入 → 附加依赖项」加入 wpcap.lib Packet.lib ws2_32.libwpcap.lib是抓包 API 的导入库Packet.lib是 npcap 直接发送原始包用的如果你只抓不发可以先不加ws2_32.lib是 Winsock 库解析 IP 和端口时会用到。这三个缺一个都会在链接阶段报LNK2019 无法解析的外部符号。第四步确认运行时的 DLL。编译出来的 exe 依赖wpcap.dll和Packet.dll这两个在安装 npcap 时会放到C:\Windows\System32\Npcap一般不用手动拷。但如果你要把程序发给别人对方机器上必须先装 npcap 运行库否则一启动就提示找不到 DLL。提示装完 npcap 后如果pcap_findalldevs返回空列表八成是驱动没装好或者权限不够。用管理员身份跑一次程序试试还不行就重装 npcap 并确认勾了兼容模式。2.3 工程目录结构与关键文件定位解压 sniffer.zip 后目录大致是这样路径作用sniffer.slnVS 解决方案入口双击打开sniffer/主工程目录含 .cpp/.h 和 .ui 文件sniffer-main/可能是主逻辑或入口相关代码x64/编译输出目录Debug/Release 分开放打开 sln 后先别急着 F5先看「解决方案资源管理器」里有没有黄色感叹号的文件——那通常是 Qt 的 moc 文件没生成或者头文件路径没配对。把 Qt VS Tools 的版本选对之后重新生成一次moc 会自动补上。3. 从 pcap_next_ex 到 QTableView抓包线程与界面刷新的完整链路3.1 抓包为什么必须放独立线程pcap_next_ex是阻塞调用——没有包来的时候它就卡在那儿等。如果你把它放在 Qt 的主线程UI 线程里界面直接假死按钮点不动、窗口拖不动用户以为程序崩了。所以标准做法是开一个QThread或者用std::thread把抓包循环扔进去抓到包之后通过信号槽把数据传回主线程刷新界面。这里有个 Qt 的经典坑跨线程传数据时如果传的是自定义结构体必须用qRegisterMetaType注册否则信号槽连接会失败而且失败是静默的——不报错就是收不到。我一般会把包数据封装成一个结构体// packetdata.h struct PacketData { quint32 index; // 包序号 qint64 timestamp; // 时间戳微秒 QByteArray rawData; // 原始字节 QString srcIp; QString dstIp; quint16 srcPort; quint16 dstPort; QString protocol; // TCP/UDP/ICMP }; Q_DECLARE_METATYPE(PacketData)Q_DECLARE_METATYPE让这个类型能被 Qt 的元对象系统识别配合qRegisterMetaTypePacketData(PacketData)在 main 函数里注册一次跨线程信号槽才能正常传。3.2 抓包线程的核心循环与参数说明抓包线程的 run 函数大致长这样void CaptureThread::run() { char errbuf[PCAP_ERRBUF_SIZE]; // 打开设备snaplen 设 65535 保证不截断promisc 设 1 开混杂模式 pcap_t* handle pcap_open_live(devName.toLocal8Bit().data(), 65535, // snaplen每个包最多抓多少字节 1, // promisc1混杂模式抓所有经过网卡的包 1000, // read_timeout毫秒超时后返回继续检查停止标志 errbuf); if (!handle) { emit errorOccurred(QString(打开设备失败: %1).arg(errbuf)); return; } // 编译并设置 BPF 过滤规则 struct bpf_program fcode; if (pcap_compile(handle, fcode, filterStr.toLocal8Bit().data(), 1, PCAP_NETMASK_UNKNOWN) 0) { pcap_setfilter(handle, fcode); } struct pcap_pkthdr* header; const u_char* pktData; int res; quint32 idx 0; while (!m_stop) { res pcap_next_ex(handle, header, pktData); if (res 1) { PacketData pd; pd.index idx; pd.timestamp header-ts.tv_sec * 1000000LL header-ts.tv_usec; pd.rawData QByteArray((const char*)pktData, header-caplen); parsePacket(pd); // 解析 IP/端口/协议 emit packetCaptured(pd); // 信号发回主线程 } else if (res 0) { continue; // 超时正常 } else { break; // 出错或设备关闭 } } pcap_close(handle); }几个参数值得单独说。snaplen设 65535 是为了不截断大包如果你只关心包头可以设成 96 或 128 来省内存但那样 payload 就看不全了。promisc设 1 是混杂模式能抓到经过网卡但不是发给本机的包交换机环境下这个模式作用有限但在集线器或镜像口上很关键。read_timeout设 1000 毫秒是为了让循环有机会检查m_stop标志否则pcap_next_ex会一直阻塞你点「停止」按钮它不响应。3.3 界面刷新QTableView 自定义 Model 处理大数据量抓包工具最怕的就是包一多界面卡死。如果你用QTableWidget一行一行setItem几千个包之后就开始卡几万个包直接假死。热词里提到的「qt 表格大数据卡顿优化 tablewiget 到 qtableview 自定义 model」说的就是这个场景。正确做法是用QTableView配一个继承自QAbstractTableModel的自定义模型数据存在一个QVectorPacketData里data()函数按需返回界面只渲染可见的那几十行。class PacketTableModel : public QAbstractTableModel { Q_OBJECT public: int rowCount(const QModelIndex) const override { return m_packets.size(); } int columnCount(const QModelIndex) const override { return 6; } QVariant data(const QModelIndex idx, int role) const override { if (role ! Qt::DisplayRole) return {}; const PacketData p m_packets[idx.row()]; switch (idx.column()) { case 0: return p.index; case 1: return QDateTime::fromMSecsSinceEpoch(p.timestamp / 1000).toString(hh:mm:ss.zzz); case 2: return p.srcIp; case 3: return p.dstIp; case 4: return p.protocol; case 5: return p.rawData.size(); } return {}; } void appendPacket(const PacketData p) { beginInsertRows(QModelIndex(), m_packets.size(), m_packets.size()); m_packets.append(p); endInsertRows(); } private: QVectorPacketData m_packets; };beginInsertRows和endInsertRows必须成对出现它们告诉视图「我要插数据了你准备一下」少了这两个调用视图不会更新。另外如果包来得太快比如每秒几千个每个包都触发一次appendPacket会导致大量重绘常见做法是攒一批再插或者用QTimer每 100 毫秒批量刷新一次。注意QVectorPacketData里存了QByteArray rawData包多的时候内存涨得很快。一个 1500 字节的包加上结构体开销一万个包就是十几 MB。如果长时间抓包要么限制缓存条数比如只留最近 10 万条要么把 rawData 落盘、内存里只留解析后的字段。4. 协议解析这层最容易翻车以太网帧、IP 头、TCP/UDP 的偏移量计算4.1 从原始字节到协议字段的解析顺序抓到的rawData是一串裸字节解析就是按协议栈一层层剥。以太网帧头固定 14 字节6 目标 MAC 6 源 MAC 2 类型类型字段 0x0800 表示上层是 IPv40x0806 是 ARP0x86DD 是 IPv6。IPv4 头默认 20 字节但如果有选项字段会更长所以不能硬编码 20要读 IHL首部长度字段。TCP 头默认 20 字节同样要看 Data Offset 字段。UDP 头固定 8 字节。void parsePacket(PacketData pd) { const u_char* d (const u_char*)pd.rawData.constData(); int len pd.rawData.size(); if (len 14) return; quint16 ethType (d[12] 8) | d[13]; if (ethType ! 0x0800) { pd.protocol Non-IPv4; return; } int ipOff 14; if (len ipOff 20) return; int ihl (d[ipOff] 0x0F) * 4; // 首部长度单位是 4 字节 quint8 proto d[ipOff 9]; // 协议号6TCP, 17UDP, 1ICMP // 源 IP 和目标 IP 各 4 字节 pd.srcIp QString(%1.%2.%3.%4).arg(d[ipOff12]).arg(d[ipOff13]) .arg(d[ipOff14]).arg(d[ipOff15]); pd.dstIp QString(%1.%2.%3.%4).arg(d[ipOff16]).arg(d[ipOff17]) .arg(d[ipOff18]).arg(d[ipOff19]); int transOff ipOff ihl; if (proto 6 len transOff 20) { pd.protocol TCP; pd.srcPort (d[transOff] 8) | d[transOff1]; pd.dstPort (d[transOff2] 8) | d[transOff3]; } else if (proto 17 len transOff 8) { pd.protocol UDP; pd.srcPort (d[transOff] 8) | d[transOff1]; pd.dstPort (d[transOff2] 8) | d[transOff3]; } else if (proto 1) { pd.protocol ICMP; } else { pd.protocol QString(IP-%1).arg(proto); } }这段代码里最容易出错的是偏移量。ipOff 9是协议号因为 IP 头里版本和首部长度占第 0 字节服务类型第 1 字节总长度第 2-3 字节标识第 4-5 字节标志和片偏移第 6-7 字节TTL 第 8 字节协议第 9 字节。数错一个位置解析出来的就是垃圾。我建议对着 RFC 791 的头部图一个一个数别凭记忆。4.2 BPF 过滤规则怎么写才不误伤pcap_compile接受的过滤字符串就是 tcpdump 那套语法写对了能大幅减少无效包。常见写法# 只抓 80 端口的 TCP 包 tcp port 80 # 抓某个 IP 的所有流量 host 192.168.1.100 # 抓两个网段之间的流量 net 192.168.1.0/24 and net 10.0.0.0/8 # 排除 ARP 和 ICMP not arp and not icmp # 抓 TCP 且带 SYN 标志的包只看连接建立 tcp[tcpflags] tcp-syn ! 0tcp[tcpflags]这种写法是 BPF 的偏移量语法tcpflags是 TCP 头里标志位那个字节的别名。写过滤规则时注意port 80会同时匹配源端口和目标端口如果你只想看发往 80 的得写dst port 80。另外过滤规则是在内核层生效的写得好能显著降低用户态的处理压力别等抓到之后再在代码里if过滤那样浪费性能。提示过滤字符串如果编译失败pcap_compile返回 -1但很多人不检查返回值结果过滤器没生效抓了一堆无关包还以为是代码问题。养成检查返回值的习惯。4.3 时间戳与包序号的显示处理pcap_pkthdr里的时间戳是struct timeval秒和微秒分开存。显示的时候要转成人类可读的格式同时保留毫秒精度因为分析时序问题时毫秒很关键。Wireshark 默认显示的是相对时间相对于第一个包这个体验比绝对时间好因为你看的是包之间的间隔。实现上就是在抓到第一个包时记下基准时间后面每个包显示(current - base)。包序号从 1 开始递增别从 0 开始因为用户习惯说「第 1 个包」。序号在过滤前后要区分清楚如果你先抓再过滤序号是连续的如果过滤规则在内核层生效序号只对通过过滤的包递增。这两种行为没有对错但要在界面上说清楚否则用户对不上号。5. 编译运行与抓包异常的排查清单5.1 编译期报错LNK2019 与 Qt moc 问题现象链接时报LNK2019 无法解析的外部符号 pcap_open_live。原因wpcap.lib没加到附加依赖项或者库目录指向了 32 位版本而工程是 64 位。解决检查「链接器 → 输入 → 附加依赖项」里有没有wpcap.lib再确认「库目录」指向的是Lib\x64而不是Lib。现象报无法打开源文件 QApplication。原因Qt 的包含目录没配或者 Qt VS Tools 没正确关联版本。解决在 Qt VS Tools 里重新选一次 Qt 版本确认 qmake 路径指向的是 MSVC 版本而不是 MinGW 版本。现象编译通过但运行时报moc_xxx.cpp 找不到。原因头文件里用了Q_OBJECT宏但没被 moc 处理。解决在 VS 里对含Q_OBJECT的头文件右键 → 属性 → 项类型设为「Qt Meta-Object Compiler」然后重新生成。5.2 运行期异常抓不到包、界面卡死、内存暴涨现象程序启动后设备列表为空。原因npcap 驱动没装好或者程序没有管理员权限。解决以管理员身份运行重装 npcap 并勾选 WinPcap 兼容模式用pcap_findalldevs的返回值判断如果返回 0 个设备就弹提示引导用户装驱动。现象点「开始抓包」后界面无响应。原因抓包循环跑在主线程里。解决确认抓包逻辑在QThread::run或独立线程里信号槽连接用Qt::QueuedConnection跨线程默认就是队列连接但手动指定更保险。现象抓了几万个包之后程序越来越卡最后崩溃。原因QVectorPacketData无限增长内存耗尽。解决设一个上限比如 10 万条超过就删最旧的或者把 rawData 存到磁盘内存里只留解析字段。另外QByteArray的隐式共享在这种情况下帮不上忙因为每个包的数据都是独立的。现象过滤规则写了但没效果还是抓到一堆无关包。原因pcap_compile失败但没检查返回值或者过滤规则语法写错。解决检查pcap_compile返回值失败时用pcap_geterr拿到具体错误信息弹出来。过滤字符串先在命令行用 tcpdump 验证一遍再填进去。现象解析出来的 IP 和端口是乱码。原因偏移量算错或者忘了网络字节序转主机字节序。解决IP 和端口在协议里都是大端网络字节序x86 是小端读多字节字段时要用ntohs/ntohl转换。上面代码里手动移位拼接其实已经隐含了字节序处理但如果你用memcpy直接拷quint16就必须转。6. 二次开发进阶把解析层抽出来做成可插拔的协议插件这套源码最值得动手改的地方是把协议解析从parsePacket那个大函数里抽出来做成一个解析器接口。因为实际项目里你往往不只解析 TCP/UDP还要解析自定义的应用层协议——比如你公司内部的二进制协议、MQTT、Modbus 之类。如果全堆在一个函数里每加一个协议就要改一次主逻辑迟早变成一坨。我的做法是定义一个抽象基类class ProtocolParser { public: virtual ~ProtocolParser() default; // 返回 true 表示这个解析器认领了这个包 virtual bool canParse(const u_char* data, int len, quint16 dstPort) 0; virtual void parse(PacketData pd, const u_char* data, int len) 0; virtual QString name() const 0; };然后搞一个注册表启动时把所有解析器注册进去抓到一个包就遍历一遍谁认领谁处理。这样加新协议只需要写一个新类、注册一下不用动抓包线程和界面代码。解析结果可以往PacketData里加一个QMapQString, QString fields界面上的详情面板直接遍历这个 map 显示连界面都不用改。验证解析对不对最直接的办法是拿 Wireshark 抓同一个网卡的同一时段流量对比两边的字段。重点对三个东西包总数、每个包的源/目的 IP 和端口、payload 的十六进制内容。如果包总数对不上多半是过滤规则不一致如果 IP 端口对不上是偏移量问题如果 payload 对不上检查caplen和len的区别——caplen是实际抓到的长度len是包在链路上的原始长度snaplen设小了的时候两者会不一样。还有一个实用技巧在详情面板里加一个「复制为十六进制」的按钮把选中包的 rawData 以 hex dump 格式复制到剪贴板。调试协议的时候直接把这段 hex 贴到 Wireshark 的「导入十六进制转储」里就能用 Wireshark 的解析能力交叉验证你的解析结果。这个习惯帮我省了大量对偏移量的时间。从那以后我每次改解析代码都强制自己先用 Wireshark 抓一组对照数据跑一遍确认字段完全一致再提交。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

微信小程序会议室管理系统:基于Java与MySQL的完整设计与实现

微信小程序会议室管理系统:基于Java与MySQL的完整设计与实现

简介:这套毕业设计资料包围绕微信小程序与Java后端构建会议室管理系统,面向高校软件工程、计算机相关专业学生,尤其适合需要完成毕业设计或实训项目的学习者。系统以会议室预约管理为核心,涵盖会议室信息维护、预约申请与审批、用…

2026/10/14 0:48:22 阅读更多 →
工业 CANopen 协议栈精要:对象字典结构与 PDO 快速事件映射纯 C 实现

工业 CANopen 协议栈精要:对象字典结构与 PDO 快速事件映射纯 C 实现

在工业自动化产线与多轴运动控制系统中,裸 CAN 2.0B 协议仅定义了物理层与数据链路层。如果直接用原生 11 位标识符随意收发自定义报文,一旦节点数量增加到几十个,总线就会因为缺乏统一的应用层拓扑而陷入混乱。 作为欧洲自动化工业的标准语言…

2026/10/11 10:59:35 阅读更多 →
大模型测试集污染检测技术:从最长公共子序列(LCS)到条件困惑度异常检测

大模型测试集污染检测技术:从最长公共子序列(LCS)到条件困惑度异常检测

在评估大语言模型(LLM)的综合推理与数理能力时,**测试集污染(Data Contamination)**始终是笼罩在学术界与工业界头顶的“房间里的大象”。在大模型动辄消耗数十万亿 Token 的预训练与持续预训练阶段,爬虫抓…

2026/10/12 17:02:34 阅读更多 →

最新新闻

金融时间序列建模全流程:从平稳性检验到GARCH波动率预测

金融时间序列建模全流程:从平稳性检验到GARCH波动率预测

1. 从第一节课到第四章:金融时间序列到底在研究什么如果你正在啃金融相关的课程,大概率会在一门叫《金融时间序列分析》或类似名字的课上卡住。这门课和传统统计学、计量经济学都不一样,它研究的是股票收益率、汇率波动、债券利差这类有“先后…

2026/10/14 0:48:55 阅读更多 →
AgenticOps工程:企业自动化运维的自主决策革命

AgenticOps工程:企业自动化运维的自主决策革命

1. AgenticOps Engineering 的本质与价值AgenticOps Engineering 正在重新定义企业自动化运维的边界。与传统自动化工具不同,这种新型工程范式通过赋予系统自主决策能力,使企业IT基础设施能够像拥有"数字员工"一样主动感知环境变化、预测问题并…

2026/10/14 0:48:55 阅读更多 →
用插件重构知识工作流:浏览器、编辑器与知识库的自动化实践

用插件重构知识工作流:浏览器、编辑器与知识库的自动化实践

知识工作者这个词听起来有点抽象,但落到日常就非常具体:你可能天天在写方案、查资料、写代码、记笔记、做汇报,一天结束回头一看,真正用在"思考"上的时间反而不多,大量时间被复制粘贴、切换窗口、找文件、重…

2026/10/14 0:48:55 阅读更多 →
ABAP单元测试效率提升:ADT工具链实战

ABAP单元测试效率提升:ADT工具链实战

1. 项目概述:当ABAP单元测试遇上效率革命在SAP开发领域,ABAP Unit作为核心测试框架已经存在多年,但真正能将其融入日常开发的团队却不多见。问题不在于框架本身,而在于传统测试流程中存在太多效率断层——从编写测试用例到执行测试…

2026/10/14 0:48:55 阅读更多 →
Python远程批量关机实战:WinRM/WMI/SMB三路径选型与避坑

Python远程批量关机实战:WinRM/WMI/SMB三路径选型与避坑

简介:本资源是一份面向Windows系统管理员与IT运维人员的Python自动化脚本工具包,解决多台设备集中管理场景下的远程批量关机需求,适用于机房巡检、课室终端维护、故障应急处置等实际运维任务。压缩包共3个文件(923B)&a…

2026/10/14 0:48:55 阅读更多 →
尖叫声音样本数据集eva:从包结构到训练基线的完整实践

尖叫声音样本数据集eva:从包结构到训练基线的完整实践

简介:EVA尖叫声音样本数据集是一份面向音乐信息检索(MIR)与音频分类研究的人声尖叫样本库,由台湾清华大学MIR课程项目整理,旨在为尖叫检测、异常声音识别、SVM分类等实验提供稀缺的领域数据。压缩包共63个文件&#xf…

2026/10/14 0:47:55 阅读更多 →

日新闻

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