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

如何修改R代码提取Reddit帖子全部评论并获取完整JSON?

解决Reddit帖子评论提取不全的问题

问题描述

我需要提取某Reddit帖子的全部评论,原代码仅能获取37条评论,但实际帖子有超过1000条评论。原代码及更新后的尝试如下:

原代码:

library(jsonlite)
library(purrr)
library(dplyr)
library(tidyr)

URL  <- "https://www.reddit.com/r/FunnyandSad/comments/112yfey/really_surprised_how_this_didnt_become_a_big_news/.json"

results = fromJSON(URL) |>
  pluck("data", "children") |> 
  bind_rows() |>
  filter(row_number() > 1) |>
  unnest(data) |>
  select(id, author, body) |>
  mutate(comment_id = row_number(), .before = "id")

运行后仅得到37条评论:

> dim(results)
[1] 37  4

更新后尝试用read_json:

results = read_json(URL)

body_list <- list()
for (i in seq_along(results[[2]]$data$children)) {
    body <- results[[2]]$data$children[[i]]$data$body
    body_list[[i]] <- body
}

仍仅返回36条评论。


问题原因

Reddit的公开JSON接口默认只返回第一页的顶级评论(约25-50条),剩余评论需要通过分页参数after迭代获取;同时原代码未处理嵌套子评论,而帖子中的大量评论属于子评论层级。另外,Reddit会限制未设置User-Agent的请求,可能导致部分内容无法获取。


解决方案

1. 设置合法请求头(User-Agent)

Reddit要求请求必须包含User-Agent字段,否则可能被限流或返回不完整数据,需在请求中添加该字段。

2. 循环分页获取所有顶级评论

每次请求后,从响应中提取data$after字段,作为下一次请求的after参数,直到after为NULL(表示没有更多内容)。

3. 递归提取嵌套子评论

每条顶级评论的data$replies字段中包含其子评论,需要递归遍历所有层级的子评论。


完整代码示例

library(jsonlite)
library(dplyr)
library(purrr)

# 定义请求URL和请求头
base_url <- "https://www.reddit.com/r/FunnyandSad/comments/112yfey/really_surprised_how_this_didnt_become_a_big_news/.json"
headers <- c("User-Agent" = "R script for comment scraping (by u/your_username)")

# 递归提取所有层级的评论(包括子评论)
extract_comments <- function(comment_data) {
  # 提取当前层级的评论
  current_comments <- comment_data |>
    map_dfr(~{
      data <- .x$data
      tibble(
        id = data$id,
        author = data$author,
        body = data$body,
        parent_id = data$parent_id,
        depth = data$depth
      )
    })
  
  # 提取子评论并递归处理
  child_comments <- comment_data |>
    map(~.x$data$replies) |>
    keep(~!is.null(.x)) |>
    map(~.x$data$children) |>
    map_dfr(extract_comments)
  
  # 合并当前评论和子评论
  bind_rows(current_comments, child_comments)
}

# 循环分页获取所有评论
all_comments <- tibble()
after <- NULL

while(TRUE) {
  # 构建带分页参数的URL
  request_url <- if(is.null(after)) {
    base_url
  } else {
    paste0(base_url, "?after=", after)
  }
  
  # 发送请求
  response <- fromJSON(request_url, headers = headers)
  
  # 提取评论部分(response[[2]]是评论区数据)
  comment_children <- response[[2]]$data$children
  
  # 如果没有更多评论,退出循环
  if(length(comment_children) == 0) break
  
  # 提取当前页的所有评论(包括子评论)
  page_comments <- extract_comments(comment_children)
  
  # 合并到总结果
  all_comments <- bind_rows(all_comments, page_comments)
  
  # 更新after参数,用于下一页请求
  after <- response[[2]]$data$after
  
  # 如果after为NULL,说明没有更多内容
  if(is.null(after)) break
  
  # 加个延迟,避免触发Reddit限流
  Sys.sleep(2)
}

# 查看结果
dim(all_comments)
head(all_comments)

说明

  • User-Agent需要替换为你自己的标识(比如你的Reddit用户名),避免被Reddit判定为恶意请求。
  • Sys.sleep(2)是为了在请求之间添加延迟,遵守Reddit的API速率限制,避免频繁请求被封禁。
  • extract_comments函数会递归遍历所有子评论层级,确保获取到帖子中的所有评论。

内容的提问来源于stack exchange,提问作者stats_noob

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:06:35