R语言Rtweet包循环调用get_timeline提取推文时间线失败问题
问题根因
你的代码跑不通和字符串格式有部分关系,但核心是3个写法错误:
- 循环入参完全传错:
for (i in 1:nrow(...))里的i是1、2、3……的整数行索引,你直接把i传给get_timeline(),相当于请求推特ID为1、2、3的账号,和数据框里存的用户名没有关联,自然拿不到目标结果。 - 带空格的列名没有正确引用:你的数据框列名是
tw usernames,R默认把空格当代码分隔符,不做特殊处理根本读不到这一列的值。 - 用户名存储格式不符合接口要求:你列里存的值有两类问题:部分带
@前缀,部分带空格(比如'John Doe'),而get_timeline()要求传入的用户名是不带@、无空格的纯账号handle,你手动调用能成功,是因为你传的是去掉空格的'JohnDoe',和数据框里存的原始值格式不一致。
实现方案
完全不需要额外循环拉取数值型用户ID,把用户名清洗到位后,不管是直接批量传参还是写循环都能正常跑,额外拉ID属于冗余操作,还容易触发接口限流。
方案1:零循环最简写法
get_timeline()原生支持传入用户名向量做批量请求,不需要自己写循环,运行效率更高:
library(rtweet) # 第一步:清洗原始用户名,去掉开头的@、去掉所有空格 # 注意带空格的列名要用反引号包裹才能正确读取 user_df$clean_handle <- gsub(pattern = "^@|\\s+", replacement = "", x = user_df$`tw usernames`) # 第二步:直接传入清洗后的用户名向量,一次性拉取所有用户的20条推文 all_timelines <- get_timeline( user = user_df$clean_handle, n = 20, token = NULL )
返回结果自带screen_name、user_id字段,可以直接区分不同用户的推文数据。
方案2:修正后的for循环写法
如果需要自定义请求逻辑(比如加间隔防限流、给每个用户的结果加备注),可以用修正后的循环写法,注意不要直接传循环索引,要通过索引取对应位置的用户名:
# 提前初始化等长列表存储结果,避免循环中动态扩容拖慢速度 timelines <- vector(mode = "list", length = nrow(user_df)) for (i in seq_along(timelines)) { timelines[[i]] <- get_timeline( user = user_df$clean_handle[i], n = 20, token = NULL ) # 加2秒请求间隔,避免短时间请求太多触发接口限流 Sys.sleep(2) } # 把列表里的多个数据框合并成一个完整数据框 all_timelines <- do.call(rbind, timelines)
注意:如果数据框行数为0,用1:nrow()会生成1:0的错误索引导致循环跑飞,用seq_along()可以规避这个问题。
内容的提问来源于stack exchange,提问作者Juan de Dios Fernandez
相关产品推荐
相关产品推荐

