嵌入式静态分析入门:用Cppcheck筑牢代码质量底线
做嵌入式开发的这些年我越来越理解一句话代码里最贵的 bug往往不是编译不过的而是编译通过、跑起来也正常、唯独在某个极端路径下才爆发的。前几天帮一位做车载设备的朋友定位故障折腾了一整天最后发现是协议解析里一个数组越界在编译器不开优化时恰好没有破坏数据开了优化后才把相邻栈变量踩掉。这类问题用动态测试很难复现但 Cppcheck 这种嵌入式静态分析工具从源码层面扫一遍通常一眼就能指出来。这篇文章不打算讲太多理论就把自己这几年在实际嵌入式工程里使用 Cppcheck 的经验、参数配置、与构建系统集成的方式、以及被误报折磨后摸索出来的治理方法一次性梳理清楚。适合正在入门静态分析工具的嵌入式软件工程师也适合想在团队里落地代码质量门禁的负责人。你不需要很深的工具链知识照着做就能搭出一套可用的检查流程。Cppcheck 是开源的 C/C 静态分析工具支持 Linux、Windows、macOS对嵌入式常用的 C99/C11 以及 C 标准支持得都比较全。它和商业静态分析工具相比最大的优势是免费、可定制、跑得快而且社区更新活跃规则也在不断补充。下面从一个真实可复现的命令开始。1. 静态分析在嵌入式项目中的定位1.1 嵌入式代码的典型雷区嵌入式代码和服务器后端代码有一个很大的区别前者通常运行在资源受限的 MCU 上出问题后的排查手段非常有限。在裸机芯片上很难挂调试器断点更不可能像调试 Web 服务那样随手打日志。很多故障要靠现场复现、抓波形、拆设备才能定位代价极高。所以对于固件开发来说把问题尽量前置在编译期和检查期就发现是最划算的事情。具体到代码层面嵌入式项目里最常踩的几类雷我随手就能列出一串缓冲区溢出与数组越界。小内存设备上这类问题不仅导致功能异常还可能破坏邻近变量甚至踩坏栈行为非常随机。整数溢出与符号位问题。传感器数据、协议解析里大量存在 uint8_t、uint16_t 的窄类型运算溢出是常态而且编译器不报。空指针与野指针。驱动代码里频繁操作硬件指针错误分支处理不当就是一颗定时炸弹。未初始化变量。老编译器下可能默认零换新编译器或开优化后行为完全不同这类问题最难定位。资源管理问题。malloc/free、句柄、中断使能的不对称使用长期运行后逐步耗尽。位操作与 volatile 缺失。寄存器操作少写 volatile优化器把连续读合并成一次读取驱动就失效了。这些问题有一个共同特征它们在语法上合法在常规测试路径上不触发但确实可以在特定输入、特定优化级别下被激活。你很难靠编译器和人工 Review 全部拦下来这时候就需要静态分析工具做一次源码级的穷举扫描。1.2 编译器告警和静态分析的差异有人会说编译器开了 -Wall -Wextra -Werror 不也能提示吗确实能抓一部分但编译器更关注语法、类型和明显的未定义行为而且不同厂商的编译器检查力度参差不齐。尤其嵌入式领域常见的私有编译器或老旧编译器告警能力可能停留在十年前的水平。Cppcheck 站在源码层面做数据流分析、路径分析和符号执行能发现不少编译器不报的问题比如某些条件下变量未初始化、按路径可达的数组越界、资源重复释放、空指针在特定分支里被解引用。它的定位不是替代编译器而是跟编译告警、人工审查、动态测试形成互补。这个增量在我实践中非常明显。某次给一套老工业控制器代码做全面体检Cppcheck 在几万行 C 代码里查出了三十多处 warning 以上级别的问题其中两处是真实的数组越界路径——代码在正常输入下不会触发但协议帧被异常填充时就会越界。这类问题靠人工 code review 不是不能发现但在遗留代码量很大的项目里用工具先筛一遍明显高效得多。1.3 为什么选择 Cppcheck静态分析工具其实不少商业的有好几家功能强大但价格也很感人部署和培训成本都不低。开源方案里 Cppcheck 是接受度最高的一个。它的优势可以归纳为几点第一免费开源没有 license 数量限制团队里每个人都能跑第二支持 C89/C99/C11/C17 和多种 C 标准对嵌入式老工程很友好第三有 JSON/XML 输出容易接进 CI 平台也方便自己写脚本处理第四提供 MISRA 等编码规范的增量检查能力虽然不如专业工具那么完备但对付大多数场景够了。当然它也有短板。最明显的是误报率比商业工具高一些遇到复杂的宏展开和平台相关头文件时需要做一定的抑制配置。这恰好是本篇文章要重点解决的问题。你要做的不是拿到工具就跑一个全量检查然后被报告淹没而是学会配置它、驯服它让它真正成为开发流程的一部分。2. 上手第一步检查级别与平台参数2.1 enable 参数到底怎么设Cppcheck 的基本用法极其简单一条命令就能跑cppcheck --enablewarning,style,performance,portability --stdc11 --platformembedded --error-exitcode1 ./src这条命令大概是使用频率最高的一种组合。逐个说明--enable 指定要开启的检查大类。error 级别默认开启warning 是可疑代码style 是风格问题performance 是性能隐患portability 是可移植性问题。--std 指定语言标准告诉工具按哪个版本的语法规则解析代码。--platform 指定目标平台对嵌入式来说用 embedded 能减少部分寄存器相关误报。--error-exitcode 让工具在发现 error 级别问题时返回非零退出码这个在 CI 里非常关键。很多初学者图省事直接用 --enableall我建议慎用。all 会额外开启 unusedFunction 检查它需要跨文件分析哪些函数从未被调用。小项目无所谓大项目里这会显著拉长运行时间而且对于库代码和测试代码会产生大量“没用的函数”噪声。更好的做法是先用我上面那组跑完看报告再按需补充。2.2 平台参数和语言标准的坑--platformembedded 是我强烈建议加上的。它告诉 Cppcheck 目标环境是嵌入式平台此时 int 可能是 16 位或 32 位指针宽度和寄存器访问方式都有别于桌面环境。如果不加这个参数工具按照 64 位桌面环境来推断类型宽度很多和窄类型、位宽相关的检查就会失真要么漏报要么误报。语言标准也要跟工程实际情况一致。有的老代码还是 C89 风格声明都放在语句前面你用 --stdc11 去解析也能过但某些检查的上下文判断会更严格容易误伤。反过来新写的代码用了 C11 的特性你用 --stdc89解析阶段可能就报语法错误。最稳妥的办法是跟编译器用的标准保持一致。这里给一个参考表格方便快速对照场景推荐参数裸机 C 工程C99 标准--stdc99 --platformembeddedARM Cortex-M 系列固件--platformembedded --stdc11Linux 用户态 C 程序--platformunix64 --stdc11C 嵌入式应用--stdc11 --platformembedded跨平台库--platformunix64 --platformwin64 分别跑2.3 输出格式与报告对接Cppcheck 默认输出纯文本人看没问题但接 CI 平台和生成报告就需要结构化输出。两种格式最常用cppcheck --xml --xml-version2 --enablewarning,performance --projectcompile_commands.json -j4 2 cppcheck-result.xmlXML 输出可以直接被很多 CI 插件解析。另一个是模板输出适合脚本处理cppcheck --template{file}:{line}: {severity}: {message} [{id}] --enablewarning ./src我一般把模板输出重定向到文件再用 grep 或脚本做统计。比如想知道警告集中在哪些文件直接 awk 按文件名分组排序几秒钟就能定位到问题重灾区。这一步看起来不起眼实际分析大项目时非常有用。3. 真正用起来工程集成全流程3.1 用编译数据库解决头文件地狱嵌入式工程最让静态分析工具头疼的不是代码本身而是头文件路径和宏定义。交叉编译环境下编译器内置路径、芯片厂商 SDK 的头文件、RTOS 的配置头文件层层嵌套手工用 -I 去补基本上补不齐稍微漏一个就满屏 parse error。正确的姿势是复用编译器自己的配置。CMake 工程可以在生成构建系统时带上编译数据库cmake -DCMAKE_EXPORT_COMPILE_COMMANDSON .. cppcheck --projectcompile_commands.json --enablewarning,performance -j4compile_commands.json 里记录了每个源文件编译时用的确切命令包括头文件路径、宏定义、语言标准。Cppcheck 直接读取这份文件就相当于拿到了编译器视角的完整上下文解析失败率会大幅下降。非 CMake 工程也别慌。Linux 下可以用 bear 包裹 make 命令来生成同样的编译数据库bear -- make有些老工程用自定义构建脚本也能通过 Cppcheck 的 --includes-file 和 --defines-file 手动指定头文件路径和宏列表。虽然麻烦一点但比在命令行里堆几十个 -I 要可维护得多。我在实际项目里就是先试 compile_commands.json不行再退回手动配置后者只作为兜底方案。3.2 在 CI 里跑门禁的正确姿势工具单机能跑通只是第一步真正让静态分析发挥价值的地方是持续集成。团队十几个人同时改代码指望每个人都在本地跑一遍检查不现实只有在合并代码前让机器自动把关才能形成制度约束。我的建议是先把存量问题建档而不是一上来就要求零告警。操作上分三步第一步对当前主干跑一次全量检查把结果保存为基线文件第二步CI 中对本次变更涉及的源文件做增量检查第三步新增问题阻塞合入存量问题允许存在但必须可追溯。增量检查的实现思路很简单就是对比变更文件列表只对变更文件执行 Cppcheck。脚本大致长这样#!/bin/bash files$(git diff --name-only origin/main...HEAD -- *.c *.cpp) if [ -n $files ]; then cppcheck --projectcompile_commands.json --enablewarning,performance \ --suppressionssuppressions.txt --error-exitcode1 $files fi这里有个细节单独拎出几个文件检查时如果它们依赖其他文件里的类型和函数定义Cppcheck 会回头去解析全部 include性能反而不好。更稳妥的做法是配合 --file-filter 参数对整个工程扫描但只输出指定文件的报告。这样既保留了完整上下文又只关注变更点。3.3 误报治理从无脑抑制到基线管理谈 Cppcheck 的落地绕不开误报这个话题。工具越严格误报自然越多但如果团队一看到误报就手忙脚乱地往代码里塞抑制注释那只会把问题掩盖掉。正确的路线是建立一套有层次的抑制机制。第一层是全局抑制文件把那些与项目无关的系统性噪声统一处理掉。比如缺失系统头文件这是个典型噪声源?xml version1.0? suppressions suppress idmissingIncludeSystem/id /suppress suppress idunknownMacro/id file*/sdk/*/file /suppress /suppressions第二层是针对具体告警的局部抑制。确认是误报后我在代码旁边写内联抑制注释并注明原因方便后来人 review// 硬件寄存器按 32 位指针访问此处解引用是预期的 // cppcheck-suppress nullPointerRedundantCheck value *(volatile uint32_t *)REG_ADDR;第三层是基线文件。已经存在的存量告警全部记录在基线里不阻塞合入但每季度安排一次清理行动。这样既不会让工具成为开发者的敌人也保证问题始终在账面上不会被遗忘。我自己实践下来这个治理节奏比“一步清零”靠谱得多。强推零告警的结果往往是团队学会各种花式抑制最后报告里干干净净但真实问题一点没少。4. 实战中一定会碰到的坑4.1 头文件解析失败的典型场景Cppcheck 最让人崩溃的输出就是满屏的 failed to parse 和 internalError。我第一次跑一个带商业编译器的工程时几乎一半文件都报解析失败当时差点放弃这个工具。后来总结下来解析失败大致有三个原因一是编译器特有的关键字比如attribute、__interrupt、__packed 等Cppcheck 不认二是头文件路径缺失导致大量 unknown macro三是代码里使用了编译器的扩展语法但工具的解析器只认标准 C/C。解决方式也有三件套第一用 -D 把编译器内置宏补上或者在项目根目录建一个 defines.txt把所有平台相关宏集中管理第二在工具链里设置 --platformembedded让它能识别一部分嵌入式编译器扩展第三实在解析不了的文件用 --suppressmissingInclude 或直接 --file-filter 排除掉但要在报告里留下记录。还有个容易被忽视的选项是 --force。它在遇到无法确定的条件编译宏时会尝试分析所有配置分支而不是默认只分析一条路径。代价是速度变慢但确实能减少因宏展开导致的漏报。我在安全相关的模块上会开普通业务代码不开。4.2 宏展开带来的误报和漏报嵌入式代码里宏几乎是不可避免的尤其寄存器操作和板级配置经常是大规模宏套宏。Cppcheck 虽然会做宏展开但它和编译器的展开方式并不完全一致于是出现两类问题一类是误报比如 assert 宏展开后工具认为某变量可能未初始化另一类是漏报比如条件编译覆盖了某个危险路径工具没有深入分析。针对误报我会把项目自定义的宏在配置里显式声明。比如 NDEBUG、UNIT_TEST 这类,可以在命令行里显式传参cppcheck -DNDEBUG -UUNIT_TEST --enablewarning --projectcompile_commands.json-D 表示定义宏-U 表示取消宏。这告诉 Cppcheck 走哪条编译路径能大幅减少因配置分支导致的误报。还有一个参数 --max-configs它控制工具最多检查多少个配置组合。嵌入式工程里条件编译多配置组合可能成千上万不设上限会跑得非常慢设太小又会漏掉某些配置下的问题。我一般设 64 或 128够覆盖常见配置运行时间也可控。这个参数需要根据项目条件编译复杂度慢慢调没有绝对标准。4.3 全量检查太慢怎么办大项目的全量 Cppcheck 检查确实慢几万个文件跑下来可能要一两个小时。但这问题不是没有解法。首先是并行。-j 参数指定线程数我在八核机器上一般用 -j8速度接近线性提升。其次是把检查拆开只检查 src 目录排除 build 目录和第三方库。很多团队把整个仓库丢给工具跑结果大量时间浪费在无关代码上。用 --file-filter 或直接命令行限定路径能把时间缩短到原来的五分之一。第三招是增量。CI 里每次全量跑不现实就只对变更文件做检查。这个我在前面已经写过脚本。最后如果还觉得慢可以考虑建一个独立的编译节点专门跑静态检查跟主构建并行不阻塞开发流程。时间上全量检查可以放到凌晨跑早上出报告。还有个小技巧检查时加上 --suppressmissingIncludeSystem可以跳过对系统头文件的反复解析很多项目靠这一条就能省下不少时间。4.4 版本升级带来的告警漂移Cppcheck 版本更新很快新版本会新增检查规则也会修复误报。这意味着同一份代码旧版本没告警新版本可能冒出一堆新问题。这是好事但也容易让团队措手不及。我的习惯是锁定工具版本至少在 CI 里固定使用某个发布版升级时先在本地对基线代码跑一遍评估新增告警的影响再决定是否切换。升级后产生的增量告警不要直接全量抑制而是逐条审视——新告警里往往藏着真问题。我经历过一次升级新版本多出十几条空指针相关的告警其中两条在静态分析后确认是真实 bug当时旧版本完全没提示。5. 进阶玩法与团队落地心得5.1 增加编码规范检查很多嵌入式项目会有编码规范要求比如安全关键代码常用的 MISRA C 规范。Cppcheck 本身不带 MISRA 检查但可以通过 addon 机制扩展。使用时需要指定 addon 脚本cppcheck --addonmisra.py --projectcompile_commands.json --enablewarning,styleaddon 是 Cppcheck 的扩展机制misra.py 是官方提供的一个 Python 脚本它会读取工具的中间结果再输出 MISRA 规则相关的告警。这个能力虽然不比专用的规范检查工具那么权威细致但对于预算有限的团队来说已经足够在早期拦住一大批规范违规。使用 addon 有个前提本地 Python 环境得跑得通而且 addon 脚本版本要跟 Cppcheck 主程序匹配。我踩过版本不匹配的坑表现为 addon 不输出任何结果查了半天才发现是 Python 脚本和主程序版本对不上。建议直接把 addon 文件固定到 CI 环境里避免升级后行为变化。5.2 用 library 文件减少领域误报Cppcheck 支持 .cfg 格式的 library 文件用来自定义函数行为。嵌入式 SDK 里很多函数不是标准库函数工具不了解它们的参数和返回值关系就会产生误报。举个例子某 SDK 的读取函数只要传入合法句柄且返回成功输出缓冲区必定被填充但 Cppcheck 不知道这层关系可能报“buffer is not written”。这时就可以在 library 文件里声明它的语义。我自己维护了一个项目专用的 cfg 文件把芯片厂商 SDK 里常用的函数都声明了一遍。这样做的好处是长期积累、越用越准而不是每次都靠人为抑制掩盖问题。可惜大多数嵌入式团队没有意识到这个功能一直跟误报硬刚其实问题根源在工具不了解领域函数。5.3 团队落地心得最后聊几点团队落地的心得这些是文档里不会写、但实际影响效果的东西。第一先跑基线别逼团队清零。存量代码的问题不是一天造成的强行清零只会引发抵触情绪。先把基线建好让增量问题不再出现存量问题排期消化。第二把工具检查嵌入开发流程而不是事后跑报告。建议在提交代码之前的一个必要步骤里就跑一遍发现问题当场改。人类对“当时的上下文”记忆最清晰隔三天再看报告修改成本高得多。第三定期把趋势分析出来。统计一下每周新增告警数量、存量告警清理数量把这个数字在团队周会上过一遍。不是用来指责谁而是让团队看到质量在变好形成正反馈。我用一个简单的脚本每周自动生成 CSV 报告效果比口头强调好很多。第四给工具成长空间。Cppcheck 不是银弹它做不到商业工具那么深的路径分析也不应该背负“保证零缺陷”的期望。它的价值是低成本地把低级错误兜住把人工审查的精力释放给更复杂的设计问题。带着这个预期去用你会觉得它越用越顺手。我个人在实际操作中的体会是静态分析工具的价值不在于报告多少问题而在于你把那些确定性的低级问题交给机器之后团队终于有时间去 review 真正需要人脑判断的东西。Cppcheck 对嵌入式项目的意义恰恰在于它足够轻、足够直接能安安静静地站在编译流程后面替你守住那些最容易被忽略的边界条件。如果看完这篇文章能让你少踩几个头文件解析和误报治理的坑这篇分享就没白写。

相关新闻

自然语言理解实战:从分词到意图识别的NLU技术链路拆解

自然语言理解实战:从分词到意图识别的NLU技术链路拆解

自然语言理解这个概念,刚入行的时候我也觉得它挺虚的。教科书上给的定义是“让计算机理解和生成人类语言”,听起来一句话就说完了,但真正动手做项目才会发现,这里面藏着从分词、句法分析到语义推理、意图识别的一整条技术链路。你…

2026/10/12 11:41:40 阅读更多 →
Python学生校园消费行为分析:从数据清洗到KMeans聚类实战

Python学生校园消费行为分析:从数据清洗到KMeans聚类实战

简介:针对期末大作业与课程设计的典型需求,面向Python数据分析初学者和需要提交期末大作业的学生,这是一套可直接运行的学生校园消费行为分析课程设计源码。项目以校园一卡通消费记录为研究对象,覆盖数据导入、缺失值处理、消费金…

2026/10/12 11:41:40 阅读更多 →
iDesignCapture实操复盘:从元器件搜索到3D模型下载的四步闭环

iDesignCapture实操复盘:从元器件搜索到3D模型下载的四步闭环

不少硬件工程师应该都有过这种经历:原理图画了一半,发现库里缺个元器件,要么翻遍本地库找不到,要么从旧项目里拷过来发现封装对不上,3D模型更是聊胜于无。我在实际项目中也踩过太多类似的坑,所以当我把 iDe…

2026/10/12 11:41:40 阅读更多 →

最新新闻

Vue实战进阶:从环境配置到动态路由与多端部署要点

Vue实战进阶:从环境配置到动态路由与多端部署要点

学Vue这几年,从最开始只会照着教程敲todo list,到后来完整负责过好几个基于Spring Boot加Vue的前后端分离项目,中间踩过的坑、绕过的弯,攒下来不少东西。这份Vue网站制作学习心得,我按“从入门到实战的进阶之路”来写&…

2026/10/12 13:21:33 阅读更多 →
豆瓣Top250数据分析大作业:Python爬虫+可视化完整源码与避坑指南

豆瓣Top250数据分析大作业:Python爬虫+可视化完整源码与避坑指南

简介:这份资源是面向高校学生与Python初学者的数据可视化课程设计完整方案,围绕豆瓣电影Top250数据集展开,涵盖数据采集、清洗、统计分析与图表呈现全流程,适合用作毕业设计、期末大作业或课程设计的高分参考。压缩包共221个文件&…

2026/10/12 13:21:33 阅读更多 →
基于SpringBoot+Vue的办公管理系统:全栈设计与实现指南

基于SpringBoot+Vue的办公管理系统:全栈设计与实现指南

每年到这个时间点,都会有一批学弟学妹来问我:"毕设选题到底怎么选?Java后端会不会太难?前端是不是要写很多页面?"我的回答一直很统一:如果方向是Java Web或全栈开发,基于SpringBoot …

2026/10/12 13:21:33 阅读更多 →
claude-mem:为Claude打造跨会话长期记忆的本地记忆管理层

claude-mem:为Claude打造跨会话长期记忆的本地记忆管理层

你有没有过这种体验:跟Claude聊一个项目,前期费了好大劲把背景、依赖、约束讲清楚,刚进入正题,上下文窗口满了,或者新开一个会话,全部打回原形。每次对话就像金鱼一样,七秒记忆,项目…

2026/10/12 13:21:33 阅读更多 →
云数据库HTTP API歌单更新实战:权限、批量与避坑指南

云数据库HTTP API歌单更新实战:权限、批量与避坑指南

1. 从一次歌单同步的诡异失败说起做云音乐类小程序,绕不开的一个核心功能就是歌单管理。用户在小程序端新建、编辑、删除歌单,这些操作最终都要落到云数据库里。我最近在重构一个云音乐小程序的管理系统,前面几篇已经把基础架构、页面路由、用…

2026/10/12 13:21:33 阅读更多 →
C++中判断汉字:从编码原理到跨平台实现

C++中判断汉字:从编码原理到跨平台实现

1. 从一次文本统计翻车说起:为什么“判断汉字”没那么简单前阵子帮一个做数据清洗的朋友处理一批用户提交的文本,需求听起来特别朴素:把每条记录里的汉字挑出来,统计一下字数,非汉字的字符(标点、数字、字母…

2026/10/12 13:20:31 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 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 阅读更多 →