# PissedConsumer Scraper (`memo23/pissedconsumer-scraper`) Actor

Scrape complaints and reviews from PissedConsumer.com — author, rating, date, headline, full text, location, comments, photos, company address and video. Search by company page, category, or keyword. Optional full complaint details. JSON/CSV export.

- **URL**: https://apify.com/memo23/pissedconsumer-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** E-commerce, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 complaints

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

## PissedConsumer Scraper — Complaints & Reviews Extractor

Extract structured consumer complaints and reviews from **PissedConsumer.com** at scale. Give the actor a company page, a category, a search keyword, or a direct complaint URL and it returns one clean row per complaint: author, rating, date, headline, full text, location, comments, photos, and (on detail pages) pros, cons, monetary loss, preferred solution, company address, and video.

### Why use this PissedConsumer Scraper

PissedConsumer is one of the largest consumer-complaint databases on the web — over a million reviews across tens of thousands of companies. This actor turns those unstructured review pages into clean, analyst-ready rows without a browser, without an account, and without anti-bot workarounds.

- One row per complaint, with the full review body and inline comments.
- Company pages, category indexes, keyword search, and direct complaint URLs all supported.
- Detail pages add pros, cons, monetary loss, preferred solution, company address, all photos, and embedded video.
- Sliding-window concurrency with per-request proxy rotation for throughput.
- No login, no cookies, no headless browser — fast and cheap to run.

### Overview

PissedConsumer.com (operated by Opinion Corp.) lets consumers publish complaints and reviews about any company. Each company has a listing page (`{slug}.pissedconsumer.com/review.html`) with paginated review snippets; each individual complaint has a detail page with the full review, pros/cons, monetary loss, preferred solution, company address, photos, video, and threaded comments. The site exposes rich schema.org microdata on every page, which this actor parses directly.

### Supported inputs

| You provide | Example |
|---|---|
| A company page URL | `https://amazon.pissedconsumer.com/review.html` |
| A category URL | `https://www.pissedconsumer.com/search-companies/category/electronics.html` |
| A search URL | `https://www.pissedconsumer.com/browse-reviews.html?query=Temu` |
| A search keyword | `Temu` |
| A direct complaint URL | `https://amazon.pissedconsumer.com/{complaint-slug}-{id}.html` |

Company, category, and search URLs are expanded into company listing pages automatically. Direct complaint URLs return the full detail row (pros, cons, monetary loss, company address, video, all photos).

### Use cases

- Build a consumer-sentiment dataset for a brand or category.
- Track complaint volume, ratings, and themes for competitor companies over time.
- Enrich a lead-generation pipeline with company addresses and complaint context.
- Surface recurring product or service issues (pros/cons, monetary loss, preferred solution).
- Feed a reputation-monitoring or review-aggregation product.

### How it works

1. You supply one or more start URLs and/or a search keyword.
2. The actor resolves category and search URLs into company listing pages.
3. For each company, it pages through the listing (`rel="next"`), parsing each Review microdata block into a complaint row.
4. Direct complaint URLs are fetched as detail pages, adding pros, cons, monetary loss, preferred solution, company address, all photos, and video.
5. Each complaint is written to the dataset as one clean row.

### Input configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | — | PissedConsumer URLs: company pages, category pages, search URLs, or direct complaint pages. |
| `searchQuery` | string | — | Search PissedConsumer for companies by name (e.g. `Amazon`). |
| `maxItems` | integer | `1000` | Maximum complaints to scrape. |
| `maxPages` | integer | `0` | Max listing pages per company (0 = unlimited). |
| `maxConcurrency` | integer | `10` | Pages fetched in parallel. |
| `proxy` | object | built-in | Optional proxy override; the actor ships with residential proxy support. |

### Output overview

One dataset item per complaint. Example (trimmed) for a listing-level row:

```json
{
  "source": "listing",
  "companyName": "Amazon",
  "companySlug": "amazon",
  "complaintId": "202512187009405",
  "url": "https://amazon.pissedconsumer.com/they-canceled-claim-whet-i-have-in-writing-202512187009405.html",
  "author": "Mark s Ohy",
  "authorUrl": "https://www.pissedconsumer.com/people/29624045.html",
  "verifiedReviewer": true,
  "rating": 1,
  "bestRating": 5,
  "headline": "They canceled claim whet I have in writing",
  "reviewBody": "First, I put an order in. I didn't even know it was through a third party...",
  "datePublished": "2025-12-18 09:16:19",
  "location": "Boise, Idaho",
  "commentCount": 4,
  "upvoteCount": 5,
  "comments": [
    { "author": "Guest-2983222", "date": "2026-07-18 22:25:44", "text": "...", "upvoteCount": 5 }
  ],
  "featured": true
}
```

Example (trimmed) for a detail-level row from a direct complaint URL:

```json
{
  "source": "detail",
  "companyName": "Amazon",
  "companySlug": "amazon",
  "complaintId": "202512187009405",
  "url": "https://amazon.pissedconsumer.com/they-canceled-claim-whet-i-have-in-writing-202512187009405.html",
  "author": "Mark s Ohy",
  "rating": 1,
  "headline": "They canceled claim whet I have in writing",
  "reviewBody": "...",
  "datePublished": "2025-12-18 09:16:19",
  "location": "Boise, Idaho",
  "pros": "Large selection, Easy to find items decent prices.",
  "cons": "Customer service is horrible, Quality has gone down.",
  "monetaryLoss": "$236.",
  "preferredSolution": "Full refund.",
  "commentCount": 4,
  "viewCount": "1.1K views",
  "images": ["https://cdn0.opinion-corp.com/..."],
  "video": { "contentUrl": "https://youtube.com/embed/...", "thumbnailUrl": "https://img.youtube.com/.../hqdefault.jpg" },
  "comments": [ ... ]
}
```

### Output fields

| Field | Type | Description |
|---|---|---|
| `source` | string | `listing` or `detail`. |
| `companyName` | string | Reviewed company name. |
| `companySlug` | string | Company subdomain slug. |
| `complaintId` | string | PissedConsumer complaint ID. |
| `url` | string | Complaint page URL (null on listing rows without a direct link). |
| `author` | string | Reviewer display name. |
| `authorUrl` | string | Reviewer profile URL. |
| `verifiedReviewer` | boolean | Whether the reviewer is verified. |
| `rating` | number | Star rating (1–5). |
| `bestRating` | number | Always 5. |
| `headline` | string | Complaint headline. |
| `reviewBody` | string | Full complaint text. |
| `datePublished` | string | Publication timestamp. |
| `dateModified` | string | Last-modified timestamp (detail only). |
| `location` | string | Reviewer location. |
| `commentCount` | number | Number of comments. |
| `viewCount` | string | View count (detail only). |
| `upvoteCount` | number | Upvotes on the review. |
| `comments` | array | Inline comments (author, date, text, upvoteCount). |
| `images` | array | Photo URLs (detail only). |
| `video` | object | Embedded video (contentUrl, thumbnailUrl, description; detail only). |
| `companyAddress` | string | Company address (detail only, when present). |
| `pros` | string | Pros (detail only). |
| `cons` | string | Cons (detail only). |
| `monetaryLoss` | string | Reported monetary loss (detail only). |
| `preferredSolution` | string | Preferred resolution (detail only). |
| `featured` | boolean | Whether the review is featured on the listing. |

### Limitations

- Listing pages do not expose direct complaint URLs for non-featured reviews (the date shown is last-activity, not the post date, so URL construction is unreliable). Pass direct complaint URLs as `startUrls` to get full detail rows.
- The site paginates with `rel="next"` alternating between `/complaints/RT-P.html` and `/reviews/RT-P.html`; the actor follows both.
- Very large companies (e.g. Amazon) have 100K+ reviews; use `maxPages` to cap crawl depth.

### Changelog

- `0.0` — initial release: company, category, search, and direct-complaint crawling; listing + detail parsing; sliding-window concurrency.

# Actor input Schema

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

PissedConsumer URLs to scrape. Supported: company pages (https://amazon.pissedconsumer.com/review.html), category pages (https://www.pissedconsumer.com/search-companies/category/electronics.html), individual complaint pages (https://amazon.pissedconsumer.com/{complaint-slug}-{id}.html), or search URLs. Company pages yield all complaints on that company; individual complaint URLs yield the full detail (pros, cons, monetary loss, company address, video, all photos).

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

Search PissedConsumer for companies by name (e.g. "Amazon", "Temu"). Resolved to company search results and crawled alongside any Start URLs.

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

Maximum number of complaints to scrape across all Start URLs.

## `maxPages` (type: `integer`):

Maximum number of listing pages to crawl per company (15 complaints per page). 0 = unlimited.

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

Maximum number of pages fetched in parallel.

## `proxy` (type: `object`):

Leave empty to use the default Apify proxy. PissedConsumer has no anti-bot, so most proxies work.

## Actor input object example

```json
{
  "startUrls": [
    "https://amazon.pissedconsumer.com/review.html"
  ],
  "maxItems": 1000,
  "maxPages": 0,
  "maxConcurrency": 10
}
```

# Actor output Schema

## `results` (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://amazon.pissedconsumer.com/review.html"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/pissedconsumer-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://amazon.pissedconsumer.com/review.html"] }

# Run the Actor and wait for it to finish
run = client.actor("memo23/pissedconsumer-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://amazon.pissedconsumer.com/review.html"
  ]
}' |
apify call memo23/pissedconsumer-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/pissedconsumer-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/Kjr4IVsCaielMiJHp/builds/6ZZfON5DxbUjXoHxn/openapi.json
