You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 14:36:02