Reddit Search Scraper — Posts by Keyword, Score & Date
Pricing
from $2.00 / 1,000 per post returneds
Reddit Search Scraper — Posts by Keyword, Score & Date
Search Reddit by keyword — site-wide or inside chosen subreddits — and get posts with real score, upvote ratio, comment count, author, flair, selftext and timestamps from Reddit's own JSON. Sort by relevance, new or top; date window; strict keyword match; optional top comments. No login, no API key.
Pricing
from $2.00 / 1,000 per post returneds
Rating
0.0
(0)
Developer
Scrapers Delight
Maintained by CommunityActor stats
0
Bookmarked
931
Total users
532
Monthly active users
8 hours ago
Last modified
Categories
Features
Share
Search Reddit by keyword — across all of Reddit or inside the subreddits you name — and get one row per post: id, subreddit, title, author, selftext, url, domain, permalink, score, num_comments, created time, NSFW/spoiler flags and thumbnail, plus the query, subreddit, sort and time range it was found under. Optionally nest each post's top comments inside the row. No login, no Reddit account, no API key.
{"queries": ["web scraping"],"sort": "relevance","time": "all","maxItems": 100}
That is the input the Actor ships with: click Try for free and Start to get 100 posts.
What you get
One row per unique post, de-duplicated run-wide on Reddit's t3_ fullname. Timestamps are UTC
(created_utc whole seconds + created_iso ISO-8601).
| Group | Fields | Filled |
|---|---|---|
| Identity | id, name, permalink, url, domain, is_self | always |
| Where | subreddit, subreddit_prefixed | always |
| Content | title, selftext, author, author_fullname, thumbnail | selftext is "" on link posts; author is "[deleted]" for a deleted account (then author_fullname is null); thumbnail only on posts Reddit shows a preview for |
| Engagement | score, ups, num_comments | always (ups = score) |
| Time | created_utc, created_iso | always |
| Flags | over_18, spoiler | always |
| Comments (optional) | topComments[] (id, name, parent_id, depth, author, body, score, created_iso, is_submitter, permalink, post_id), commentsEnriched | when includeTopComments is on |
| Provenance | search_query, search_subreddit, search_sort, search_time, transport, scraped_at | always (search_subreddit is null on a site-wide search) |
| Not shown to logged-out visitors | upvote_ratio, subreddit_subscribers, num_crossposts, total_awards_received, link_flair_text, post_hint, is_video, stickied, locked, distinguished | null — see below |
Since November 2026 Reddit no longer serves its post JSON to logged-out visitors, so the fields
in the last row of the table are null on every row (never a fake 0). They stay in the dataset so
your integrations keep the same columns. edited is false (Reddit's search page does not show
edits).
The dataset ships with a saved table view (title, subreddit, author, score, upvote ratio, comments, posted time, flair, query, transport, permalink, link).
Read this before you buy rows
- One Reddit search ends after about 200 distinct posts. Measured on the platform on 2026-11-12: one unbounded site-wide search for "web scraping" returned 206 distinct posts and then Reddit stopped serving pages. If you ask for 1,000 from one query you get ~200 and a clean SUCCEEDED run. To get more, add queries (synonyms, phrasings) and/or subreddits — every query × subreddit pair is its own search, and the Actor de-duplicates across all of them before billing.
scoreis a snapshot, and Reddit fuzzes it by a few points on every read. Two runs minutes apart can differ by ±1–3 on the same post. Brand-new posts often show 0.dateFrom/dateTofilter after Reddit answers. Reddit has no exact-date operator, so the Actor reads search pages and keeps the in-window rows (removed rows are never billed). Usesort: "new"so the walk stops at the first page older thandateFrom.selftextis empty ("") for link posts, not null. Filter onis_self. A post whose own page Reddit did not serve keepsselftext,url,domainandis_selfnull, and the run's status message says how many there were.- Strict keyword match (
strictSearch: true) keeps only posts whose title + selftext contain every word of the query (case-insensitive; quotes and common stop-words are ignored). Do not combine it with Reddit's search operators —-seleniumortitle:fooare matched as literal words, so a query using them will filter to zero.
How to run it
1. Site-wide keyword search
{"queries": ["web scraping", "\"headless browser\" -selenium"],"sort": "relevance","time": "year","maxItems": 300}
Reddit's own search syntax works inside a query: quotes for an exact phrase, OR, a leading -
to exclude, and field prefixes (title:, author:, subreddit:, flair:, self:yes). Each
query is its own search; a post matching two of them is returned and billed once.
2. Inside chosen subreddits
{"queries": ["pricing", "refund"],"subreddits": ["SaaS", "startups", "r/smallbusiness"],"sort": "top","time": "month","maxItemsPerQuery": 50,"maxItems": 300}
Every query is run inside every subreddit (2 × 3 = 6 searches). maxItemsPerQuery stops one broad
query from spending the whole budget before the others run.
3. Keyword monitor — newest first, from a date, strict
{"queries": ["web scraping"],"subreddits": ["webscraping", "learnpython"],"sort": "new","dateFrom": "2026-10-13","strictSearch": true,"maxItems": 200}
Save it as a Task, attach a weekly Schedule, and move dateFrom forward each week.
4. Posts with their top comments
{"queries": ["best CRM for small business"],"includeTopComments": true,"maxCommentsPerPost": 10,"maxItems": 30}
One extra Reddit request per post, so runs take longer. Charged on comments-enriched only for
posts where comments actually came back.
Scheduling and integrations
Save the input as a Task (Console → the Actor → Save as Task), then attach an Apify Schedule. The dataset is available over the REST API and through the standard Apify integrations (Zapier, Make, n8n, webhooks, MCP) like any other Actor. From the API:
curl -X POST "https://api.apify.com/v2/acts/scrapersdelight~reddit-search-scraper/runs?token=YOUR_TOKEN" \-H 'Content-Type: application/json' \-d '{"queries":["web scraping"],"subreddits":["webscraping"],"sort":"new","maxItems":100}'
Sample row
A real row from a run on the shipped default input, 2026-11-12.
{"id": "1tbuq4g","name": "t3_1tbuq4g","subreddit": "webscraping","subreddit_prefixed": "r/webscraping","subreddit_subscribers": null,"title": "The Complete Web Scraping & Anti-Bot Bypass Guide 2026","author": "pimterry","author_fullname": "t2_3vf8x","selftext": "","is_self": false,"url": "https://asadfix.github.io/scraping-guide/","domain": "asadfix.github.io","permalink": "https://www.reddit.com/r/webscraping/comments/1tbuq4g/the_complete_web_scraping_antibot_bypass_guide/","score": 142,"ups": 142,"upvote_ratio": null,"num_comments": 53,"num_crossposts": null,"total_awards_received": null,"created_utc": 1778665169,"created_iso": "2026-05-13T09:39:29.000Z","edited": false,"over_18": false,"spoiler": false,"stickied": null,"locked": null,"is_video": null,"link_flair_text": null,"post_hint": null,"thumbnail": "https://external-preview.redd.it/OaTdPqed-x064p4EFyiLkNhdfqOJOqbTEScgdj84rqI.png?width=140&height=73&auto=webp&s=614026ad6ac9383ed04d84be45ec98ca40c5a578","distinguished": null,"search_query": "web scraping","search_subreddit": null,"search_sort": "relevance","search_time": "all","transport": "search","topComments": [],"commentsEnriched": false,"scraped_at": "2026-11-12T15:58:39.956Z"}
Fields people misread:
scoreandupsare the same number on a post (Reddit no longer exposes downvotes).search_subredditisnullon a site-wide search and the subreddit name on a restricted one;subredditis always where the post actually lives. A post on a user's profile has subredditu_<name>and a/user/<name>/comments/…permalink.transportis"search"(rows read from Reddit's search page). Rows from runs before November 2026 may say"json"or"rss".
Input
| Field | Type | Default | What it does |
|---|---|---|---|
| 🔎 What to search | |||
queries | string list | ["web scraping"] | One keyword phrase per line; Reddit search syntax allowed. Empty = the documented sample. |
subreddits | string list | [] | Restrict every query to each listed subreddit. Empty = all of Reddit. |
sort | select | relevance | relevance · new · top · hot · comments. |
time | select | all | Reddit's server-side time range. |
| 🎚️ Filters | |||
dateFrom / dateTo | string | "" | YYYY-MM-DD (UTC) or ISO-8601; applied to created_utc before billing. |
strictSearch | boolean | false | Keep only posts whose title + selftext contain every query word. |
includeNsfw | boolean | true | Uncheck to drop over-18 posts. |
| 💬 Comments | |||
includeTopComments | boolean | false | Nest each post's top comments into topComments[]. |
maxCommentsPerPost | integer | 10 | 1–100, Top order, top-level + direct replies. |
| 💷 Limits & cost | |||
maxItems | integer | 100 | Your hard cost cap. 100 = $0.20, 1,000 = $2.00. 0 = no limit (internally capped at 100,000). |
maxItemsPerQuery | integer | 100 | Cap per query × subreddit search. 0 = unlimited (Reddit stops at ~200 anyway). |
| ⚙️ Advanced | |||
allowRssFallback | boolean | true | Keep a post whose search result showed neither a score nor a comment count (rare). Off = such posts are dropped, unbilled. |
proxyConfiguration | proxy | Apify RESIDENTIAL | Residential is the default and the recommended setting: Reddit turns away most Apify datacenter IPs. |
tryDirectFirst | boolean | false | Try Apify's own network before the proxy. Reddit currently refuses it, so leave this off unless you run behind your own network. |
requestDelayMs | integer | 700 | Minimum gap between two search page requests. |
Pricing
$0.002 per post returned — $2 per 1,000, charged on the post-scraped event.
$0.003 per post comment-enriched, charged on comments-enriched only when the add-on is on
and at least one comment was returned for that post. No monthly fee from this Actor.
| Run | Posts | Cost |
|---|---|---|
| The shipped default (100 posts) | 100 | $0.20 |
| One keyword to Reddit's ceiling | ~200 | $0.40 |
| 4 queries × 5 subreddits, 50 each | 1,000 | $2.00 |
| 100 posts + top comments on all of them | 100 + 100 | $0.50 |
- You are charged for rows delivered. Duplicates across queries and subreddits are dropped before billing; posts removed by the date window, strict match or NSFW filter are never charged.
- Charged first, then pushed — at a budget cap (
maxTotalChargeUsdor a free-tier balance) you get whole rows and stop, never a half-billed dataset. The Actor reads your remaining charge headroom at startup and stops fetching at the affordable count. - Comments are never charged for a post that got none.
Honest limits
- About 200 posts per search is Reddit's ceiling (206 measured on 2026-11-12). Fan out across queries and subreddits to go wider.
- Scores are fuzzed by Reddit by a few points on every read. Treat them as ±3.
- Upvote ratio, flair, subscriber counts, awards, crossposts and the stickied/locked flags are null: Reddit stopped showing them to logged-out visitors in November 2026.
- Top comments only.
topCommentsis the firstmaxCommentsPerPostcomments in Top order (top-level comments and their direct replies); deeper replies are not included, and a 2,000-comment thread yields at most 100 here.stickiedis null on comments. - No user/profile data beyond the author handle.
authorandauthor_fullnameare what Reddit prints on the post; nothing is looked up about the person. - Residential proxy is recommended. Reddit turns away most Apify datacenter IPs. The default is already correct.
How it works
Reddit answers logged-out visitors with a small JavaScript challenge page before it serves any data. The Actor answers that challenge the way a browser would — no browser needed, no account — and then reads Reddit's own search page, 7 posts at a time in Reddit's order, with each post's score, comment count, author, subreddit and time. Each post's own feed adds its selftext and the link it points to. Top comments come from the post's comment page. Sessions run through residential IPs; if Reddit refuses an IP, or an IP stops answering, a fresh session is opened and the search continues from the same page. Residential traffic is capped per run at $0.01 plus 60% of what the run has billed; a run that passes it continues on Apify datacenter sessions, and stops with what it has delivered if Reddit refuses those too.
When a run fails
This Actor fails loudly only where the output would otherwise be silently wrong:
- Duplicate leak → the uniqueness assertion fails the run.
- Reddit refused or did not answer every request (no search page came back) → FAILED with that reason in the status message; nothing is charged. Re-run later.
Everything else ends SUCCEEDED with a status message that says what happened:
- 0 rows → the message names the cause — no results from Reddit, or your filters removed everything — and what to change.
- Run time budget → the Actor stops fetching in time to push what it has: "Stopped early to stay inside this run's time limit — N posts delivered and charged."
- Charge cap → "Stopped at this run's pay-per-event charge cap with N posts delivered. Every row delivered was billed."
Our other Reddit Actor
| Actor | What it is | When to use it instead |
|---|---|---|
| Reddit Subreddit Scraper | A subreddit's hot / new / top / rising listing plus full comment trees | When you want everything in a subreddit rather than a keyword's matches |
FAQ
Does this need a Reddit account, a login or an API key? No. It reads the same public pages Reddit shows a logged-out visitor, on a residential IP. No cookie of yours is ever used.
Why are upvote_ratio and link_flair_text null?
Reddit stopped serving them to logged-out visitors in November 2026. score and num_comments
are still read from Reddit's search page on every row.
How many posts can one query return? About 200 — Reddit's own ceiling. Add queries and subreddits to go wider.
Can I search by exact date?
Use dateFrom / dateTo (applied before billing) with sort: "new" for an early stop, and time
to pre-narrow what Reddit returns.
Do comments cost extra?
Only when you turn includeTopComments on, and only for posts that actually returned at least
one comment — comments-enriched at $0.003 per such post.
Two runs — will I get duplicates?
Within a run, never: dedupe is on the t3_ fullname and asserted before the run can succeed.
Across runs, move dateFrom forward.
Will a run ever succeed with zero rows? Yes, when Reddit has no results or your filters removed them: it ends SUCCEEDED with a status message naming the cause, so a scheduled monitor on a quiet keyword does not get flagged as broken. Only a run Reddit refused completely ends FAILED (nothing charged).
Feedback
Found a missing field or want a new filter? Open an issue on the Issues tab.