关于 reddit-fetch
Reddit Fetch 是通过 Playwright 获取 Reddit 列表、帖子和评论的工作流程。它先借助 DuckDuckGo 跳转建立会话,再读取 Reddit JSON,并提供页面抓取等备用方式。
主要功能
- 01通过 DuckDuckGo 跳转建立会话
- 02使用 Playwright 获取 Reddit JSON
- 03读取列表、帖子和评论
- 04从页面抓取更多评论
- 05应对访问受阻的备用方式
- 06按顺序请求以避开速率限制
适用场景
- 01收集 Subreddit 的近期搜索结果
- 02读取帖子及其评论树
- 03获取超出 JSON 限额的评论
- 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 内容之前执行一次。
- 使用
mcp__playwright__browser_navigate导航到https://html.duckduckgo.com/html/?q=site:reddit.com/r/SUBREDDIT+YOUR+QUERY - 获取第一个结果的完整 href——这是一个包含
rut令牌的 DDG 重定向链接(https://duckduckgo.com/l/?uddg=...&rut=...)。该令牌是必需的;导航到不带令牌的/l/?uddg=会返回 400。() => document.querySelector('.result__a')?.href - 使用
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)。
- 使用
browser_navigate导航到例如https://www.reddit.com/r/SUBREDDIT/search.json?q=QUERY&restrict_sr=on&sort=new&t=week&limit=25 - 运行
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); } } - 对于帖子讨论串,导航到
.../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]),以便输出更易读。
备用方案
- 获取每个讨论串的更多评论:(完成跳转后)加载渲染后的讨论串页面,并抓取
shredditDOM——它返回的评论比.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 打开讨论串或
.jsonURL,并从页面中读取内容。 - **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 跳转。