Use Reddit Multi-Mode Scraper for Posts, Comments & Profiles with Python
Pick one of five modes to pull subreddit posts, full comment threads, user profiles, keyword search results or curated community listings from Reddit, each with deep post/comment filters. No account or API key needed.
1. Choose the data you need
Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.
2. Prepare a source-based input
This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.
{
"authors": [],
"commentSort": "confidence",
"excludeArchived": false,
"excludeAuthors": [],
"excludeCrossposts": false,
"excludeDeletedAuthor": false,
"excludeKeywords": [],
"excludeLocked": false,
"excludeRemoved": false,
"excludeSpoilers": false,
"excludeStickied": false,
"failOnEmpty": false,
"includeComments": false,
"includeNSFW": false,
"includePost": true,
"includeProfileInfo": true,
"includeSubredditInfo": false,
"includeSubredditRules": false,
"maxComments": 5,
"maxCommunities": 0,
"maxDepth": 6,
"maxItems": 2,
"maxPosts": 2,
"maxProxyBytesMb": 50,
"maxUsers": 0,
"mode": "subreddit",
"onlyNew": false,
"onlyOriginalContent": false,
"onlyWithFlair": false,
"postUrls": [],
"proxyMode": "none",
"restrictSubreddits": [],
"searchComments": false,
"searchCommunities": false,
"searchPosts": true,
"searchQuery": "",
"searchUsers": false,
"sections": [
"posts"
],
"sort": "hot",
"source": "archive",
"stateKey": "reddit-mcp-state",
"subreddits": [
"programming"
],
"timeFilter": "day",
"usernames": []
}
Download input.example.json and save your reviewed copy as input.json.
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | required | What to scrape: a subreddit listing, post URLs with comments, a user profile, or keyword search. |
source | string | optional | auto uses live Reddit first and the Arctic Shift archive for depth/bulk or as a fallback. archive is faster and cheaper but lags live Reddit by several hours; live never uses archive data. |
subreddits | array | optional | Subreddits to scrape (mode=subreddit). Accepts names, r/ names or URLs. |
postUrls | array | optional | Post URLs, comment URLs, share links or bare post IDs (mode=post). |
usernames | array | optional | Reddit usernames to scrape (mode=profile). Accepts names, u/ names or profile URLs. |
searchQuery | string | optional | Keyword or phrase to search for (mode=search). Reddit search syntax such as "exact phrase", author:name, subreddit:name and -exclude is supported by live search. |
maxItems | integer | optional | Hard cap on all records pushed by the run, across every target. |
maxPosts | integer | optional | Posts per subreddit, keyword or profile section. |
maxComments | integer | optional | Comments per post, keyword, or profile comment section. 0 disables comment records. |
maxDepth | integer | optional | Deepest reply level to emit (0 = top-level comments only). |
includeComments | boolean | optional | Emit comment records for each post. Disable to fetch only the parent post. |
includePost | boolean | optional | Emit the post record before its comments. |
sort | string | optional | Post/listing sort. Search accepts relevance, hot, top, new or comments; other modes use hot, new, top, rising, controversial or best. |
timeFilter | string | optional | Time window for top/controversial sorts and search. |
commentSort | string | optional | Comment ordering for mode=post. |
includeNSFW | boolean | optional | Include over-18 posts and communities. |
includeSubredditInfo | boolean | optional | Emit one community record per subreddit before its posts. |
includeSubredditRules | boolean | optional | Attach posting rules to the community record. Requires includeSubredditInfo. |
includeProfileInfo | boolean | optional | Emit a profile record with karma, counts and account metadata. |
sections | array | optional | Which history sections to fetch (mode=profile). Allowed values: overview, posts, comments. |
searchPosts | boolean | optional | Include post results in keyword search. |
searchComments | boolean | optional | Include comment results in keyword search when Reddit's comment tab returns them. |
searchCommunities | boolean | optional | Include subreddit matches in keyword search. |
searchUsers | boolean | optional | Include matching Reddit accounts in keyword search. |
withinCommunity | string | optional | Limit post/comment search to a single subreddit (name, r/name or URL). Required for archive keyword search. |
maxCommunities | integer | optional | Maximum subreddit matches per search query. |
maxUsers | integer | optional | Maximum account matches per search query. |
onlyNew | boolean | optional | Emit only records newer than the watermark saved under stateKey by a previous run. |
stateKey | string | optional | Key-value store key prefix used by onlyNew watermarks. |
failOnEmpty | boolean | optional | Mark the run FAILED with a clear status message instead of finishing silently with 0 records. |
maxProxyBytesMb | integer | optional | Safety ceiling for paid proxy traffic. The run stops when the ceiling is reached. Images, media and fonts are never downloaded. |
proxyMode | string | optional | Direct (no proxy) is the default. Choose datacenter if Reddit blocks your runs. Residential is an explicit last resort and is capped by maxProxyBytesMb. |
minScore | integer | optional | Drop posts/comments below this score. |
maxScore | integer | optional | Drop posts/comments above this score. |
minPostComments | integer | optional | Drop posts with fewer comments than this. |
maxPostComments | integer | optional | Drop posts with more comments than this. |
minUpvoteRatio | number | optional | Drop posts below this upvote ratio (0-1). |
postType | string | optional | Keep only posts of this type. |
titleContains | string | optional | Keep only posts whose title contains this text. |
contentContains | string | optional | Keep only posts whose body/self-text contains this text. |
flairContains | string | optional | Keep only posts whose link flair contains this text. |
authorFlairContains | string | optional | Keep only posts whose author flair contains this text. |
domain | string | optional | Keep only posts whose link domain contains this text. |
authors | array | optional | Keep posts by these usernames. |
excludeAuthors | array | optional | Drop posts by these usernames. |
excludeKeywords | array | optional | Drop posts whose title, body or flair contains any of these terms. |
excludeStickied | boolean | optional | Exclude pinned/stickied posts from results. |
excludeRemoved | boolean | optional | Exclude posts or comments removed by moderators. |
excludeCrossposts | boolean | optional | Exclude crossposts. |
excludeSpoilers | boolean | optional | Exclude posts marked as spoilers. |
excludeLocked | boolean | optional | Exclude locked posts and comments. |
excludeDeletedAuthor | boolean | optional | Exclude records whose author account was deleted. |
excludeArchived | boolean | optional | Exclude archived posts that no longer accept votes or comments. |
onlyWithFlair | boolean | optional | Drop posts without a link flair. |
onlyOriginalContent | boolean | optional | Keep only posts tagged as OC. |
minAwards | integer | optional | Keep only posts with at least this many awards. |
minContentLength | integer | optional | Keep only posts whose body is at least this many characters. |
maxContentLength | integer | optional | Keep only posts whose body is at most this many characters. |
postedAfter | string | optional | UTC date lower bound (YYYY-MM-DD). |
postedBefore | string | optional | UTC date upper bound (YYYY-MM-DD), inclusive. |
restrictSubreddits | array | optional | Only keep profile posts/comments made in these subreddits. |
keyword | string | optional | Only keep profile posts/comments whose title, body or text contains this phrase. |
minCommunitySubscribers | integer | optional | Community search only: drop smaller subreddits. |
maxCommunitySubscribers | integer | optional | Community search only: drop larger subreddits. |
minUserKarma | integer | optional | User search only: drop accounts with less total karma. |
maxUserKarma | integer | optional | User search only: drop accounts with more total karma. |
distinguished | string | optional | Keep only moderator/admin/special posts, or only regular posts. |
3. Start an Actor run
Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.
Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.
import json
import os
import urllib.request
# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
actor_input = json.load(stream)
token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
"https://api.apify.com/v2/acts/TvCs8gaYvL352HNwD/runs?timeout=120&maxTotalChargeUsd=0.50",
data=json.dumps(actor_input).encode("utf-8"),
headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.
4. Inspect the actual results
Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.
Reddit posts, comments, profiles and community records with engagement metrics, derived activity and per-record source provenance.
Questions before you run
Which inputs are required?
The published required fields are mode
What does this guide verify?
The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.
What if the run request times out?
Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.
Generated from source build ilFk20SGtzrsuw9Db and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.