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

使用R的httr调用Twitter API v2获取推文失败求助

问题排查与修复方案

1. 核心问题:变量作用域导致数据无法写入全局列表

你的process_response和process_success函数中,对all_tweets的赋值属于局部变量赋值,不会修改全局环境中的all_tweets列表。在R中,函数内部要修改全局变量必须使用<<-运算符。

修复方法:
修改两个函数中的赋值语句:

# 在process_response中
all_tweets[[competitor]] <<- tibble()

# 在process_success中
all_tweets[[competitor]] <<- tweets_data
all_tweets[[competitor]] <<- tibble()

2. 增加错误调试信息,定位API响应问题

当前代码仅判断HTTP状态类别,无法获取API返回的具体错误详情。建议在process_response中添加调试输出:

process_response <- function(response, competitor) {
  # 打印状态码和响应内容,方便排查
  cat("Competitor:", competitor, "Status Code:", response$status_code, "\n")
  if (http_status(response)$category != "success") {
    print(content(response))
    message("Failed to fetch tweets for ", competitor)
    all_tweets[[competitor]] <<- tibble()
  } else {
    process_success(response, competitor)
  }
}

通过这些输出可以快速定位具体问题,比如:

  • 权限不足(即使拥有付费权限,可能未开通recent search访问权限)
  • Query参数格式错误
  • Token读取失败(环境变量未正确配置)

3. 验证Bearer Token的读取正确性

确认Sys.getenv("TWITTER_BEARER_TOKEN")确实读取到有效Token,可在代码开头添加:

bearer_token <- Sys.getenv("TWITTER_BEARER_TOKEN")
cat("Bearer Token length:", nchar(bearer_token), "\n") # 应为非空的长字符串

4. 优化API请求参数

  • tweet.fields中text和author_id是默认返回字段,无需重复指定,仅保留public_metrics即可
  • 确认max_results在API允许范围内(付费版最多1000,你的10是合法值)

修改后的参数列表:

params <- list(
  'query' = paste(competitor, "lang:en"),
  'max_results' = '10',
  'tweet.fields' = 'public_metrics',
  'expansions' = 'author_id',
  'user.fields' = 'username,verified'
)

5. 修复用户信息匹配逻辑

原代码中查找用户的方式效率低且易出错,改用dplyr关联更可靠:

compile_tweets_data <- function(content_list) {
  # 将用户数据转为tibble
  users_df <- tibble(
    AuthorID = map_chr(content_list$includes$users, ~.x$id),
    Username = map_chr(content_list$includes$users, ~.x$username),
    Verified = map_lgl(content_list$includes$users, ~.x$verified)
  )
  
  # 构造推文数据后关联用户信息
  tweets_df <- map_df(content_list$data, ~tibble(
    Text = .x$text,
    AuthorID = .x$author_id,
    Likes = .x$public_metrics$like_count,
    Retweets = .x$public_metrics$retweet_count,
    Replies = .x$public_metrics$reply_count
  ))
  
  left_join(tweets_df, users_df, by = "AuthorID")
}

完整修复后的代码示例

# Load necessary libraries
library(httr)
library(tidyverse)

bearer_token <- Sys.getenv("TWITTER_BEARER_TOKEN")
cat("Bearer Token length:", nchar(bearer_token), "\n")

# Twitter API v2 endpoint for searching tweets
endpoint_url <- "https://api.twitter.com/2/tweets/search/recent"

# List of competitors
competitors <- c("nespresso", "keurig", "tassimo", "sage", "breville", "senseo")

# Initialize a list to hold data for all competitors
all_tweets <- list()

# Function to compile tweets data
compile_tweets_data <- function(content_list) {
  users_df <- tibble(
    AuthorID = map_chr(content_list$includes$users, ~.x$id),
    Username = map_chr(content_list$includes$users, ~.x$username),
    Verified = map_lgl(content_list$includes$users, ~.x$verified)
  )
  
  tweets_df <- map_df(content_list$data, ~tibble(
    Text = .x$text,
    AuthorID = .x$author_id,
    Likes = .x$public_metrics$like_count,
    Retweets = .x$public_metrics$retweet_count,
    Replies = .x$public_metrics$reply_count
  ))
  
  left_join(tweets_df, users_df, by = "AuthorID")
}

# Functions to process API responses
process_response <- function(response, competitor) {
  cat("Competitor:", competitor, "Status Code:", response$status_code, "\n")
  if (http_status(response)$category != "success") {
    print(content(response))
    message("Failed to fetch tweets for ", competitor)
    all_tweets[[competitor]] <<- tibble()
  } else {
    process_success(response, competitor)
  }
}

process_success <- function(response, competitor) {
  content_list <- content(response, as = "parsed", type = "application/json")
  
  if (!is.null(content_list$data)) {
    tweets_data <- compile_tweets_data(content_list)
    all_tweets[[competitor]] <<- tweets_data
  } else {
    message("No tweets found for ", competitor)
    all_tweets[[competitor]] <<- tibble()
  }
}

for (competitor in competitors) {
  # Construct the query parameters with additional fields
  params <- list(
    'query' = paste(competitor, "lang:en"),
    'max_results' = '10',
    'tweet.fields' = 'public_metrics',
    'expansions' = 'author_id',
    'user.fields' = 'username,verified'
  )
  
  # Make the GET request to the Twitter API
  response <- GET(url = endpoint_url, add_headers(Authorization = paste("Bearer", bearer_token)), query = params)
  
  # Process the response
  process_response(response, competitor)
}

# Combine all tweets into a single tibble
all_tweets_combined <- bind_rows(all_tweets, .id = "Competitor")

# Print result
print(all_tweets_combined)

内容的提问来源于stack exchange,提问作者Display name:匿名用户

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 16:57:21