# Reddit Public Post & Comment Scraper (`technicaldost/reddit-public-content-scraper`) Actor

Scrape public Reddit posts and comments by subreddit, search term or URL. Get title, text, author, score, awards and timestamps. Perfect for research and social listening. JSON output.

- **URL**: https://apify.com/technicaldost/reddit-public-content-scraper.md
- **Developed by:** [Technical Dost Solutions](https://apify.com/technicaldost) (community)
- **Categories:** Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 results

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 Public Post & Comment Scraper

### What this Actor does

Extract public Reddit post data from subreddit listing pages and post permalinks as clean, structured JSON.

It processes user-provided public Reddit URLs (subreddit listings such as `https://www.reddit.com/r/webscraping/`, or individual post permalinks), prioritizes JSON-LD / schema.org structured data (`DiscussionForumPosting` / `SocialMediaPosting`), and can optionally use a conservative fallback that reads visible public post rows. It normalizes useful fields, applies an optional keyword filter, deduplicates rows by permalink, and saves structured records to the Apify dataset.

### Why this Actor is useful

Researchers, analysts, and marketers use this kind of extraction to replace manual browsing, create repeatable monitoring, feed spreadsheets and dashboards, and turn scattered public Reddit pages into a clean, API-ready dataset.

### Who this is for

- Market and trend researchers
- Community and brand analysts
- Content and social media teams
- Product and UX researchers
- Data teams building public-signal datasets

### Common use cases

- Track new posts across one or more public subreddits
- Filter posts by keyword (e.g. "pricing", "review")
- Feed a research dataset or dashboard with fresh public posts
- Monitor a specific subreddit or topic over time
- Build recurring public discussion-intelligence datasets

### Input

| Field | Type | Description |
| --- | --- | --- |
| `startUrls` | array (required) | Public Reddit subreddit listing pages or post permalinks. Use only pages you may access without login or bypassing access controls. |
| `keywords` | array of strings | Optional keywords. Only posts whose title or text contains at least one keyword (case-insensitive) are kept. Empty = no filter. |
| `maxItems` | integer | Maximum rows to save. Default 50, min 1, max 10000. |
| `maxConcurrency` | integer | Pages processed in parallel. Default 3, min 1, max 20. |
| `extractionMode` | string | `structuredDataOnly` or `structuredDataWithFallback` (default). The fallback safely reads visible public post rows. |
| `requestTimeoutSecs` | integer | Maximum time per page. Default 30, min 5, max 180. |
| `proxyConfiguration` | object | Optional Apify proxy configuration where permitted by your source review. |

### Output

| Field | Description |
| --- | --- |
| `postTitle` | Title of the Reddit post. |
| `subreddit` | Subreddit name parsed from the URL (e.g. `webscraping`). |
| `author` | Post author username when available. |
| `score` | Post score / upvotes when published in structured data. |
| `upvoteRatio` | Upvote ratio when available. |
| `numComments` | Number of comments when available. |
| `postText` | Body text of the post when available. |
| `postUrl` | Public URL of the post. |
| `permalink` | Reddit permalink of the post. |
| `createdDate` | Date the post was published. |
| `flair` | Post flair / section when available. |
| `sourceUrl` | URL where the data was extracted. |
| `detectedAt` | Timestamp when this Actor extracted the row. |
| `extractionMethod` | `structured_data` for schema data, or `fallback_public_reddit_listing` for visible public listings. |
| `confidenceScore` | Heuristic confidence based on structured data availability and completeness. |
| `missingFields` | Required fields that were not available from the source page. |

### Sample input

```json
{
  "startUrls": [
    {
      "url": "https://www.reddit.com/r/webscraping/"
    }
  ],
  "keywords": ["pricing", "review"],
  "maxItems": 25,
  "maxConcurrency": 3,
  "extractionMode": "structuredDataWithFallback",
  "requestTimeoutSecs": 30
}
```

### Sample output

```json
{
  "postTitle": "How I built a resilient scraper for public listings",
  "subreddit": "webscraping",
  "author": "example_user",
  "score": 128,
  "upvoteRatio": null,
  "numComments": 34,
  "postText": "Sharing my approach to structured-data-first extraction...",
  "postUrl": "https://www.reddit.com/r/webscraping/comments/abc123/how_i_built_a_resilient_scraper/",
  "permalink": "https://www.reddit.com/r/webscraping/comments/abc123/how_i_built_a_resilient_scraper/",
  "createdDate": "2026-06-15T00:00:00.000Z",
  "flair": "Tutorial",
  "sourceUrl": "https://www.reddit.com/r/webscraping/",
  "detectedAt": "2026-06-27T00:00:00.000Z",
  "extractionMethod": "structured_data",
  "confidenceScore": 0.95,
  "missingFields": []
}
```

### Pricing

This Actor uses a pay-per-event model: **$0.005 per post result** saved to the dataset. You pay only for the structured post rows you receive, which makes recurring monitoring predictable and low-cost.

### How to use

Run this Actor on Apify with public Reddit URLs, export the dataset as JSON, CSV, or Excel, or pull it through the Apify API. Connect the output to Google Sheets, Make, Zapier, a webhook, or an internal dashboard. For monitoring, save the input as an Apify task and schedule recurring runs.

**Tip:** Reddit URLs can be appended with `.json` to return raw API data, but this Actor is designed to parse the standard public HTML pages you view in a browser. Provide the normal page URLs (for example `https://www.reddit.com/r/webscraping/`).

### Best practices

- Start with a small set of reviewed public subreddit or post URLs.
- Use `keywords` to focus on the topics you care about.
- Use `structuredDataOnly` for highest precision; use `structuredDataWithFallback` for pages that only render visible post rows.
- Keep `maxConcurrency` low for cautious, low-footprint runs.
- Review Reddit's rules and terms before scheduling recurring runs.

### Compliance and responsible use

This Actor is for public data only. It must not be used to bypass logins, paywalls, CAPTCHAs, or security systems, to collect private or sensitive personal data, or to support spam or abuse. Only public Reddit pages should be processed here. You are responsible for following applicable laws and Reddit's rules and terms of service.

### Limitations

- Output quality depends on the public structured data available on the source pages.
- Fallback extraction is intentionally conservative and only looks for visible public post-row patterns. It does not claim universal support.
- Dates and counts are extracted as published and are not reformatted or converted.
- Some fields may be empty when the source does not publish them; these appear in `missingFields`.
- Website markup and access policies can change.

### Troubleshooting

- Empty output usually means the page has no public structured post data and no visible post-row patterns.
- Invalid URL errors mean one or more input URLs are malformed.
- Slow runs can usually be improved by lowering `maxConcurrency`.
- Missing fields are source-data limitations, not inferred values.

### Changelog

- v0.1.0: Initial release with structured-data-first extraction, conservative public post-listing fallback, keyword filtering, and confidence scoring.

# Actor input Schema

## `startUrls` (type: `array`):

Public Reddit subreddit listing pages or post permalinks to extract from. Use only URLs you are allowed to access without login, paywall bypass, CAPTCHA bypass, or security circumvention.

## `keywords` (type: `array`):

Optional list of keywords. Only posts whose title or text contains at least one keyword (case-insensitive) are kept. Leave empty to keep all posts.

## `maxItems` (type: `integer`):

Maximum number of normalized post rows to save. The Actor stops pushing new rows when this limit is reached.

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

How many pages to process at once. Lower this for cautious, low-footprint runs.

## `extractionMode` (type: `string`):

Use structured data only, or allow a conservative fallback for visible public post rows on Reddit listing pages.

## `requestTimeoutSecs` (type: `integer`):

Maximum time to spend processing a single page before it is treated as failed.

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

Optional Apify proxy configuration. Use only where permitted by the source website and your compliance process.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.reddit.com/r/webscraping/"
    }
  ],
  "keywords": [],
  "maxItems": 50,
  "maxConcurrency": 3,
  "extractionMode": "structuredDataWithFallback",
  "requestTimeoutSecs": 30
}
```

# 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 = {
    "startUrls": [
        {
            "url": "https://www.reddit.com/r/webscraping/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("technicaldost/reddit-public-content-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 = { "startUrls": [{ "url": "https://www.reddit.com/r/webscraping/" }] }

# Run the Actor and wait for it to finish
run = client.actor("technicaldost/reddit-public-content-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 '{
  "startUrls": [
    {
      "url": "https://www.reddit.com/r/webscraping/"
    }
  ]
}' |
apify call technicaldost/reddit-public-content-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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