mcpField
R
reddit-fetch

reddit-fetch

github.com/ykdojo生产力10.3k382 次安装5 周前更新
代码仓库

关于 reddit-fetch

Reddit Fetch 是通过 Playwright 获取 Reddit 列表、帖子和评论的工作流程。它先借助 DuckDuckGo 跳转建立会话,再读取 Reddit JSON,并提供页面抓取等备用方式。

主要功能

  1. 01通过 DuckDuckGo 跳转建立会话
  2. 02使用 Playwright 获取 Reddit JSON
  3. 03读取列表、帖子和评论
  4. 04从页面抓取更多评论
  5. 05应对访问受阻的备用方式
  6. 06按顺序请求以避开速率限制

适用场景

  1. 01收集 Subreddit 的近期搜索结果
  2. 02读取帖子及其评论树
  3. 03获取超出 JSON 限额的评论
  4. 04在 Reddit 阻止直连时恢复访问

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ykdojo/claude-code-tips --skill reddit-fetch

安装后在 Claude Code 中输入/reddit-fetch确认已加载。

详细介绍

Reddit 抓取

Reddit 的公开 JSON API 只需在任意 Reddit URL 后追加 .json 即可使用,但 Reddit 现在会硬性阻止自动化访问。**curl 几乎每次都会返回 403(无论是在主机还是容器中,也无论 User-Agent 是什么),甚至冷启动后使用 Playwright 导航到 reddit.com,也会遇到 "You've been blocked by network security" 挑战页面。**可靠的方法是通过 DuckDuckGo 搜索结果重定向进入 Reddit:这会设置 Reddit 会话 Cookie,从而在本次浏览器会话期间解锁直接访问 .json。

主要方法:通过 DuckDuckGo 跳转解锁

**步骤 1 - 跳转至 DDG。**每次会话中,在获取任何 .json 内容之前执行一次。

  1. 使用 mcp__playwright__browser_navigate 导航到 https://html.duckduckgo.com/html/?q=site:reddit.com/r/SUBREDDIT+YOUR+QUERY
  2. 获取第一个结果的完整 href——这是一个包含 rut 令牌的 DDG 重定向链接(https://duckduckgo.com/l/?uddg=...&rut=...)。该令牌是必需的;导航到不带令牌的 /l/?uddg= 会返回 400。
    () => document.querySelector('.result__a')?.href
    
  3. 使用 browser_navigate 导航到该完整重定向 href。它会跳转到真实的 www.reddit.com 页面(标题 = 帖子或子版块标题,而不是“Blocked”),并设置会话 Cookie。搜索结果不必是你要找的确切帖子——只要跳转到任意真实的 Reddit 页面,就能设置 Cookie。

如果 Playwright 报错 Browser is already in use,说明有过期实例占用了配置文件——运行 pkill -f ms-playwright-mcp(或错误信息中列出的配置文件目录),然后重试。

**步骤 2 - 现在可以直接访问 .json。**在本次会话的剩余时间内,直接使用 Playwright 导航到任意 .json URL,并运行 JSON.parse(document.body.innerText)。浏览器导航时使用 www.reddit.com(不要用 old.reddit.com)。可使用完整的最新排序方式(sort=new&t=week)。

  1. 使用 browser_navigate 导航到例如 https://www.reddit.com/r/SUBREDDIT/search.json?q=QUERY&restrict_sr=on&sort=new&t=week&limit=25
  2. 运行 browser_evaluate,务必用 try/catch 包裹(失败时返回 document.body.innerText.slice(0,200),以便查看是否出现挑战页面;如果会话已失效,只需重新执行跳转):
    () => {
      try {
        const data = JSON.parse(document.body.innerText);
        return data.data.children.map(c => ({
          t: c.data.title, s: c.data.score, n: c.data.num_comments, id: c.data.id
        }));
      } catch (e) { return document.body.innerText.slice(0, 200); }
    }
    
  3. 对于帖子讨论串,导航到 .../comments/POST_ID.json?limit=30&sort=top,并解析 data[0](帖子)和 data[1].data.children(评论)。

JSON 结构(浏览器和 curl 相同)

# Listing - swap hot for new/top/rising; for top add &t=day|week|month|year|all
/r/SUBREDDIT/hot.json?limit=15
# Post + comments - JSON array where [0]=post, [1]=comment tree
/r/SUBREDDIT/comments/POST_ID.json?limit=20
# Search within a subreddit
/r/SUBREDDIT/search.json?q=QUERY&restrict_sr=on&sort=new&limit=15
  • 列表:.data.children[].data 包含 title、score、num_comments、author、id。
  • 帖子讨论串:[0].data.children[0].data 是帖子;[1].data.children[](筛选 kind == "t1")是评论,包含 author、score、body,以及结构相同的嵌套 replies。
  • 截断较长的评论正文(例如,在 JS 中使用 body.slice(0, 300),或在 jq 1.7+ 中使用 .body[:300]),以便输出更易读。

备用方案

  • 获取每个讨论串的更多评论:(完成跳转后)加载渲染后的讨论串页面,并抓取 shreddit DOM——它返回的评论比 .json?limit= 更多:
    () => ({
      title: document.querySelector('shreddit-post')?.getAttribute('post-title'),
      comments: [...document.querySelectorAll('shreddit-comment')].map(c => ({
        author: c.getAttribute('author'),
        score:  c.getAttribute('score'),
        text:   c.querySelector('.md')?.innerText
      }))
    })
    
  • **完全无法使用 Playwright:**使用 Claude for Chrome 打开讨论串或 .json URL,并从页面中读取内容。
  • **curl(最后手段,预计会返回 403):**过去可以使用带浏览器 User-Agent 的直接 curl 请求,而且成功时速度更快;但现在几乎总是会返回 403——更改 UA 也没有帮助。只有在你已经准备从 Shell 发出请求且无法使用浏览器时,才值得快速尝试一次;如果返回 403,就直接使用 DDG 跳转。
    UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
    curl -s -L -o /tmp/reddit_result.txt -w "%{http_code}" -H "User-Agent: $UA" \
      'https://old.reddit.com/r/SUBREDDIT/hot.json?limit=15'
    jq -r '.data.children[] | .data | "\(.title)\n   \(.score) pts | \(.num_comments) comments | u/\(.author) | id: \(.id)\n"' /tmp/reddit_result.txt
    
    先将内容获取到临时文件(使用 -o),然后再解析;-w "%{http_code}" 会打印状态码;-L 会跟随重定向;URL 要用单引号括起来,避免 Shell 吞掉 &。

速率限制

即使解除访问限制后,Reddit 仍会严格限制请求速率:

  • 不要并行发送请求——按顺序执行,并使用 sleep 2/sleep 3(或在导航之间短暂停顿)。先获取一个列表并解析,然后逐个获取帖子讨论串。
  • 响应为空(0 字节):等待 3-5 秒后重试。HTTP 429:等待 10-15 秒后再试。会话中途出现挑战页面,表示 Cookie 已失效——重新执行 DDG 跳转。

评论

支持 Markdown