Reddit Scraper - Posts, Comments, Subreddits & Media
Pricing
from $1.00 / 1,000 results
Reddit Scraper - Posts, Comments, Subreddits & Media
Scrape Reddit posts, comments and media from any subreddit or user profile. Search by keyword, sort by hot, new, top or rising, and optionally extract full comment threads and media URLs. Fast, resource-efficient and requires no login or API keys.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
18
Total users
0
Monthly active users
a day ago
Last modified
Categories
Share
Reddit Scraper: Posts, Comments and Media from Any Subreddit or User
Reddit Scraper turns Reddit into a clean data feed. Point it at any subreddit or any user profile, pull posts sorted by new, hot, top or rising, optionally fetch available comments and replies under each post, and collect image, video and gallery URLs, or download the files themselves. Export the results to JSON, CSV or Excel, or read them straight through the API.
Why This Scraper?
- Two targets, one actor. Scrape any public subreddit's listing, or switch to username mode and pull one user's posted history instead.
- Posts with context. Collect post text, author, timestamps, scores, flair and discussion counts together in each post record.
- Comments on demand. Turn on comment scraping to pull the discussion thread under each post, with available replies and their depth.
- Media without extra tooling. Image, video and gallery URLs come straight from the post data, and can optionally be downloaded to storage instead of just linked.
- Built for schedules. Resume continues one interrupted pull without re-collecting or re-charging posts it already has, and incremental mode returns only new and changed posts on recurring runs.
- Optional extra work. Comment scraping and media downloads are off by default. Media URLs can be collected without downloading files; recurring monitoring can suppress unchanged posts.
Use Cases
- Market research and brand monitoring: track product mentions and competitor discussion across chosen subreddits.
- Sentiment and NLP research: build labeled text datasets from post titles, self text and comment threads.
- Content curation: collect trending posts and their media for aggregation or a content pipeline.
- Academic and social research: gather subreddit or user activity for longitudinal studies.
- Lead generation: find users discussing a relevant topic or product across a community.
- Recurring monitoring: schedule the actor with incremental mode to track a subreddit or user's new activity without re-collecting what you already have.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
The dataset also ships three ready-made views (Posts Overview, Comments, Media URLs) selectable from the dataset's view tabs.
| Field | Example |
|---|---|
type | "post" (also "comment") |
id | "1hj2abc" |
title | "What's your favorite Python library?" |
author | "pythonista123" |
subreddit | "python" |
created_utc | "2024-12-20T15:30:00" |
permalink | "https://reddit.com/r/python/comments/1hj2abc/..." |
url | "https://reddit.com/r/python/comments/1hj2abc/..." (destination link for image/video/link posts) |
score | 1542 |
upvote_ratio | 0.96 |
num_comments | 234 |
num_crossposts | 5 |
selftext | "I've been exploring different libraries..." |
post_type | "text" (also "image", "video", "gallery", "link") |
is_nsfw | false |
is_spoiler | false |
flair | "Discussion" |
total_awards | 3 |
has_media | false |
media_urls | { "images": [], "videos": [], "galleries": [] } (when Extract Media URLs is on) |
media_downloaded | true (when Download Media Files is on) |
changeType | "NEW" (incremental mode only) |
changedFields | [] (incremental mode only) |
firstSeenAt / lastSeenAt | "2026-07-30T03:00:00Z" (incremental mode only) |
Comment records use a separate shape carried under type: "comment": comment_id, post_permalink, post_title, parent_id, author, body, score, created_utc, depth (top-level comments are depth 0; replies are read through depth 3) and is_submitter. Comments never carry changeType or the other incremental fields; incremental mode only classifies posts.
How to Use
- Enter a target: a subreddit name (e.g.
python) or, with Is Username on, a Reddit username. - Set Post Limit and Sort By (
new,hot,toporrising); pick a Timeframe if sorting bytop. - Turn on Scrape Comments and/or Extract Media URLs (and Download Media Files) for the extra data you need.
- Click Start. Results are saved to the dataset as they are scraped.
Subreddit, hot posts with media URLs and no comments:
{"target": "python","limit": 100,"sort": "hot","scrapeComments": false,"extractMediaUrls": true}
User profile, latest submitted posts:
{"target": "spez","isUser": true,"limit": 50}
Recurring subreddit monitor with incremental mode:
{"target": "askreddit","limit": 200,"sort": "new","incrementalMode": true,"emitExpired": true}
Continue an interrupted large pull:
{"target": "python","limit": 1000,"sort": "new","resumeFromRunId": "abCdEfGhIjKlMnOpQ"}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/reddit-scraper").call(run_input={"target": "python", "limit": 50, "sort": "hot"})for post in client.dataset(run["defaultDatasetId"]).iterate_items():if post.get("type") == "post":print(post["title"], post["score"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/reddit-scraper').call({ target: 'python', limit: 50, sort: 'hot' });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Resume and recurring updates
Two different features, both opt-in:
- Resume (
resumeFromRunId) continues one specific interrupted run: paste its run or dataset ID and this run skips posts it already collected there, so you don't pay twice. - Incremental mode (
incrementalMode) is for scheduling this actor on the same subreddit or user, sort and timeframe again and again. State is kept separately per target, sort, timeframe and media-toggle combination, or under one name you choose withstateKey. Each post is classifiedNEW,UPDATED(withchangedFields),UNCHANGED,REAPPEAREDorEXPIRED.NEWandUPDATEDare always returned.UNCHANGEDis suppressed (not returned or billed) unlessemitUnchangedis on.EXPIREDis only produced whenemitExpiredis on and the run scanned the whole listing to its natural end, which a Post Limit cap orresumeFromRunIdprevents; without that, previous state is left untouched.REAPPEAREDcan therefore only happen for a post that a pastemitExpiredrun already tombstoned asEXPIREDand that later shows up again; turningemitExpiredon is what makesREAPPEAREDpossible at all. With incremental mode off, output is exactly as before. - A vote or a new comment alone never marks a post
UPDATED. Score, upvote ratio and comment count drift on their own within minutes, so they are excluded from change detection;UPDATEDmeans some other field changed, for example the title, text, URL, flair, NSFW/spoiler flags, crosspost or award count, author (such as a deleted account) or media. Every returned post still carries its current, livescore,upvote_ratioandnum_comments.
Caps and media limits
Post Limit stops a run after that many posts are scanned (a suppressed UNCHANGED post still counts against it). Comments Per Post controls the requested comment count, rather than a hard cap on output rows: included replies can increase the number returned. Comment rows are additional to Post Limit. The actor reads available replies through depth 3, with top-level comments at depth 0; it does not expand every remaining thread. When Download Media Files is on, downloads are capped per post: up to 5 images, up to 10 gallery items and up to 2 videos (YouTube links are kept as URLs only, never downloaded).
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
target | string | none (example: python) | Subreddit name or username (required). |
isUser | boolean | false | Set true if target is a username instead of a subreddit. |
limit | integer | 10 | Maximum posts to scrape, up to 1000. |
sort | string | new | new, hot, top, or rising. Applies to subreddit listings; username mode returns the user's submitted posts in Reddit's own order. |
timeframe | string | all | Time filter used with top sort: hour, day, week, month, year, all. |
scrapeComments | boolean | false | Fetch available comments and replies; each returned comment is a separate billable result row. |
commentsLimit | integer | 100 | Requested comments per post, up to 500. Included replies can increase the returned row count. |
extractMediaUrls | boolean | true | Extract image, video and gallery URLs from posts. |
downloadMedia | boolean | false | Download media files to the Key-Value Store; requires extractMediaUrls: true and adds transfer/storage work. |
proxy | object | none (example: Apify Proxy, RESIDENTIAL group, country US) | Connection settings. Reddit's listing host blocks most non-residential connections. |
resumeFromRunId | string | none | Continue one specific interrupted run without re-collecting or re-charging its posts. |
incrementalMode | boolean | false | Turn on for recurring monitoring: classify each post as NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED against the previous run. |
stateKey | string | none | Name a monitoring campaign explicitly; otherwise the state key is derived automatically from target, sort, timeframe and media toggles. |
emitUnchanged | boolean | false | Also return (and bill) UNCHANGED posts every run. |
emitExpired | boolean | false | Also return (and bill) posts no longer found, once a run fully scans the listing. |
mcpConnectors | array | none | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | none | Notion connector only: page under which item pages are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
Example post record:
{"type": "post","id": "1hj2abc","title": "What's your favorite Python library?","author": "pythonista123","subreddit": "python","created_utc": "2024-12-20T15:30:00","permalink": "https://reddit.com/r/python/comments/1hj2abc/","url": "https://reddit.com/r/python/comments/1hj2abc/","score": 1542,"upvote_ratio": 0.96,"num_comments": 234,"num_crossposts": 5,"selftext": "I've been exploring different libraries and wanted to hear what everyone's using...","post_type": "text","is_nsfw": false,"is_spoiler": false,"flair": "Discussion","total_awards": 3,"has_media": false,"media_urls": {"images": [],"videos": [],"galleries": []}}
Plan Requirement
Check the Pricing tab for current actor charges and your Apify plan for available connection resources. Choose limits and optional data appropriate to your workload.
FAQ
How much does it cost?
The Pricing tab shows the current actor-start charge and per-result rate. Each post and each comment returned is a result. Post Limit caps scanned posts, not comment rows or total charges. Connection usage and downloaded files can add transfer and storage costs.
For a lower-workload starting point, keep Scrape Comments and Download Media Files off, keep Extract Media URLs on if you need media links, and choose a Post Limit that covers your needs. For recurring monitoring, enable incremental mode and leave Emit unchanged and Emit expired off unless you need those rows. Incremental mode still scans the source and still fetches comments when enabled; it reduces post output, rather than eliminating request work or the actor-start charge.
Is it legal to scrape Reddit?
This actor collects publicly available posts and comments. Follow Reddit's terms, applicable privacy laws and regulations, and use a lawful basis when processing personal data. Obtain legal advice for your intended use where needed.
Can I get only new or changed posts on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental changes for scheduled runs. Later runs then return only NEW and UPDATED posts by default, and unchanged posts are not returned or billed unless you turn on Emit unchanged. When Scrape Comments is enabled, comments can still be fetched and returned as separate billable rows for an unchanged post.
What's the difference between Resume and Incremental mode?
Resume (resumeFromRunId) continues one specific interrupted run from a pasted run or dataset ID, so a large one-off pull can finish without starting over. Incremental mode is for scheduling the actor repeatedly against the same subreddit or user, sort and timeframe, so each run returns only what's new or changed since the last one. They solve different problems and can be combined for a first bootstrap run.
Why did my run fail instead of returning an empty dataset?
This actor fails the run for a configuration problem (a missing target, a resumeFromRunId that doesn't resolve to a run or dataset you own, or turning on incremental mode with resumeFromRunId while that state key already has saved history) or an unexpected internal error. If Reddit itself blocks requests during the scrape, the run still finishes and simply returns fewer posts, or none, rather than failing; try again in a few minutes, or check that a residential connection is selected.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
🔗 Want more social media data?
Pair this actor with these related scrapers from the same team:
| 📱 Lemon8 Feed Scraper Scrape Lemon8 feeds across 22 categories and 10+ regions. Extract posts, images, videos... | 📱 Lemon8 Search Scraper Scrape Lemon8 posts by keyword across multiple regions. Extract posts, images, videos... |
| 📱 Lemon8 Profile Scraper Scrape Lemon8 user profiles with automated multi-profile discovery. Extract profile data... | 📱 Lemon8 Media Scraper Lightweight Lemon8 scraper for extracting image and video URLs from posts, with optional... |
| 🧩 Pikabu Scraper Scrape Pikabu (Пикабу): keyword search, hot/new/best feeds, communities, tags, full story... | 📱 Mastodon Scraper Scrape trending Mastodon profiles and related posts from any Mastodon instance. Extract... |
💬 Support
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.