# Disqus Comments Scraper - Comments, Replies & Threads (`scrapewise/disqus-comments-scraper`) Actor

Scrape Disqus comments from any article URL, forum shortname or thread id: text, HTML, replies (parent), date, likes, edited and deleted flags, author display name. List a whole forum's discussions. Schedule it: only new comments. No login. Error rows are free.

- **URL**: https://apify.com/scrapewise/disqus-comments-scraper.md
- **Developed by:** [Scrapewise Data](https://apify.com/scrapewise) (community)
- **Categories:** Social media, News
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.85 / 1,000 comment delivereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Disqus Comments Scraper: comments, replies and discussions from any site

Export **Disqus comments** from any website that uses Disqus, **without an account, API key or browser**. Paste an
article URL, a forum shortname or a thread id. Every comment comes with its text (plain and HTML), date, likes and
dislikes, the **reply chain** (`parentId`), edited, deleted and approved flags, the author's display name and the
discussion it belongs to.

Read a **whole site at once**: the newest comments across every article, or the list of discussions with their
comment counts (newest or most commented), with or without their comments. Built for **monitoring**: schedule it and
get **only the comments posted since the last run**. A quiet day costs nothing.

### At a glance

- **Price per 1,000 comments, Free plan:** US$ 1.00
- **Discussion row (title, link, comment count):** US$ 1.00 per 1,000
- **Fee per run start:** None
- **Input by article URL, forum shortname or thread id:** Yes
- **Whole forum: newest comments, or discussions with comment counts:** Yes
- **Most commented discussions (24 h, 7, 30, 90 days):** Yes
- **Reply chain (`parentId`, `isReply`):** Yes
- **Only new comments since the last run (`onlyNew`):** Yes, free when nothing is new
- **Author data:** display name only (see below)
- **Error rows (bad input, page without Disqus, unknown forum):** Free, with an `errorCode`

### Real rows

From a test run on 2026-10-06 (an article URL on Wccftech, oldest first), shortened. The discussion:

```json
{
  "type": "thread",
  "threadId": "11489208382",
  "forum": "wccftech",
  "title": "PNY Denied Warranty To An RTX 5090 Owner Because Dead GPU Wasn't Used With Company-Approved 12VHPWR Power Cable Or Adapter; Documentation Mentions No Such Clause",
  "url": "https://wccftech.com/pny-denies-rtx-5090-warranty-non-approved-12vhpwr-cable/",
  "identifiers": ["1747294"],
  "commentCount": 1343,
  "likes": 1,
  "createdAt": "2026-09-24T19:02:40Z",
  "isClosed": false
}
```

One of its comments, a reply:

```json
{
  "type": "comment",
  "commentId": "6937898365",
  "threadId": "11489208382",
  "threadUrl": "https://wccftech.com/pny-denies-rtx-5090-warranty-non-approved-12vhpwr-cable/",
  "commentUrl": "https://wccftech.com/pny-denies-rtx-5090-warranty-non-approved-12vhpwr-cable/#comment-6937898365",
  "forum": "wccftech",
  "parentId": "6937896653",
  "isReply": true,
  "createdAt": "2026-09-24T19:14:04Z",
  "authorName": "VoiceOfLogic",
  "text": "LMAO, it's never nVIDIA's fault, right?\n😂",
  "html": "<p>LMAO, it's never nVIDIA's fault, right?<br>😂</p>",
  "likes": 9,
  "dislikes": 0,
  "isEdited": false,
  "isDeleted": false,
  "isApproved": true,
  "mediaUrls": []
}
```

### What you can do with it

- **Media and brand monitoring:** follow what readers say about your brand, product or topic on news and tech sites
  that still run Disqus, every day, with only the new comments.
- **Sentiment and opinion research:** thousands of real reader comments per article, with likes and the reply
  chain, ready for sentiment analysis, topic models and LLM summaries.
- **Community managers and publishers:** export your own site's whole comment history before a migration, a
  redesign or a moderation audit, discussion by discussion, in the order of the conversation.
- **Academic research:** public discourse datasets with timestamps, threading and engagement, per article or for a
  whole site.
- **AI and RAG:** clean plain text plus the original HTML, one row per comment.

### Input

| Field | What it does |
|---|---|
| `startUrls` | Article or page URLs with Disqus comments. With or without `https://`; the Actor finds the discussion by itself |
| `forums` | Forum shortnames: the part before `.disqus.com` in the site's `embed.js` (for example `wccftech`). Upper case, spaces and `https://name.disqus.com` links are fine |
| `threadIds` | Numeric Disqus thread ids (the `threadId` column) |
| `forumMode` | For forums: `latestComments` (default, newest comments across the site), `threads` (one row per discussion), `threadsWithComments` |
| `threadSort` | For the discussion modes: `newest` (default), `popular1d`, `popular7d`, `popular30d`, `popular90d` (most commented in the period) |
| `maxThreads` | Discussions per forum, default 10. 0 = up to 10,000 |
| `maxComments` | Comments per URL, per thread, per discussion (in `threadsWithComments`) or per forum (in `latestComments`), default 100. 0 = all, up to 50,000 |
| `commentOrder` | `newest` (default) or `oldest` (the order of the conversation) |
| `commentsSince` | Only comments from this date (`2026-10-01`) or period (`7 days`, `24 hours`) |
| `onlyNew` | Deliver only comments posted after the newest one delivered in earlier runs |
| `requestDelaySecs` | Pause between Disqus requests, default 1 second |
| `proxyConfiguration` | Off by default; Apify Proxy (datacenter) spreads very large exports over several IPs |

Every comment of one article, in the order of the conversation:

```json
{
  "startUrls": ["https://wccftech.com/pny-denies-rtx-5090-warranty-non-approved-12vhpwr-cable/"],
  "maxComments": 0,
  "commentOrder": "oldest"
}
```

The newest comments across a whole site, every hour, only the new ones:

```json
{
  "forums": ["wccftech"],
  "forumMode": "latestComments",
  "maxComments": 1000,
  "onlyNew": true
}
```

The 20 most commented discussions of the week, each with its top 200 comments:

```json
{
  "forums": ["wccftech"],
  "forumMode": "threadsWithComments",
  "threadSort": "popular7d",
  "maxThreads": 20,
  "maxComments": 200
}
```

### How to find a forum shortname

You usually do not need it: paste an article URL and the Actor finds the discussion. For a whole site, open any
article, view the page source and look for `something.disqus.com/embed.js` or `disqus_shortname`; `something` is the
shortname. Pasting the website address in `forums` also works when its pages load Disqus in the usual way.

### How monitoring works

With `onlyNew`, the Actor remembers the newest comment it delivered for each article, thread and forum in a named
key-value store in your own account, `disqus-comments-scraper-state`. Disqus comment ids grow over time, so the next
run reads newest first and stops at the first comment it already delivered.

- The first run delivers up to `maxComments`. Later runs deliver only newer comments.
- Discussion rows come back only when the discussion is new or has new comments.
- In the discussion modes, discussions whose comment count did not change are skipped without a request.
- A run with nothing new delivers nothing and costs nothing. Delete the key-value store to start over.

### Output

Comment rows (`type: "comment"`): `commentId`, `threadId`, `threadTitle`, `threadUrl`, `commentUrl`, `forum`,
`parentId` (the comment it replies to, or null), `isReply`, `createdAt` (UTC), `authorName`, `text` (plain text),
`html`, `likes`, `dislikes`, `isEdited`, `isDeleted`, `isDeletedByAuthor`, `isApproved`, `isSpam`, `isHighlighted`
(pinned by the moderators), `mediaUrls` (images and links attached to the comment), `input`, `scrapedAt`.

Discussion rows (`type: "thread"`): `threadId`, `forum`, `title`, `url`, `identifiers` (the site's own ids),
`commentCount`, `likes`, `dislikes`, `createdAt` (UTC), `isClosed`, `isDeleted`, `feedUrl` (the discussion's RSS),
`input`, `scrapedAt`.

**Author data, by design: display name only.** No username, user id, avatar, profile link or location of
commenters is returned. Use `commentUrl` to see the comment on the site.

### Error codes (never charged)

| `errorCode` | Meaning |
|---|---|
| `INVALID_INPUT` | A value the Actor does not understand (unknown mode, a thread id that is not a number, an empty URL) |
| `NOT_FOUND` | The page has no Disqus discussion, the forum or the thread does not exist |
| `NO_RESULTS` | The forum has no comments or no discussion for the chosen period |
| `RATE_LIMITED` | Disqus kept answering with its rate limit after waits and IP changes; run again or raise `requestDelaySecs` |
| `KEY_REJECTED` | Disqus refused its public key and the key its embed uses today |
| `NETWORK` | Disqus did not answer after several tries |
| `NOT_REACHED` | The run timeout arrived before this input |
| `TIMEOUT_TOO_SHORT` | The run timeout was too short to read even one page; raise it |
| `UNEXPECTED` | Data came in a shape we did not expect; the rest of the run goes on |

### Pricing

| Event | Per 1,000 |
|---|---|
| Comment delivered | US$ 1.00 |
| Discussion delivered | US$ 1.00 |

An article with 1,343 comments costs US$ 1.34 for the comments plus US$ 0.001 for its discussion row. An hourly
`onlyNew` run on a busy site that finds 80 new comments costs US$ 0.08. Error rows, duplicates and comments already
delivered are free, and there is no start fee.

### Limitations

- The Actor reads the same public data the Disqus widget shows to every visitor. Comments waiting for moderation,
  and private or members-only discussions, are not returned.
- A page is matched to its discussion by its exact address (common variants such as `http`, `www` and a trailing
  slash are tried). Sites that load Disqus only after a cookie banner are found through the URL anyway; if a page is
  not found, use the forum shortname.
- `onlyNew` follows the newest comment delivered. A comment approved by a moderator long after it was written can
  be older than that mark and is then not delivered as new. With a limit, a burst of more new comments than
  `maxComments` delivers the newest ones.
- The discussion modes list discussions by creation date or by Disqus' own popular list; very old discussions are
  reached only with a high `maxThreads` or by their URL or thread id.
- Big exports take time: Disqus returns 100 comments per request and the Actor pauses between requests to stay
  inside the public limit (about 35,000 comments in 15 minutes with a 2.5 s pause in our tests).

### FAQ

**Do I need a Disqus account or API key?** No.

**Which sites use Disqus?** Many news, tech, gaming and niche publishers and blogs. Wccftech is one
example.

**Can I get the reply tree?** Yes. Every comment has `parentId`; with `commentOrder: "oldest"` parents come before
their replies, so you can rebuild the tree row by row.

**Why is `text` sometimes empty?** The comment was deleted (`isDeleted: true`) or is only an image (see `mediaUrls`).

**Can I use it from n8n, Make, Zapier or an AI agent?** Yes, through the Apify app or the Apify MCP server. Error
rows are free, so an agent can explore cheaply.

**What if a run is cut by its timeout?** The Actor stops shortly before the limit and ends successfully with what it
delivered, telling you in the status message how to get the rest.

### Changelog

- **0.1 (2026-10-07):** first version. Article URL, forum shortname or thread id; newest comments across a forum;
  discussions with comment counts (newest or most commented); comments with reply chain, likes, flags and plain text;
  `onlyNew` and `commentsSince` for schedules; free error rows.

# Actor input Schema

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

Article or page URLs that show Disqus comments, one per line, for example https://wccftech.com/pny-denies-rtx-5090-warranty-non-approved-12vhpwr-cable/. With or without https://. The Actor finds the page's Disqus discussion by itself and returns its comments, each charged as 'Comment delivered'. A forum shortname or a numeric thread id pasted here also works.

## `forums` (type: `array`):

Disqus forum shortnames to read a whole site, one per line: the part before .disqus.com in the site's embed.js, for example wccftech. Upper case, spaces and full links like https://wccftech.disqus.com are fine; a website address works too when its pages load Disqus. What comes back depends on 'Forum mode' below.

## `threadIds` (type: `array`):

Numeric Disqus thread ids, one per line, for example 11489208382 (the threadId column of an earlier run). Faster than a page URL because the discussion does not need to be looked up.

## `forumMode` (type: `string`):

Only for forum shortnames. Latest comments (default) = the newest comments across the whole site, each with its discussion title and link; one request per 100 comments and the best choice for daily monitoring. Discussions only = one row per discussion with title, link, comment count, date and likes, charged as 'Discussion delivered'. Discussions with comments = each discussion row followed by its comments (up to 'Max comments' per discussion).

## `threadSort` (type: `string`):

Which discussions the two discussion modes read: Newest (default, the most recently created), or Most commented in the last 24 hours, 7, 30 or 90 days (Disqus' own popular list, up to 100 discussions).

## `maxThreads` (type: `integer`):

How many discussions to read per forum in the two discussion modes, for example 10 (default). 0 = up to 10,000. Each discussion row is charged, and in 'Discussions with comments' its comments are charged too, so this drives most of the cost.

## `maxComments` (type: `integer`):

Comments per page URL or thread id, per discussion in 'Discussions with comments', and per forum in 'Latest comments', for example 100 (default). Disqus returns 100 per request. 0 = all (up to 50,000). You pay per comment delivered.

## `commentOrder` (type: `string`):

Newest first (default), or Oldest first (the order of the conversation, good for full exports). With a limit it also decides which comments you get. 'Only new comments' and 'Comments since' always read newest first.

## `commentsSince` (type: `string`):

Only comments posted on or after this moment (UTC): a date such as 2026-10-01, or a period such as 7 days or 24 hours. Reading stops as soon as older comments are reached, so it also saves time. Empty = all dates.

## `onlyNew` (type: `boolean`):

For scheduled runs. Remembers the newest comment delivered for each page, thread and forum in a named key-value store in your account ('disqus-comments-scraper-state') and delivers only comments posted after it. The first run delivers up to the limit. Discussion rows come back only when the discussion is new or has new comments. Nothing new = nothing charged. Delete the store to start over.

## `requestDelaySecs` (type: `number`):

Pause in seconds between Disqus API requests, from 0 to 60 (default 1). The default stays well inside the public limit; if Disqus answers with a rate limit, the Actor waits, doubles the pause and, when it can, switches IP. Raise it for very large exports.

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

Off by default and usually not needed: the Disqus API answers datacenter IPs. Turn on Apify Proxy (datacenter) to spread very large exports over several IPs. Without it, the Actor switches to the datacenter proxy on its own if Disqus rate-limits the run's IP and your account has it.

## Actor input object example

```json
{
  "startUrls": [
    "https://wccftech.com/pny-denies-rtx-5090-warranty-non-approved-12vhpwr-cable/"
  ],
  "forumMode": "latestComments",
  "threadSort": "newest",
  "maxThreads": 10,
  "maxComments": 100,
  "commentOrder": "newest",
  "onlyNew": false,
  "requestDelaySecs": 1,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

## `resultsCsv` (type: `string`):

No description

# 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": [
        "https://wccftech.com/pny-denies-rtx-5090-warranty-non-approved-12vhpwr-cable/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/disqus-comments-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": ["https://wccftech.com/pny-denies-rtx-5090-warranty-non-approved-12vhpwr-cable/"] }

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

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).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": [
    "https://wccftech.com/pny-denies-rtx-5090-warranty-non-approved-12vhpwr-cable/"
  ]
}' |
apify call scrapewise/disqus-comments-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapewise/disqus-comments-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/xhmlNfYpZTdysXfzf/builds/fKiuAXO1JJVlpahvC/openapi.json
