# Reddit Scraper — Posts, Comments & Subreddits (`junipr/reddit-scraper`) Actor

Scrape Reddit posts, comments, subreddit feeds, profiles, and search results with threading, filters, media metadata, and JSON/CSV-ready output.

- **URL**: https://apify.com/junipr/reddit-scraper.md
- **Developed by:** [junipr](https://apify.com/junipr) (community)
- **Categories:** Social media, Developer tools
- **Stats:** 21 total users, 0 monthly users, 88.6% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.60 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Reddit Scraper — Posts, Comments & Subreddits

Scrape Reddit posts, comments, user profiles, and subreddit metadata without a Reddit API key. Features full comment tree threading, media extraction, NSFW filtering, and configurable content filters. Works out of the box with zero configuration — just provide a subreddit name or Reddit URL and start collecting data.

### Why Use This Over Reddit API

Reddit deprecated its free API tier in 2023. The official API now costs $0.24 per 1,000 API calls with a $100/month minimum commitment, plus requires OAuth application setup and rate limit quota management.

This actor bypasses the API entirely using web scraping. No API key, no OAuth, no monthly subscription. Additional features the Reddit API does not provide: media URL resolution for external hosts (imgur, gfycat), NSFW content filtering with safe defaults, and structured flair/award/crosspost data that competitors ignore.

| Feature | This Actor | epctex Reddit Scraper | Reddit API (Official) |
|---------|-----------|----------------------|-----------------------|
| API key required | No | No | Yes (OAuth) |
| Monthly subscription | No | No | $100/mo minimum |
| Comment threading | Full tree structure | Flat list | Full tree |
| Media extraction | Video, gallery, embed, external | Images only | URLs only |
| NSFW filtering | Configurable (off by default) | No | Basic |
| Rate limit handling | Auto backoff + rotation | Manual retry | Built-in quotas |
| Cost per 1K posts | $2.60 | ~$4.00 | $0.24 (API calls only) |

### How to Use

**Zero-config example** — scrape hot posts from r/technology:

```json
{
    "scrapeType": "posts",
    "subreddits": ["technology"],
    "maxResults": 50
}
```

**Search Reddit for brand mentions:**

```json
{
    "scrapeType": "search",
    "searchQuery": "your brand name",
    "sort": "new",
    "maxResults": 200
}
```

**Get all comments on a specific post:**

```json
{
    "scrapeType": "comments",
    "urls": ["https://www.reddit.com/r/AskReddit/comments/abc123/your_post_title/"]
}
```

**Scrape top posts from this week with comment trees:**

```json
{
    "scrapeType": "posts",
    "subreddits": ["technology", "programming"],
    "sort": "top",
    "timeFilter": "week",
    "maxResults": 100,
    "includeComments": true,
    "maxCommentsPerPost": 50
}
```

**Scrape subreddit metadata:**

```json
{
    "scrapeType": "subreddit",
    "subreddits": ["technology", "programming", "webdev"]
}
```

### Input Configuration

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `scrapeType` | string | `"posts"` | What to scrape: `posts`, `comments`, `subreddit`, `userProfile`, `search` |
| `urls` | string\[] | `[]` | Direct Reddit URLs (posts, subreddits, users) |
| `searchQuery` | string | — | Search query (required for `search` type) |
| `subreddits` | string\[] | `[]` | Subreddit names without `r/` |
| `sort` | string | `"hot"` | Sort: `hot`, `new`, `top`, `rising`, `controversial` |
| `timeFilter` | string | `"all"` | Time filter for `top`/`controversial`: `hour`, `day`, `week`, `month`, `year`, `all` |
| `maxResults` | integer | `100` | Maximum results (1–100,000) |
| `includeComments` | boolean | `true` | Include comments when scraping posts |
| `maxCommentsPerPost` | integer | `100` | Max comments per post (0–10,000) |
| `commentDepth` | integer | `10` | Max reply nesting depth (1–20) |
| `includeNsfw` | boolean | `false` | Include NSFW content |
| `minScore` | integer | — | Minimum post/comment score |
| `excludeAuthors` | string\[] | `["AutoModerator", "[deleted]"]` | Authors to exclude |
| `flattenComments` | boolean | `false` | Flatten comment trees to a flat list |
| `proxyConfiguration` | object | Apify residential | Proxy settings |

### Output Format

Each post includes full metadata, media, and optionally a threaded comment tree:

```json
{
    "id": "t3_abc123",
    "title": "Example Post Title",
    "body": "Post body text in markdown...",
    "author": "reddit_user",
    "subreddit": "technology",
    "score": 1542,
    "upvoteRatio": 0.94,
    "numComments": 231,
    "createdUtc": "2024-01-15T10:30:00.000Z",
    "isNsfw": false,
    "media": {
        "type": "image",
        "images": [{ "url": "https://...", "width": 1920, "height": 1080, "caption": null }],
        "video": null,
        "embed": null
    },
    "comments": [
        {
            "id": "t1_xyz789",
            "author": "commenter",
            "body": "Great post!",
            "score": 45,
            "depth": 0,
            "isOp": false,
            "replies": [
                {
                    "id": "t1_abc456",
                    "body": "Thanks!",
                    "depth": 1,
                    "replies": []
                }
            ]
        }
    ]
}
```

Comments maintain full tree structure with `replies` arrays. Set `flattenComments: true` for a flat list with `depth` and `parentId` fields for CSV/spreadsheet use.

### Tips and Best Practices

**Rate limiting:** Reddit aggressively rate-limits scrapers. The default `requestDelay` of 1000ms is a safe baseline. Lower values increase speed but risk 429 errors. The actor handles rate limits automatically with exponential backoff.

**Proxy selection:** Reddit blocks datacenter proxies. Use residential proxies (the default) for reliable scraping. The actor rotates IPs on rate limit responses.

**Public feed fallback:** For public subreddit post listings, the actor falls back to Reddit's public Atom feed when anonymous JSON access returns 403. The feed preserves titles, authors, permalinks, timestamps, and post content, but it does not expose score, comment-count, or award metrics. Those fields remain zero or empty unless the JSON path succeeds.

**Large subreddits:** For subreddits with millions of posts, use `sort: "top"` with a `timeFilter` to get manageable result sets. Scraping all of r/AskReddit would take days — filter first.

**NSFW filtering:** NSFW content is excluded by default. Set `includeNsfw: true` to include it. When scraping NSFW subreddits with the default setting, zero results are returned.

**Comment threading:** Comments are returned as a tree by default. Each comment has a `replies` array containing child comments. Use `flattenComments: true` if you need a flat structure for data analysis.

### Pricing

Pay-Per-Event in the queued monetization update: **$2.60 per 1,000 results**.

A "result" is one successfully scraped item pushed to the dataset. A post counts as 1 result, a separately pushed comment row counts as 1 result, and a subreddit or user object counts as 1 result. Comments nested inside a post row are included with that post and do not create additional events; use the comments mode with flattened output when you need one billable dataset row per comment.

| Scenario | Items | Cost |
|----------|-------|------|
| 100 posts, no comments | 100 | $0.26 |
| 100 posts with nested comments | 100 | $0.26 |
| 100 posts + 2,000 separately pushed comments | 2,100 | $5.46 |
| Brand monitoring (500 mentions/week) | 500 | $1.30/week |
| Subreddit metadata (10 subreddits) | 10 | $0.03 |
| Full thread exported as 1 post + 5K flattened comment rows | 5,001 | $13.00 |

Items filtered out by score, NSFW, author, or flair filters are NOT billed. Failed requests are NOT billed.

### FAQ

#### Does this require a Reddit API key?

No. This actor scrapes Reddit's web interface directly. No API key, no OAuth setup, no Reddit developer account needed. It works out of the box.

#### How does it handle Reddit's rate limiting?

The actor uses exponential backoff when Reddit returns 429 (Too Many Requests) responses. It starts with a 5-second delay and increases to 60 seconds, with random jitter to avoid thundering herd patterns. Proxy IPs are rotated on rate limit hits.

#### Can I scrape private subreddits?

No. Private subreddits require Reddit account authentication, which this actor does not support. The actor detects private subreddits and reports them as errors without wasting retries.

#### How do I filter NSFW content?

NSFW content is excluded by default (`includeNsfw: false`). Set `includeNsfw: true` to include it. When scraping a known NSFW subreddit with the default setting, you will get zero results.

#### Does it work for non-English subreddits?

Yes. The actor supports full UTF-8 content including emoji, CJK characters, and other scripts. Content is preserved exactly as posted on Reddit.

#### Can I download images and videos?

The actor extracts media URLs (images, videos, galleries) by default. Direct download to the Apify key-value store is not currently supported — use the extracted URLs with a separate download tool.

#### What happens if Reddit blocks the scraper?

The actor detects anti-bot pages and retries with different proxy IPs. With residential proxies (the default), blocks are rare. If all retries fail, the URL is logged in the run summary's `failedUrls` array.

#### How are comments structured?

Comments are returned as a tree by default. Each comment has a `replies` array containing nested child comments, preserving Reddit's thread structure. The `depth` field indicates nesting level (0 = top-level). Set `flattenComments: true` for a flat list.

# Actor input Schema

## `scrapeType` (type: `string`):

What type of content to scrape from Reddit.

## `urls` (type: `array`):

Direct Reddit URLs to scrape. Accepts post URLs, subreddit URLs, user profile URLs. Required unless using search or subreddits parameter.

## `searchQuery` (type: `string`):

Search query string. Required when scrapeType is 'search'.

## `subreddits` (type: `array`):

Subreddit names (without r/). Used with scrapeType 'posts' or 'search'.

## `sort` (type: `string`):

Sort order for posts and search results.

## `timeFilter` (type: `string`):

Time filter for 'top' and 'controversial' sorts.

## `maxResults` (type: `integer`):

Maximum number of results to return.

## `maxAge` (type: `string`):

Only return posts newer than this duration. Format: '24h', '7d', '30d', '1y'.

## `includeComments` (type: `boolean`):

Include comments when scraping posts.

## `maxCommentsPerPost` (type: `integer`):

Maximum comments to extract per post.

## `commentSort` (type: `string`):

Sort order for comments.

## `commentDepth` (type: `integer`):

Maximum reply depth to follow.

## `expandMoreComments` (type: `boolean`):

Follow 'load more comments' / 'continue this thread' links.

## `includeNsfw` (type: `boolean`):

Include NSFW (Not Safe For Work) content. Default excludes it.

## `minScore` (type: `integer`):

Only include posts/comments with score >= this value.

## `minComments` (type: `integer`):

Only include posts with >= this many comments.

## `flairFilter` (type: `array`):

Only include posts with these flair texts (case-insensitive).

## `authorFilter` (type: `array`):

Only include posts/comments by these usernames.

## `excludeAuthors` (type: `array`):

Exclude posts/comments from these usernames.

## `contentContains` (type: `array`):

Only include posts where title or body contains any of these strings (case-insensitive).

## `excludeStickied` (type: `boolean`):

Exclude stickied/pinned posts.

## `mediaType` (type: `string`):

Filter posts by media type.

## `extractMedia` (type: `boolean`):

Extract media URLs (images, videos, galleries).

## `includeRawHtml` (type: `boolean`):

Include raw HTML of post/comment body alongside markdown.

## `flattenComments` (type: `boolean`):

Output comments as flat list instead of tree. Useful for CSV/spreadsheet analysis.

## `requestDelay` (type: `integer`):

Minimum delay between requests in milliseconds. Reddit is aggressive on rate limiting.

## `maxConcurrency` (type: `integer`):

Maximum number of concurrent requests.

## `maxRetries` (type: `integer`):

Maximum number of retries for failed requests.

## `proxyConfiguration` (type: `object`):

Proxy settings. Reddit requires residential proxies for reliable scraping.

## Actor input object example

```json
{
  "scrapeType": "posts",
  "urls": [
    "https://www.reddit.com/r/technology/"
  ],
  "sort": "hot",
  "timeFilter": "all",
  "maxResults": 1,
  "includeComments": false,
  "maxCommentsPerPost": 0,
  "commentSort": "best",
  "commentDepth": 3,
  "expandMoreComments": false,
  "includeNsfw": false,
  "excludeAuthors": [
    "AutoModerator",
    "[deleted]"
  ],
  "excludeStickied": false,
  "mediaType": "all",
  "extractMedia": true,
  "includeRawHtml": false,
  "flattenComments": false,
  "requestDelay": 1000,
  "maxConcurrency": 2,
  "maxRetries": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Reddit posts, comments, user profiles, or subreddit data with full metadata, comment trees, and media extraction.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "scrapeType": "posts",
    "urls": [
        "https://www.reddit.com/r/technology/"
    ],
    "maxResults": 1,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("junipr/reddit-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "scrapeType": "posts",
    "urls": ["https://www.reddit.com/r/technology/"],
    "maxResults": 1,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("junipr/reddit-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "scrapeType": "posts",
  "urls": [
    "https://www.reddit.com/r/technology/"
  ],
  "maxResults": 1,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call junipr/reddit-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=junipr/reddit-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/h7Deg2uR7UDjhLIJJ/builds/nWCpaKEUV7PLT2xz8/openapi.json
