C语言JSON解析核心函数cJSON_GetObjectItem详解与实战
1. 从“黑盒”到“钥匙”为什么我们需要 cJSON_GetObjectItem在C语言的世界里处理JSON就像在一个没有标签的仓库里找东西。仓库管理员比如某个网络接口递给你一个巨大的、结构复杂的包裹JSON字符串告诉你“你要的数据在里面自己找吧。” 这个包裹里可能嵌套着无数个小盒子对象每个盒子里又装着各种纸条键值对。如果你徒手去拆不仅效率低下还容易把纸条撕破内存错误、解析失败。cJSON_GetObjectItem就是cJSON库给你的一把精准的“钥匙”。它不是解析整个JSON字符串的入口那是cJSON_Parse的工作而是在你已经把包裹拆开、整理好解析成cJSON结构体树之后用来快速、安全地打开特定盒子取出里面那张你需要的纸条的函数。没有它你就得在解析后的树形结构里手动遍历写一堆繁琐的if判断和指针操作代码冗长且极易出错。有了它你只需要告诉它“父对象”和“钥匙的名字”键名它就能直接把你需要的值cJSON节点递给你或者告诉你“没找到”返回NULL。几乎所有涉及JSON数据交互的C/C项目都绕不开这个函数。无论是解析来自物联网设备的传感器数据{temperature: 25.5, humidity: 60}处理Web API的返回结果{code: 200, data: {...}}还是读取本地的配置文件cJSON_GetObjectItem都是你从结构化数据中提取特定信息的首选工具。它的设计直白而高效完美契合了C语言“贴近硬件、注重效率”的哲学同时又通过库的封装规避了手动操作原始字符串的种种风险。2. 函数原型与参数精解不仅仅是两个参数那么简单看一眼cJSON_GetObjectItem的函数原型简单到令人安心CJSON_PUBLIC(cJSON*) cJSON_GetObjectItem(const cJSON * const object, const char * const string);但在这简单的背后藏着几个必须吃透的细节否则“安心”就会变成“坑”。2.1 参数 object你的搜索起点第一个参数object类型是const cJSON*。这里的关键词是“对象”。cJSON库中只有类型为cJSON_Object的节点才能作为cJSON_GetObjectItem的有效搜索起点。为什么因为JSON对象在语法上是由花括号{}包裹的、无序的键值对集合。cJSON_GetObjectItem的内部实现本质上就是遍历这个cJSON_Object节点下的子节点链表逐个比对子节点的string字段即键名是否与传入的string参数匹配。如果你错误地传入了一个cJSON_Array数组或cJSON_String字符串等类型的节点函数的行为是未定义的。通常它会直接返回NULL因为数组或字符串节点内部没有用于存储键值对的链表结构。这会导致你误以为“键不存在”而实际上是“找错了地方”。一个必须养成的习惯在调用cJSON_GetObjectItem之前先确认object参数不为NULL并且其type字段是cJSON_Object。这是一个防御性编程的基本操作。cJSON *root cJSON_Parse(json_string); if (root NULL) { // 解析失败处理错误 return; } if (root-type ! cJSON_Object) { // 根节点不是对象不符合预期 cJSON_Delete(root); return; } cJSON *item cJSON_GetObjectItem(root, key);2.2 参数 string精确匹配的键名第二个参数string类型是const char*代表你要查找的键名。这里的匹配是区分大小写的精确匹配。这意味着name、Name和NAME会被认为是三个完全不同的键。很多跨语言数据交换的坑都源于此。例如后端用Go语言生成的JSON键名可能是userId驼峰命名而前端JavaScript或C语言客户端如果尝试用userid或user_id去获取就会失败。在项目初期定义好统一的命名规范如全小写下划线并在所有交互方严格遵守能省去大量调试时间。另一个重点是字符串的生命周期。cJSON_GetObjectItem内部不会复制这个string参数它只是用这个指针进行字符串比较。因此你必须确保传入的字符串指针在函数调用期间是有效的。通常我们直接传入字符串字面量如key或栈上/堆上有效的字符数组地址这没有问题。但要避免传入一个已经被释放或作用域已结束的临时字符串地址。2.3 返回值指针与所有权的哲学函数的返回值是一个cJSON*指针。理解这个指针的所有权至关重要。cJSON_GetObjectItem返回的是一个指向已有cJSON结构体内存节点的指针而不是一个新创建的副本。这意味着不要手动释放它你不需要、也不应该对这个返回的指针调用cJSON_Delete。它的生命周期由其父对象即传入的object管理。当你删除父对象cJSON_Delete(root)时所有子节点包括这个返回的item会被递归地、安全地释放。它的有效性依赖于父对象如果你在获取到这个item指针后修改或释放了它的父对象那么这个item指针就变成了悬垂指针dangling pointer再次访问它将导致未定义行为通常是程序崩溃。NULL的含义如果返回NULL只代表在当前object下没有找到对应string键名的子项。这本身不一定是错误可能是数据中该字段可选。你需要根据业务逻辑来判断是记录日志、使用默认值还是报错返回。3. 实战演练从基础查询到嵌套挖掘理解了原理我们来动手操作。假设我们有以下JSON字符串代表一个用户信息const char *json_str {\name\: \张三\, \age\: 30, \isStudent\: false, \hobbies\: [\reading\, \coding\], \address\: {\city\: \北京\, \street\: \中关村\}};3.1 基础类型值的提取首先解析并获取根对象cJSON *root cJSON_Parse(json_str); if (root NULL) { const char *error_ptr cJSON_GetErrorPtr(); if (error_ptr ! NULL) { fprintf(stderr, 解析错误错误位置前的内容: %s\n, error_ptr); } return; }现在我们来获取各种类型的值获取字符串cJSON *name_item cJSON_GetObjectItem(root, name); if (name_item ! NULL cJSON_IsString(name_item)) { printf(用户名: %s\n, name_item-valuestring); } else { printf(未找到‘name’字段或字段类型不是字符串。\n); }注意这里使用了cJSON_IsString辅助宏进行类型检查。直接访问name_item-valuestring而不检查类型是危险的如果JSON中name: 123那么valuestring将是NULL。获取数字cJSON *age_item cJSON_GetObjectItem(root, age); if (age_item ! NULL cJSON_IsNumber(age_item)) { // cJSON将数字统一存储在 double valuint 或 int valueint 中 // 对于整数通常访问 valueint 更合适 printf(年龄: %d\n, age_item-valueint); // 如果是浮点数则访问 valuedouble // printf(年龄: %f\n, age_item-valuedouble); }获取布尔值cJSON *is_student_item cJSON_GetObjectItem(root, isStudent); if (is_student_item ! NULL cJSON_IsBool(is_student_item)) { // cJSON_IsTrue 和 cJSON_IsFalse 是更安全的判断方式 if (cJSON_IsTrue(is_student_item)) { printf(是学生\n); } else if (cJSON_IsFalse(is_student_item)) { printf(不是学生\n); } }3.2 处理嵌套对象和数组这是cJSON_GetObjectItem真正发挥威力的地方。你需要像剥洋葱一样一层层地获取。获取嵌套对象中的值cJSON *address_item cJSON_GetObjectItem(root, address); if (address_item ! NULL cJSON_IsObject(address_item)) { cJSON *city_item cJSON_GetObjectItem(address_item, city); if (city_item ! NULL cJSON_IsString(city_item)) { printf(城市: %s\n, city_item-valuestring); } }可以看到我们先用cJSON_GetObjectItem(root, address)拿到代表地址的对象节点再以这个节点为新的起点调用cJSON_GetObjectItem(address_item, city)。遍历数组cJSON_GetObjectItem能帮你拿到数组节点但遍历数组需要另一种方式。cJSON *hobbies_item cJSON_GetObjectItem(root, hobbies); if (hobbies_item ! NULL cJSON_IsArray(hobbies_item)) { printf(爱好: ); cJSON *hobby NULL; // 使用 cJSON_ArrayForEach 宏安全遍历数组 cJSON_ArrayForEach(hobby, hobbies_item) { if (cJSON_IsString(hobby)) { printf(%s , hobby-valuestring); } } printf(\n); }这里cJSON_GetObjectItem的作用是定位到hobbies这个数组节点。后续的遍历操作由cJSON_ArrayForEach宏完成它本质上是一个链表遍历的语法糖。3.3 链式调用与错误处理模式对于深层次嵌套我们可以写出链式调用的代码但必须结合严谨的错误处理// 目标安全地获取 root.address.city 的值 const char *city NULL; cJSON *address cJSON_GetObjectItem(root, address); if (address ! NULL cJSON_IsObject(address)) { cJSON *city_item cJSON_GetObjectItem(address, city); if (city_item ! NULL cJSON_IsString(city_item)) { city city_item-valuestring; // 注意这里只是获取了指针字符串内存仍由cJSON树管理 } } if (city ! NULL) { printf(城市是: %s\n, city); } else { printf(无法获取城市信息。\n); }一个重要的提醒上面代码中city是一个指向cJSON节点内部字符串的指针。在root被cJSON_Delete释放后这个指针就失效了。如果你需要持久化这个字符串比如存入自己的结构体必须进行内存拷贝如使用strdup。4. 进阶技巧与性能考量当你熟练使用基础功能后下面这些技巧能让你写出更健壮、更高效的代码。4.1 cJSON_GetObjectItemCaseSensitive 的取舍cJSON库实际上提供了两个获取函数cJSON_GetObjectItem和cJSON_GetObjectItemCaseSensitive。在默认编译选项下未定义CJSON_STRICTcJSON_GetObjectItem是不区分大小写的而cJSON_GetObjectItemCaseSensitive是区分大小写的。这听起来可能和之前的“精确匹配”描述矛盾。实际上这是一个为了兼容性而设计的“坑”。很多历史代码依赖了不区分大小写的特性。最佳实践是在新项目中明确使用cJSON_GetObjectItemCaseSensitive来强制区分大小写这更符合JSON标准和大多数解析器的行为也能避免潜在的隐蔽bug。你可以在编译cJSON时通过定义CJSON_STRICT宏来让cJSON_GetObjectItem也变为区分大小写。4.2 使用 cJSON_HasObjectItem 进行存在性检查如果你只关心某个键是否存在而不需要立即获取其值可以使用cJSON_HasObjectItem。它的原型是CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);。它返回一个布尔值cJSON_True/cJSON_False。在某些场景下这比先Get再判断NULL更清晰尤其是当你进行一系列条件检查时if (cJSON_HasObjectItem(config, \auto_save\)) { // 执行一些依赖 auto_save 键存在的初始化操作 } // 稍后再具体获取它的值 cJSON *auto_save_item cJSON_GetObjectItem(config, \auto_save\); ...4.3 性能优化避免在循环中重复查找这是一个非常常见的性能陷阱。假设你有一个大的配置对象需要根据一个键列表来提取值const char *keys_to_fetch[] {\title\, \author\, \version\, \date\}; int num_keys sizeof(keys_to_fetch) / sizeof(keys_to_fetch[0]); // 低效做法每次都在大对象中线性搜索 for (int i 0; i num_keys; i) { cJSON *item cJSON_GetObjectItem(large_config_object, keys_to_fetch[i]); // ... 处理 item }cJSON_GetObjectItem的内部实现是遍历链表时间复杂度是O(n)。如果large_config_object有M个键这个循环的时间复杂度就是 O(M * N)。当M和N都很大时效率低下。优化思路如果键列表是固定的且需要频繁查询可以考虑在解析完成后一次性获取所有需要的键并缓存起来。或者在数据结构设计上如果可能将相关字段组合成一个子对象这样你只需要查找一次子对象然后在较小的子对象中查找多个键。4.4 与 cJSON_GetObjectItem 相关的内存管理“坑”修改返回项的值你可以修改cJSON_GetObjectItem返回的节点内容比如item-valuestring strdup(\new value\);。但极其危险因为valuestring原本指向的内存是由cJSON在解析时分配的直接替换会导致内存泄漏。正确的做法是使用cJSON_SetValuestring函数它会安全地释放旧字符串并设置新字符串。// 错误做法内存泄漏 // cJSON *name cJSON_GetObjectItem(obj, \name\); // name-valuestring malloc(...); // 正确做法 cJSON *name cJSON_GetObjectItem(obj, \name\); cJSON_SetValuestring(name, \新名字\);“借用”的字符串指针再次强调cJSON_GetObjectItem返回的节点中的valuestring指针其指向的内存生命周期与整个cJSON树绑定。如果你需要在这个树被释放后继续使用这个字符串必须进行拷贝。cJSON *name_item cJSON_GetObjectItem(root, \name\); if (name_item cJSON_IsString(name_item)) { // 安全做法深拷贝字符串 char *name_copy strdup(name_item-valuestring); // ... 使用 name_copy ... free(name_copy); // 记得释放 }5. 真实场景下的问题排查与调试理论再完美也抵不过实际编码时遇到的诡异问题。下面是我在项目中遇到的几个典型问题及排查思路。5.1 问题一总是返回NULL但键名明明存在症状代码逻辑清晰键名反复核对无误但cJSON_GetObjectItem就是返回NULL。排查链路检查根节点类型首先打印或调试查看root-type。如果JSON字符串是数组[...]而你用cJSON_GetObjectItem去访问必然失败。此时应该用cJSON_GetArrayItem或遍历数组。检查键名空格和不可见字符这是最常见的坑。JSON中的键名是带双引号的。如果你的输入字符串是手动拼接或来源不可靠键名前后可能有多余的空格、制表符甚至换行符。例如{\ name \ : \value\}。cJSON在解析时会忠实保留这些字符。解决方法是在解析前净化字符串或确保数据源是规范的。确认编码确保你的源代码文件编码、字符串字面量编码与JSON数据的编码一致通常为UTF-8。如果键名包含多字节字符如中文编码不一致会导致字符串比较失败。使用调试器或打印在调用函数前打印出object节点的string和type字段看看它到底包含什么。也可以写一个简单的遍历函数打印出对象的所有键名与你传入的键名进行肉眼比对。void print_object_keys(cJSON *obj) { cJSON *child obj-child; while (child) { printf(\Key: %s, Type: %d\\n\, child-string, child-type); child child-next; } }5.2 问题二程序在访问值时报段错误症状cJSON_GetObjectItem返回了非NULL指针但一访问item-valuestring或item-valueint程序就崩溃。排查链路类型不匹配这是首要怀疑对象。返回的指针虽然非NULL但节点的type可能不是你以为的。比如你试图访问一个cJSON_Number节点的valuestring它会是NULL对NULL解引用就崩溃了。务必在使用值前用cJSON_IsString、cJSON_IsNumber等宏进行类型守卫。cJSON *item cJSON_GetObjectItem(obj, \count\); // 错误如果 \count\ 的值是字符串 \123\下面这行就会崩溃或出错。 // int count item-valueint; // 正确 if (cJSON_IsNumber(item)) { int count item-valueint; } else if (cJSON_IsString(item)) { // 也许可以尝试转换 int count atoi(item-valuestring); }悬垂指针你是否在获取item指针后不小心提前释放或修改了它的父对象object确保整个cJSON树在你使用期间保持稳定。内存越界整个cJSON树可能因为其他原因如原始JSON字符串缓冲区被意外修改已经损坏。确保用于解析的JSON字符串在解析完成前是常量且有效的。5.3 问题三处理可选字段的最佳实践JSON数据中常有可选字段。处理它们时代码容易变得冗长。不佳实践cJSON *item cJSON_GetObjectItem(data, \optional_field\); if (item ! NULL) { if (cJSON_IsString(item)) { // 处理字符串... } else if (cJSON_IsNumber(item)) { // 处理数字... } // ... 其他类型 } // 如果字段不存在使用默认值更清晰的实践封装一个辅助函数。例如一个安全获取字符串并返回默认值的函数const char *cjson_get_string_default(const cJSON *obj, const char *key, const char *default_val) { const cJSON *item cJSON_GetObjectItem(obj, key); if (cJSON_IsString(item)) { return item-valuestring; } return default_val; } // 使用 const char *name cjson_get_string_default(user, \nickname\, \匿名用户\);类似地可以封装获取整数、浮点数、布尔值的函数使业务逻辑代码更简洁、更安全。6. 超越 cJSON_GetObjectItem探索cJSON的其他利器cJSON_GetObjectItem是查询的基石但cJSON库还提供了其他辅助函数在特定场景下能让代码更优雅。6.1 cJSON_GetObjectItem 的“兄弟”函数cJSON_GetArrayItem/cJSON_GetArraySize专门用于处理数组类型。如果你知道索引cJSON_GetArrayItem是O(1)操作比遍历对象链表更快。cJSON_DetachItemViaPointer/cJSON_DetachItemFromArray这些函数允许你从父对象中“摘下”一个子项返回其指针而不会释放它。这在需要重组JSON树时非常有用。切记“摘下”后你需要负责管理这个子项的内存最终要对其调用cJSON_Delete。6.2 使用 cJSON_Print 和 cJSON_PrintUnformatted 进行调试当你的解析逻辑出现问题时将cJSON对象树打印出来是最直观的调试方法。char *json_str_parsed cJSON_Print(root); if (json_str_parsed) { printf(\解析后的JSON树:\\n%s\\n\, json_str_parsed); free(json_str_parsed); // cJSON_Print 分配了内存需要释放 }cJSON_Print输出格式化的字符串带缩进和换行便于阅读。cJSON_PrintUnformatted输出紧凑的字符串节省空间。比较解析后重新打印的字符串与原始输入能快速发现解析差异。6.3 构建JSONcJSON_CreateObject 与 cJSON_AddItemToObject解析只是单向操作很多时候我们需要构建JSON。这时cJSON_GetObjectItem的“逆操作”是cJSON_AddItemToObject。// 创建一个新的JSON对象 cJSON *root cJSON_CreateObject(); // 向对象中添加键值对 cJSON_AddStringToObject(root, \status\, \success\); cJSON_AddNumberToObject(root, \code\, 200); cJSON *data_obj cJSON_CreateObject(); cJSON_AddStringToObject(data_obj, \message\, \Hello World\); // 将一个对象作为另一个对象的值添加 cJSON_AddItemToObject(root, \data\, data_obj); // 打印结果 char *output cJSON_Print(root); printf(\%s\\n\, output); free(output); cJSON_Delete(root);理解构建过程能让你对cJSON的内存管理和树形结构有更深的认识反过来也能帮助你更好地理解和排查解析时遇到的问题。你会发现cJSON_AddItemToObject内部其实就是创建节点、设置键名、并将其链接到父对象的子链表上这与cJSON_GetObjectItem的查找过程恰好相反。

相关新闻

51单片机综合项目实战:DS1302数码管时钟与闹钟系统设计

51单片机综合项目实战:DS1302数码管时钟与闹钟系统设计

你是不是也遇到过这样的问题:想用51单片机做一个带闹钟功能的数字时钟,结果发现网上资料要么太简单只能显示时间,要么太复杂看不懂底层驱动?或者好不容易找到代码,却发现仿真跑不通,按键没反应,…

2026/10/1 21:28:39 阅读更多 →
STM32开发环境搭建全攻略:Keil5+ST-Link+HAL库从零配置指南

STM32开发环境搭建全攻略:Keil5+ST-Link+HAL库从零配置指南

1. 项目概述:为什么STM32开发环境搭建是“第一课”如果你刚拿到一块STM32开发板,或者从51单片机、Arduino转向更专业的嵌入式领域,那么“开发环境搭建”就是你无法绕开、也必须走稳的第一步。很多新手朋友觉得这不过是装几个软件,…

2026/10/10 16:12:04 阅读更多 →
把手机屏幕“搬“上电脑有多爽?QtScrcpy 投屏实战全记录

把手机屏幕“搬“上电脑有多爽?QtScrcpy 投屏实战全记录

把手机屏幕"搬"上电脑有多爽?QtScrcpy 投屏实战全记录 【免费下载链接】QtScrcpy Android real-time display control software 项目地址: https://gitcode.com/GitHub_Trending/qt/QtScrcpy 一边要回手机微信,一边要盯着电脑文档&…

2026/10/9 4:27:11 阅读更多 →

最新新闻

Selenium Manager连接被重置?从网络排查到离线驱动配置全解

Selenium Manager连接被重置?从网络排查到离线驱动配置全解

1. 先搞清楚:Selenium Manager 报“远程主机强迫关闭了一个现有的连接”到底卡在哪一步自动化跑到一半,控制台突然甩出这么一行红色日志:selenium_manager | error trying to connect: 远程主机强迫关闭了一个现有的连接第一次遇到的人大概率…

2026/10/12 7:11:11 阅读更多 →
12天3城3展:工业品牌如何通过高密度参展实现区域渗透

12天3城3展:工业品牌如何通过高密度参展实现区域渗透

1. 一场高密度行程背后的参展逻辑12天,3座城市,3场展会。从天津到杭州,再到上海工博会。这个行程密度放在任何一家制造型企业身上,都算得上是一次高强度的"拉练"。拉孚(Larfe)这个名字&#xff0…

2026/10/12 7:11:10 阅读更多 →
AI Coding Agent实战指南:从自动补全到智能编程助手

AI Coding Agent实战指南:从自动补全到智能编程助手

我最早接触AI Coding,还是那种“按一下Tab补全一行”的老工具,说实话那时候充其量算个输入法。这几年再看,情况已经完全不一样了:主流的编程助手都配了“Agent模式”,你给它一句任务,它能自己翻项目文件、动…

2026/10/12 7:11:10 阅读更多 →
死区示例代码详解:从JS TDZ到摇杆、PID防抖的全场景实践

死区示例代码详解:从JS TDZ到摇杆、PID防抖的全场景实践

干软件这些年,我越来越觉得“死区”是两个被严重低估的字。调试摇杆的时候要处理死区,写定时控制逻辑的时候要处理死区,甚至在解答 JavaScript 报错的时候,也逃不开它。第一次听到“死区”的人会以为这又是某种玄学概念&#xff0…

2026/10/12 7:11:10 阅读更多 →
冷热电三联供Simulink仿真:从能量流建模到控制策略与调试

冷热电三联供Simulink仿真:从能量流建模到控制策略与调试

接到“综合能源系统仿真:冷热电三联供Simulink仿真”这个需求的时候,我第一反应不是找现成demo,而是先想明白一件事:这套仿真模型到底要回答什么问题。是用作教学演示,还是要做容量配置的可行性分析?是研究…

2026/10/12 7:11:10 阅读更多 →
AnyPS5项目解析:PS5手柄跨平台兼容性技术探析

AnyPS5项目解析:PS5手柄跨平台兼容性技术探析

我无法基于当前输入生成符合要求的博文。原因如下:输入中仅提供了项目标题"AnyPS5",但未提供任何实质性的【项目正文】、【关键词】或【摘要描述】;所附“相关热搜词”与“最新网络热词”字段为空,无可用语义线索&#…

2026/10/12 7:10:10 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器: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 阅读更多 →