Reddit Scraper - Posts, Comments, Subreddits & Media avatar

Reddit Scraper - Posts, Comments, Subreddits & Media

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Reddit Scraper - Posts, Comments, Subreddits & Media

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

Abot API

Maintained by Community

Actor stats

1

Bookmarked

18

Total users

0

Monthly active users

a day ago

Last modified

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.

FieldExample
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)
score1542
upvote_ratio0.96
num_comments234
num_crossposts5
selftext"I've been exploring different libraries..."
post_type"text" (also "image", "video", "gallery", "link")
is_nsfwfalse
is_spoilerfalse
flair"Discussion"
total_awards3
has_mediafalse
media_urls{ "images": [], "videos": [], "galleries": [] } (when Extract Media URLs is on)
media_downloadedtrue (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

  1. Enter a target: a subreddit name (e.g. python) or, with Is Username on, a Reddit username.
  2. Set Post Limit and Sort By (new, hot, top or rising); pick a Timeframe if sorting by top.
  3. Turn on Scrape Comments and/or Extract Media URLs (and Download Media Files) for the extra data you need.
  4. 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 ApifyClient
client = 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 with stateKey. Each post is classified NEW, UPDATED (with changedFields), UNCHANGED, REAPPEARED or EXPIRED. NEW and UPDATED are always returned. UNCHANGED is suppressed (not returned or billed) unless emitUnchanged is on. EXPIRED is only produced when emitExpired is on and the run scanned the whole listing to its natural end, which a Post Limit cap or resumeFromRunId prevents; without that, previous state is left untouched. REAPPEARED can therefore only happen for a post that a past emitExpired run already tombstoned as EXPIRED and that later shows up again; turning emitExpired on is what makes REAPPEARED possible 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; UPDATED means 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, live score, upvote_ratio and num_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.

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to 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

ParameterTypeDefaultDescription
targetstringnone (example: python)Subreddit name or username (required).
isUserbooleanfalseSet true if target is a username instead of a subreddit.
limitinteger10Maximum posts to scrape, up to 1000.
sortstringnewnew, hot, top, or rising. Applies to subreddit listings; username mode returns the user's submitted posts in Reddit's own order.
timeframestringallTime filter used with top sort: hour, day, week, month, year, all.
scrapeCommentsbooleanfalseFetch available comments and replies; each returned comment is a separate billable result row.
commentsLimitinteger100Requested comments per post, up to 500. Included replies can increase the returned row count.
extractMediaUrlsbooleantrueExtract image, video and gallery URLs from posts.
downloadMediabooleanfalseDownload media files to the Key-Value Store; requires extractMediaUrls: true and adds transfer/storage work.
proxyobjectnone (example: Apify Proxy, RESIDENTIAL group, country US)Connection settings. Reddit's listing host blocks most non-residential connections.
resumeFromRunIdstringnoneContinue one specific interrupted run without re-collecting or re-charging its posts.
incrementalModebooleanfalseTurn on for recurring monitoring: classify each post as NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED against the previous run.
stateKeystringnoneName a monitoring campaign explicitly; otherwise the state key is derived automatically from target, sort, timeframe and media toggles.
emitUnchangedbooleanfalseAlso return (and bill) UNCHANGED posts every run.
emitExpiredbooleanfalseAlso return (and bill) posts no longer found, once a run fully scans the listing.
mcpConnectorsarraynoneOptional: send a summary of each record to apps you authorized under Integrations.
notionParentPageUrlstringnoneNotion connector only: page under which item pages are created.
maxNotifyListingsinteger50Cap 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.

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...

👉 Browse all abotapi scrapers

💬 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.