tidyr数据整形核心指南:从宽表长表转换到字段拆解
1. 为什么“整理数据”比“分析数据”更耗时——从一个真实项目说起我带过不少刚接触R语言的某高校数据分析课程学员也帮某公司做过几轮业务数据清洗支持。几乎所有人第一次拿到原始数据时第一反应都不是建模或画图而是盯着Excel里那些“看着就头疼”的表格发呆一列里混着姓名、电话、地址时间字段是“2023年5月”“2023/06/15”“Jun-23”三种格式问卷选项用“1男,2女,3其他”写在表头注释里但数据区只有一串数字还有更典型的——把不同年份、不同产品线的销售数据硬塞进同一张表的横向列中美其名曰“宽格式”实则让后续所有计算都变成一场灾难。这些不是异常而是常态。某跨平台系统导出的日志报表、某实验室采集的传感器原始记录、某电商后台下载的用户行为快照……90%以上的R语言项目在library(ggplot2)和lm()之前必须先花3–5倍时间处理数据结构本身。而tidyr包就是专门解决这类“结构病”的手术刀——它不负责统计推断也不做可视化渲染它的全部使命就是把混乱的“人话表格”翻译成R世界能理解的、符合整洁数据原则Tidy Data Principles的标准形态每一行是一个观测observation每一列是一个变量variable每一个单元格是一个值value。这听起来抽象其实就三条铁律行即个体比如“张三”是一行“李四”是另一行不能把张三的订单A、订单B、订单C拆成三行又混进李四的数据里列即属性性别、年龄、城市、购买日期……每个语义明确的特征独占一列不能把“北京_朝阳_建国路8号”塞进一列再靠人工拆分单元格即原子值不能出现“男;女;未知”或“[1,2,3]”这种复合结构每个格子只放一个不可再分的信息单元。你可能觉得“我手动在Excel里拖拽、分列、筛选不就行了”——可以但代价极高不可复现、难追溯、易出错、无法批量处理新批次数据。而tidyr提供的不是功能按钮而是一套可编程、可版本化、可嵌入工作流的数据整形语法。它和dplyr组合起来构成R语言数据科学工作流的底层骨架。没有这个骨架后续所有分析都是沙上筑塔。提示很多人误以为tidyr只是“把宽表变长表”这是最大误区。它真正解决的是数据语义与结构的错配问题——当你的数据“长得像表格”但“不是表格”时tidyr才是那个帮你重写数据DNA的人。2. tidyverse的“结构语法”从pivot_longer()到separate()的逻辑链条tidyr的演进史本质是R社区对“什么是整洁数据”认知不断深化的过程。早期版本依赖gather()/spread()这对组合虽有效但命名不够直觉2020年v1.0之后全面转向pivot_longer()/pivot_wider()术语更贴近数据库范式再到separate()/unite()/extract()等专用工具形成一套层次清晰、职责分明的操作体系。它们不是孤立命令而是一条从粗粒度结构调整到细粒度字段拆解的完整逻辑链。2.1pivot_longer()识别“伪列名”还原真实观测维度假设你拿到一份某高校课程成绩表原始结构如下简化示意student_idnamemath_2022math_2023eng_2022eng_2023S001张三85927886S002李四90888289表面看是“学生×科目×年份”的三维信息但被强行压成二维宽表。math_2022这种列名实际编码了两个变量subject数学和year2022。pivot_longer()的任务就是把这种“列名携带语义”的模式还原为显式的列变量。library(tidyr) library(dplyr) # 原始数据用tibble模拟 df_wide - tibble( student_id c(S001, S002), name c(张三, 李四), math_2022 c(85, 90), math_2023 c(92, 88), eng_2022 c(78, 82), eng_2023 c(86, 89) ) # 关键一步指定哪些列要“融化” df_long - df_wide %% pivot_longer( cols starts_with(math_) | starts_with(eng_), # 选择待处理列 names_to c(subject, year), # 新列名拆解后存哪两列 names_sep _, # 列名分隔符 values_to score # 值存入哪列 )执行后得到student_idnamesubjectyearscoreS001张三math202285S001张三math202392S001张三eng202278...............这里最易错的点在于names_to参数它不是随便起两个名字而是必须对应列名中实际存在的语义维度。若原始列名是math_Q1、math_Q2则names_sep _后names_to c(subject, quarter)才合理若误写为c(subject, year)pivot_longer()不会报错但会把Q1强行当year导致后续分析全盘失真。注意cols参数支持多种选择语法——starts_with()、ends_with()、contains()、matches()正则、甚至直接列名向量。我习惯先用names(df_wide)打印列名再用grep()测试正则是否匹配准确避免漏选或多选。曾有次因matches(score)误匹配了student_score列导致主键被重复展开调试半小时才发现。2.2pivot_wider()从“观测×变量”回归“维度交叉表”pivot_longer()的逆操作常用于生成汇总报表或适配特定绘图需求。例如将上一步得到的长表按学生和年份聚合平均分并转为宽表展示df_summary - df_long %% group_by(student_id, name, year) %% summarise(avg_score mean(score), .groups drop) %% pivot_wider( names_from year, values_from avg_score, values_fill list(avg_score 0) # 缺失值填0谨慎使用 )关键参数values_fill常被忽略但它决定缺失组合如某学生2022年无成绩如何处理。设为NA是安全默认但若下游需数值计算填0可能引入偏差——比如计算“两年总分”时0和NA含义天壤之别。我的经验是除非业务明确定义“无记录0”否则一律保留NA并在后续用replace_na()或条件判断显式处理。2.3separate()与unite()处理“单列多语义”的经典场景当一列内容实际包含多个独立信息时separate()是首选。典型如地址、时间戳、ID编码。例如某电商订单表中order_id列为ORD-2023-001234需拆出前缀、年份、序号df_orders - tibble(order_id c(ORD-2023-001234, EXP-2024-005678)) df_split - df_orders %% separate( col order_id, into c(prefix, year, seq_num), sep -, # 分隔符 extra merge, # 多余部分合并到最后一列防报错 fill right # 缺少部分右填充NA )这里extra和fill参数是实战避坑核心若原始数据存在ORD-2023-001234-TEST多一个分段extra error会中断执行而merge将其合并到seq_num列值变为001234-TEST便于后续用str_remove()清理若某行是ORD-2023缺序号fill left会在prefix列填NA破坏主键完整性而right确保prefix和year优先保全。反向操作unite()则用于合并列。比如将year、month、day三列合成date_strdf_date - tibble(year 2023, month 5, day 15) %% unite( col date_str, year, month, day, sep -, # 连接符 remove TRUE # 合并后是否删除原列通常为TRUE )实操心得separate()和unite()的sep参数90%情况用字符分隔符如-、_但10%场景需正则——比如地址列北京市_朝阳区_建国路8号想按_拆但朝阳区_建国路8号里也有_此时应改用sep _(?[^_]*$)只匹配最后一个_或更稳妥地用extract()配合捕获组。2.4extract()用正则精准捕获复杂模式当分隔符不固定或需提取特定片段时extract()是终极武器。例如日志中的IP地址端口混合字段192.168.1.100:8080需分离IP和端口df_log - tibble(ip_port c(192.168.1.100:8080, 10.0.0.5:3306)) df_extracted - df_log %% extract( col ip_port, into c(ip, port), regex ^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}):(\\d)$ )正则regex参数是难点但也是可控点^和$锚定首尾避免部分匹配\\d{1,3}匹配1–3位数字IP段范围0–255需业务层校验\\.转义点号非任意字符括号()定义捕获组顺序对应into参数。我建议新手先用在线正则测试工具如regex101.com验证模式再粘贴到R中。曾因忘记转义.导致192.168.1.100:8080被错误拆成1921681100和8080排查许久才发现。3. 那些tidyr不干的活识别边界避免误用陷阱tidyr强大但绝非万能。很多初学者试图用它解决本该由其他工具处理的问题结果事倍功半甚至引入新错误。明确它的能力边界是高效使用的前提。3.1 不处理缺失值语义——那是dplyr和naniar的事tidyr的drop_na()只是机械删除含NA的行它不关心“这个NA代表未填写、还是设备故障、还是隐私屏蔽”。真正的缺失值分析需结合业务逻辑用dplyr::case_when()标记缺失原因用naniar::gg_miss_upset()可视化缺失模式用mice::mice()进行多重插补。曾有个某实验室的传感器数据项目温度列大量NA。直接drop_na()会删掉70%数据。后来发现NA集中出现在雨天而雨天湿度列有值——于是用mutate(temp_imputed ifelse(is.na(temp) !is.na(humidity), humidity * 0.8 15, temp))做业务规则插补效果远超简单删除。提示tidyr::replace_na()仅用于统一替换为指定值如replace_na(list(score 0))绝不用于“智能填充”。它的角色是预处理不是分析。3.2 不解析嵌套JSON/XML——那是jsonlite和xml2的领域当数据列中存着JSON字符串{name:张三,city:北京}separate()无法安全解析。错误做法# ❌ 危险字符串分割会破坏JSON结构 df_bad - df_json %% separate(json_col, into c(name_part, city_part), sep )正确路径是用jsonlite::fromJSON()将字符串转为列表列用tidyr::unnest()展开嵌套结构。library(jsonlite) df_json - tibble(id 1:2, json_str c({name:张三,city:北京}, {name:李四,city:上海})) df_parsed - df_json %% mutate(json_data map(json_str, fromJSON)) %% # 转为列表列 unnest(json_data) # 展开为多列unnest()在此处是tidyr的延伸能力但它依赖上游已解析为列表结构。混淆“字符串分割”和“结构化解析”是JSON数据整理中最常见失误。3.3 不处理时间格式标准化——那是lubridate的专长separate()可把2023-05-15 14:30:00拆成日期和时间两列但无法将15/May/2023、2023年5月15日、20230515统一转为POSIXct。必须用lubridate::parse_date_time()library(lubridate) df_time - tibble(raw_date c(15/May/2023, 2023年5月15日, 20230515)) df_time_parsed - df_time %% mutate( date_parsed parse_date_time( raw_date, orders c(dmy, ymd, Ymd), # 尝试多种格式 locale Chinese # 中文环境适配 ) )tidyr只管结构不管语义。时间语义的归一化必须交由专业时间处理包。3.4 不校验数据一致性——那是validate和assertr的职责pivot_longer()不会告诉你subject列里混进了maths英式拼写和math美式也不会检查score是否超出0–100范围。数据质量保障需额外步骤library(validate) library(assertr) # 定义校验规则 rules - validator( subject %in% c(math, eng, sci), # 允许值约束 score 0 score 100 # 数值范围 ) # 执行校验 confront(df_long, rules) %% summary() # 输出违规行号和原因tidyr输出的是“结构正确”的数据但不保证“内容正确”。把校验嵌入tidyverse流程是生产环境必备实践。4. 从零构建一个真实整理流水线某电商用户行为日志实战理论终需落地。下面以某电商后台导出的用户行为日志为案例完整演示tidyr在真实场景中的组合应用。原始数据CSV包含以下典型问题event_type列混有click_product、add_to_cart、purchase_success等需标准化event_detail列存JSON字符串含商品ID、价格、分类等timestamp格式混乱2023-05-15T14:30:00Z、15/05/2023 14:30、2023年5月15日 14:30:00user_profile列是age:25|city:北京|gender:male格式需拆解部分行event_detail为空但event_type为purchase_success属数据矛盾。我们目标是产出一张标准表每行一个事件含user_id、event_type标准化、product_id、price、category、timestamp统一POSIXct、age、city、gender。4.1 步骤一加载与初步清洗library(readr) library(dplyr) library(tidyr) library(jsonlite) library(lubridate) # 加载原始数据跳过空行和注释 df_raw - read_csv(user_events.csv, skip 1, # 跳过首行说明 na c(, NULL, N/A)) # 显式声明缺失值标识 # 删除完全空行 df_clean - df_raw %% drop_na(everything()) %% # 标准化event_type统一小写去空格映射别名 mutate( event_type str_to_lower(str_trim(event_type)), event_type case_when( event_type %in% c(click_product, product_click) ~ click, event_type %in% c(add_to_cart, cart_add) ~ add_to_cart, event_type purchase_success ~ purchase, TRUE ~ other ) )此处case_when()已开始介入体现tidyr与dplyr的天然协同——tidyr负责结构变形dplyr负责内容转换。4.2 步骤二解析JSON详情与用户档案# 解析event_detail JSON df_parsed - df_clean %% # 处理空JSON字符串避免fromJSON报错 mutate( event_detail ifelse(is.na(event_detail) | event_detail , {product_id:null,price:null,category:null}, event_detail) ) %% # 转为列表列 mutate(event_json map(event_detail, fromJSON)) %% # 展开JSON字段 unnest(event_json, names_repair ~str_replace(.x, ^, detail_)) # 防止列名冲突 # 解析user_profile用separate因分隔符固定 df_profile - df_parsed %% separate( col user_profile, into c(age_str, city_str, gender_str), sep \\|, # \|转义竖线 extra merge, fill right ) %% # 提取键值对如age:25→25 mutate( age as.numeric(str_extract(age_str, \\d)), city str_extract(city_str, (?:).*$), gender str_extract(gender_str, (?:).*$) ) %% # 清理中间列 select(-age_str, -city_str, -gender_str)注意names_repair参数当JSON字段名与现有列名如user_id冲突时自动加前缀避免覆盖。这是unnest()的实用技巧。4.3 步骤三时间戳标准化与最终整合# 时间解析尝试多种格式 df_final - df_profile %% mutate( timestamp_parsed parse_date_time( timestamp, orders c(ymd_HMS, dmy_HM, Y/m/d H:M:S, ymd HMS), locale Chinese, truncated 2 # 允许缺失秒 ) ) %% # 移除原始timestamp列重命名解析后列 rename(timestamp timestamp_parsed) %% # 选择最终需要的列 select( user_id, event_type, detail_product_id, detail_price, detail_category, timestamp, age, city, gender ) %% # 重命名列名使其语义清晰 rename( product_id detail_product_id, price detail_price, category detail_category ) # 查看结果 glimpse(df_final)4.4 步骤四质量检查与异常处理# 检查purchase事件是否都有product_id purchase_missing - df_final %% filter(event_type purchase is.na(product_id)) if (nrow(purchase_missing) 0) { warning(发现, nrow(purchase_missing), 条purchase事件缺失product_id已标记为invalid) df_final - df_final %% mutate( event_type ifelse(event_type purchase is.na(product_id), purchase_invalid, event_type) ) } # 检查price是否全为数值 df_final - df_final %% mutate(price as.numeric(as.character(price))) %% # 强制转数值失败则NA filter(!is.na(price)) # 删除price无法解析的行这个流水线不是一次写成而是经过三次迭代第一次运行发现parse_date_time()失败率高加入truncated 2第二次发现purchase事件product_id缺失增加业务规则标记第三次发现price列含¥199字符串追加str_remove(¥)预处理。真实的数据整理永远是“写代码→跑→报错→分析→改代码→再跑”的循环。我的个人体会每次整理项目结束我都会把df_final的glimpse()输出和关键count()结果存为Markdown片段附在脚本末尾。半年后回看能立刻知道当时解决了什么问题、数据质量如何。这比任何文档都可靠。5. 性能优化与大规模数据策略当tidyr遇上百万行tidyr默认基于data.frame和tibble对百万级数据可能变慢。但优化并非抛弃它而是理解其瓶颈并组合方案。5.1 瓶颈定位pivot_longer()和unnest()是主要耗时点用bench::mark()测试不同规模数据library(bench) # 生成测试数据 set.seed(123) df_test - tibble( id 1:10000, a rnorm(10000), b rnorm(10000), c rnorm(10000) ) # 测试pivot_longer bm - mark( pivot_longer(df_test, cols a:c, names_to var, values_to val), iterations 5, time_unit ms ) print(bm)结果显示10k行耗时约15ms100k行约150ms1000k行约1.5s——基本线性增长。但若cols参数选择不当如用matches(.*)而非明确列名性能下降5–10倍。5.2 优化策略一列选择精准化避免cols everything()或宽泛正则。明确指定列名向量# ✅ 快速明确列名 pivot_longer(df, cols c(col_a, col_b, col_c), ...) # ❌ 缓慢全表扫描 pivot_longer(df, cols matches(col_), ...)5.3 优化策略二大JSON用vroom预解析对含大量JSON的列map(fromJSON)在循环中解析效率低。改用vroom::vroom()配合jsonlite::stream_in()# 对超大JSON列先保存为临时JSON行文件 write_lines(df_raw$event_detail, temp_events.json) # 用vroom高速读取并解析 df_json_fast - vroom::vroom(temp_events.json, col_types cols(.default c)) %% mutate(data map(x, fromJSON))5.4 优化策略三切换至data.table后端dtplyr对千万级数据dtplyr提供data.table加速的dplyr语法library(dtplyr) # 将tibble转为lazy_dt df_lazy - lazy_dt(df_huge) # 后续dplyr/tidyr操作自动编译为data.table df_processed - df_lazy %% mutate(event_type str_to_lower(event_type)) %% filter(!is.na(event_type)) %% collect() # 最终转回tibbledtplyr不改变代码风格却带来数量级性能提升。我在某公司处理2000万行日志时dtplyr将整理时间从47分钟降至3.2分钟。5.5 优化策略四分块处理与并行对超大数据集furrr::future_map()实现并行解析library(furrr) plan(multisession, workers 4) # 启用4核 df_chunks - df_huge %% group_by(chunk_id ceiling(row_number() / 10000)) %% group_split() df_processed_list - future_map(df_chunks, ~{ .x %% mutate(event_json map(event_detail, fromJSON)) %% unnest(event_json) }) df_final - bind_rows(df_processed_list)分块大小需权衡太小则调度开销大太大则内存溢出。我的经验值是1–5万行/块。最后分享一个血泪教训某次处理1.2亿行数据未分块直接unnest()R进程吃光32GB内存后崩溃。重启后改用分块gc()手动回收全程耗时22分钟——比预期多10分钟但至少完成了。数据整理的第一守则宁可慢不可崩。

相关新闻

特征值与特征向量:从几何重数到代数重数,拆解矩阵的灵魂

特征值与特征向量:从几何重数到代数重数,拆解矩阵的灵魂

先问一个问题:你拿到一个矩阵,是不是下意识就想去算行列式、算秩、解方程组?这些操作当然没错,但它们更像“体检报告”——告诉你矩阵健康不健康。而真正决定一个矩阵“性格”的,是特征值与特征向量。这俩东西才是矩阵…

2026/10/14 0:33:52 阅读更多 →
逻辑回归向量化:从循环到矩阵运算的性能飞跃

逻辑回归向量化:从循环到矩阵运算的性能飞跃

1. 从单样本循环到矩阵运算:为什么必须做向量化逻辑回归的模型训练,绕不开两个核心计算:假设函数输出和梯度更新。很多刚上手的朋友在实现逻辑回归时,第一反应就是写一个for循环,逐个样本计算预测值,再逐个…

2026/10/14 0:33:52 阅读更多 →
微信小程序原生课程表源码:本地存储与离线渲染实战

微信小程序原生课程表源码:本地存储与离线渲染实战

简介:这份资源是面向微信小程序初学者与前端练手者的原生课程表项目源码,基于微信小程序原生框架实现,可帮助读者快速理解并搭建一个查看、管理每周课程安排的应用,适合学生、教师及想通过完整小项目巩固基础的前端学习者。压缩包…

2026/10/14 0:33:52 阅读更多 →

最新新闻

Kafka 生产环境分区热点倾斜治理:基于 Key 加盐与动态再均衡的高并发解法

Kafka 生产环境分区热点倾斜治理:基于 Key 加盐与动态再均衡的高并发解法

在每年双 11 的大促峰值期,许多负责消息中间件保障的架构师都会遇到一个极具迷惑性的“假象报警”: 打开 Kafka 全局监控大盘,集群整体的 CPU 利用率仅仅只有 35%,网络入网总带宽距离物理网卡上限还有一半以上的富余,看…

2026/10/14 1:23:07 阅读更多 →
算法岗实习面试全攻略:字节、PayPal、寒武纪等五家大厂面经与避坑指南

算法岗实习面试全攻略:字节、PayPal、寒武纪等五家大厂面经与避坑指南

/* 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 1:23:07 阅读更多 →
单端口与双端口RAM实现指南:Verilog代码、时序与综合推断

单端口与双端口RAM实现指南:Verilog代码、时序与综合推断

/* 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 1:23:07 阅读更多 →
Java 24 作用域值(Scoped Values)实战:彻底淘汰 ThreadLocal 消除内存泄露

Java 24 作用域值(Scoped Values)实战:彻底淘汰 ThreadLocal 消除内存泄露

在 Java 企业级服务端研发领域,ThreadLocal 无疑是陪伴了大家二十余年的“老朋友”。无论是 Spring 的事务管理器、Logback 的 MDC 链路追踪上下文、还是微服务网关透传的当前登录用户信息,几乎全部依托 ThreadLocal 在线程私有存储中穿针引线。 然而&am…

2026/10/14 1:23:07 阅读更多 →
跨机房专线延迟下的数据双写冲突消解:分布式逻辑时钟与 LWW 策略实战

跨机房专线延迟下的数据双写冲突消解:分布式逻辑时钟与 LWW 策略实战

在三地五中心的单元化异地多活架构中,最令架构师头疼的技术挑战,永远是打破了“单一机房封闭”的跨地域共享数据双写。 虽然我们在设计上极力强调“按用户维度做单元封闭(Cell Isolation)”,但在真实的电商与金融生态中…

2026/10/14 1:23:07 阅读更多 →
Unity AssetBundle标签策略:功能模块化vs资源类型化

Unity AssetBundle标签策略:功能模块化vs资源类型化

/* 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 1:22:07 阅读更多 →

日新闻

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