如何用Pushshift API提取Reddit指定帖子的全部评论?
问题与解答
问题描述
我正在使用Reddit的Pushshift API,目前已掌握如何提取特定时间段内含“covid”关键词的评论,示例请求为https://api.pushshift.io/reddit/search/comment?q=covid&after=3h&before=2h&size=1。现在我想提取某篇含“covid”评论的帖子的全部评论(无论是否含该关键词),已知该帖子的link_id为t3_116l7ct,但尝试请求https://api.pushshift.io/reddit/comment/search/?link_id=t3_116cjib后得到空结果。请问是否可行?能否采用两阶段方案:先定位含目标关键词评论的帖子,再提取该帖子所有评论?另外,能否修改我现有的R脚本实现该需求?
现有R脚本:
library(jsonlite) part1 = "https://api.pushshift.io/reddit/search/comment/?q=trump&after=" part2 = "h&before=" part3 = "h&size=500" results = list() for (i in 1:10) {tryCatch({ { url_i<- paste0(part1, i+1, part2, i, part3) r_i <- fromJSON(url_i) results[[i]] <- data.frame(r_i$data$body , r_i$data$id, r_i$data$parent_id, r_i$data$link_id) #myvec_i <- sapply(results, NROW) #print(c(i, sum(myvec_i))) print(i) #ifelse(i %% 200 == 0, saveRDS(results, "results_index.RDS"), "" ) } }, error = function(e){}) } final = do.call(rbind.data.frame, results)
解答
1. 可行性说明
通过Pushshift API提取指定帖子的全部评论是可行的。你请求返回空结果可能有以下原因:
- 帖子的
link_id输入错误(你示例里用的t3_116cjib和提到的t3_116l7ct不一致) - 该帖子的评论未被Pushshift索引(部分较新或极旧的内容可能未收录)
- API请求参数格式有误(比如多余的问号,正确的路径是
/reddit/comment/search而非/reddit/comment/search/?)
2. 两阶段方案完全可行
流程清晰明确:
- 阶段1:搜索含目标关键词(如“covid”)的评论,提取这些评论对应的
link_id(即所属帖子的唯一标识) - 阶段2:针对每个
link_id,调用API提取该帖子下的所有评论,不受关键词限制
3. 修改后的R脚本
以下是实现两阶段需求的优化版脚本,包含分页逻辑(适配API单请求size上限1000)和错误处理:
library(jsonlite) # 阶段1:搜索含指定关键词的评论,获取对应帖子的link_id get_target_post_ids <- function(keyword, time_window_hours = 24, max_results = 500) { base_url <- "https://api.pushshift.io/reddit/search/comment" after_param <- paste0(time_window_hours, "h") request_url <- paste0(base_url, "?q=", URLencode(keyword), "&after=", after_param, "&size=", max_results) tryCatch({ api_response <- fromJSON(request_url) if (!is.null(api_response$data)) { # 去重得到唯一的帖子ID列表 unique(api_response$data$link_id) } else { character(0) } }, error = function(e) { message("阶段1请求出错: ", e$message) character(0) }) } # 阶段2:根据帖子link_id提取该帖子的所有评论(分页获取) get_all_post_comments <- function(link_id) { base_url <- "https://api.pushshift.io/reddit/comment/search" comment_list <- list() last_timestamp <- NULL page_num <- 1 repeat { # 构建分页请求URL request_params <- paste0("?link_id=", link_id, "&size=1000") if (!is.null(last_timestamp)) { request_params <- paste0(request_params, "&before=", last_timestamp) } request_url <- paste0(base_url, request_params) tryCatch({ api_response <- fromJSON(request_url) if (length(api_response$data) == 0) break # 转换为结构化数据框 comment_df <- data.frame( body = api_response$data$body, comment_id = api_response$data$id, parent_id = api_response$data$parent_id, link_id = api_response$data$link_id, created_time = api_response$data$created_utc, stringsAsFactors = FALSE ) comment_list[[page_num]] <- comment_df # 更新分页标记,获取更早的评论 last_timestamp <- min(comment_df$created_time) page_num <- page_num + 1 message("已获取第", page_num-1, "页评论,共", nrow(comment_df), "条") }, error = function(e) { message("阶段2请求出错: ", e$message) break }) } # 合并所有分页结果 if (length(comment_list) > 0) { do.call(rbind, comment_list) } else { data.frame() } } # 主执行流程 # 1. 获取含"covid"评论的帖子ID列表 target_post_ids <- get_target_post_ids("covid", time_window_hours = 24) if (length(target_post_ids) == 0) { stop("未找到含目标关键词的帖子") } message("找到", length(target_post_ids), "个目标帖子") # 2. 批量提取每个帖子的所有评论 all_comments_list <- list() for (idx in seq_along(target_post_ids)) { current_post_id <- target_post_ids[idx] message("正在提取帖子", current_post_id, "的评论...") post_comments <- get_all_post_comments(current_post_id) all_comments_list[[idx]] <- post_comments } # 合并最终结果并保存 final_result <- do.call(rbind, all_comments_list) saveRDS(final_result, "reddit_covid_post_comments.RDS") message("所有评论提取完成,共", nrow(final_result), "条数据已保存")
脚本亮点
- 拆分功能为独立函数,逻辑清晰易维护
- 自动处理API分页限制,确保获取全量评论
- 增加错误捕获机制,单个请求失败不会中断整个流程
- 实时进度提示,方便监控提取状态
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

