reddit-fetch について
Reddit Fetch は、Playwright で Reddit の一覧、投稿、コメントを取得するワークフローです。DuckDuckGo のリダイレクト経由でセッションを確立してから Reddit JSON を読み取り、必要に応じてページのスクレイピングなどに切り替えます。
主な機能
- 01DuckDuckGo リダイレクトでセッション確立
- 02Playwright で Reddit JSON を取得
- 03一覧、投稿、コメントの読み取り
- 04ページから追加コメントを取得
- 05アクセス制限時の代替手段
- 06レート制限に備えた逐次リクエスト
活用シーン
- 01サブレディットの新しい検索結果の収集
- 02投稿とコメントツリーの確認
- 03JSON の上限を超えるコメントの取得
- 04Reddit の直接アクセス制限からの復旧
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ykdojo/ claude-code-tips --skill reddit-fetchインストール後、Claude Code で/reddit-fetchを入力して読み込まれたか確認します。
詳細
Reddit Fetch
Reddit の公開 JSON API は、任意の Reddit URL の末尾に .json を付けることで利用できますが、現在 Reddit は自動アクセスを厳しくブロックしています。curl はほぼ毎回 403 を返します(ホストでもコンテナ内でも、User-Agent に関係なく)。また、Playwright で reddit.com に初めてアクセスした場合も、「ネットワークセキュリティによりブロックされました」というチャレンジページが表示されます。 確実な方法は、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) を実行します。ブラウザーナビゲーションには old.reddit.com ではなく www.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)を返します。その場合は DDG 経由のアクセスをやり直します)。() => { 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])。
代替手段
- スレッドあたりのコメント数を増やす:(DDG 経由でアクセスした後に)レンダリング済みのスレッドページを読み込み、
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 を変更しても解決しません。シェルからコマンドを実行する状況で、ブラウザーが利用できない場合に限り、一度だけ手早く試す価値があります。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 はシングルクォートで囲んでください。
レート制限
ブロック解除後も、Reddit は積極的にレート制限を行います。
- リクエストを並列実行しないでください。
sleep 2/sleep 3を挟んで(またはナビゲーションの間に短い待機を入れて)順番に実行します。一覧を 1 つ取得して解析してから、スレッドを 1 件ずつ取得してください。 - レスポンスが空(0 バイト)の場合:3~5 秒待ってから再試行します。HTTP 429 の場合:10~15 秒待ちます。セッション中にチャレンジページが表示された場合は Cookie の有効期限が切れています。DDG 経由のアクセスをやり直してください。