Twitter速率限制变为NULL导致R tweetscores包循环自终止解决方案问询
问题根源
中断由tweetscores包getFriends()函数的缺陷导致:源码第47行读取Twitter API返回头的剩余请求次数字段时未做空值校验,当API返回头异常丢失x-rate-limit-remaining字段时,存储剩余调用次数的变量会变为NULL,后续remaining > 0的比较逻辑直接抛出错误,触发循环中断。
可用解决方案
- 方案1:替换为修复版
getFriends()函数
无需修改已安装的包源码,直接在你的代码中定义以下修复版函数,将原有调用getFriends()的位置替换为getFriends_fixed()即可:
# 修复空值异常的getFriends版本 getFriends_fixed <- function(screen_name, oauth, cursor = -1, user_id = NULL, verbose = TRUE){ require(httr) remaining <- 15 all_friends <- c() while (cursor != 0){ if (remaining < 2){ if (verbose) message("触达API速率限制,等待15分钟后继续...") Sys.sleep(900) remaining <- 15 } url <- "https://api.twitter.com/1.1/friends/ids.json" params <- if (!is.null(user_id)) { list(user_id = user_id, cursor = cursor, stringify_ids = TRUE) } else { list(screen_name = screen_name, cursor = cursor, stringify_ids = TRUE) } r <- GET(url, query = params, config(token = oauth)) # 补充空值校验逻辑 remaining_raw <- headers(r)$`x-rate-limit-remaining` remaining <- if (is.null(remaining_raw) || is.na(as.numeric(remaining_raw))) { 0 } else { as.numeric(remaining_raw) } if (r$status_code != 200) stop(paste0("API请求错误,状态码:", r$status_code)) resp <- content(r, as = "parsed") cursor <- resp$next_cursor_str all_friends <- c(all_friends, unlist(resp$ids)) if (verbose && cursor != "0") message(paste0("已获取", length(all_friends), "个关注账号,继续拉取")) Sys.sleep(1) } return(all_friends) }
- 方案2:优化外层循环重试逻辑
如果不想修改函数逻辑,可直接优化外层循环的错误捕获规则,遇到异常先等待再重试当前用户,而非直接跳过:
for(user in usernames$user_screen_name){ retry_cnt <- 0 max_retry <- 3 success_flag <- FALSE while(retry_cnt < max_retry && !success_flag){ tryCatch({ friends <- getFriends(screen_name=user, oauth=my_oauth) results <- estimateIdeology2(user, friends) success_flag <- TRUE }, error = function(e){ message(paste0("用户", user, "拉取失败,15分钟后重试,错误:", e$message)) Sys.sleep(900) retry_cnt <<- retry_cnt + 1 }) } if (!success_flag) { message(paste0("用户", user, "多次重试失败,跳过")) next } user_scores <- rbind(user_scores, data.frame( screen_name = user, ideology_score = results )) print("用户得分计算完成") }
额外优化建议
提前按用户名总量初始化user_scores数据框,不要每次循环追加行,可大幅提升运行效率,避免行结构不匹配报错。
内容的提问来源于stack exchange,提问作者Pearlharborrules
相关产品推荐
相关产品推荐

