# nopCommerce Reviews Scraper & Change Monitor (`clintsa/nopcommerce-product-review-extractor`) Actor

Build a review dataset from public nopCommerce product pages. Export JSON or CSV and monitor changes. $0.6 per 1,000 rows plus $0.001 per run.

- **URL**: https://apify.com/clintsa/nopcommerce-product-review-extractor.md
- **Developed by:** [Andy Besos](https://apify.com/clintsa) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 product reviews

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

nopCommerce Reviews Scraper & Change Monitor helps you build a review dataset from public nopCommerce product pages. Export reviewer nicknames, star ratings, review titles, text, original dates and product links for feedback analysis, rating reports and recurring review checks.

Paste a public product URL to start. The Actor supports recognized inline and public review endpoints without a merchant login; coverage depends on the shop theme and review setup. Actor event charges at the default 256 MB memory are **$0.001 per run plus $0.0006 per exported row**: **$0.601 for 1,000 rows**.

Selected fields from a recent successful run; source values can change:

```json
{
  "productId": "178",
  "productName": "Divoký losos keta steak - 1000 g",
  "starRating": 5,
  "reviewDate": "2016-06-30",
  "language": "cs",
  "productUrl": "https://www.bonfood.cz/losos-keta-steak-volny-lov"
}
```

### Why use this nopCommerce review extractor?

- **Review rows with product context.** Nickname, rating, title, text and date stay attached to the correct product ID and store. An aggregate rating is never expanded into invented reviews.
- **Public review tab and page coverage.** The Actor probes the public review tab and falls back to recognized product-page or legacy review-page HTML.
- **Inputs from an existing catalog.** Paste product URLs or objects containing `url`, `id` and `name`, including exports from the [nopCommerce Product Catalog Scraper & Monitor](https://apify.com/clintsa/nopcommerce-product-catalog-scraper).
- **Review change monitoring.** Repeated runs identify new, edited, unchanged and removed reviews using persistent product-scoped snapshots.
- **Source-aware dates and language.** Original date strings are preserved. Unambiguous dates become `YYYY-MM-DD`; uncertain interpretations remain null. Language is the storefront's public HTML language tag. Isolated review URLs are enriched from the product detail page when the review layout omits that tag.
- **Bounded discovery.** Start from a category, storefront or sitemap when individual product URLs are unavailable. Product, discovery-page, review-page and request caps let you control scope.

Temporary rate limits and server errors receive retries with backoff. Requests run sequentially, respect robots rules and use a configurable delay. Product failures are isolated, and the run can succeed when another target works. A failed or capped review scan retains previously seen reviews rather than reporting them as removed. Check the run summary for individual errors and completeness.

### Pricing

Pay per event: **$0.001 per run plus $0.0006 per exported review row** at the default 256 MB memory allocation, equivalent to $0.60 per 1,000 review rows plus the start event.

| Exported review rows | Estimated event charge for one run |
| ---: | ---: |
| 1 | $0.0016 |
| 100 | $0.061 |
| 1,000 | $0.601 |
| 10,000 | $6.001 |

The exact formula is `$0.001 + exported rows × $0.0006`. An unchanged review exported on a normal repeat run is also a billed row, as is a removal event. The summary is stored separately and is not a dataset row. Compute is included in these event prices; the Actor does not use a proxy. Increasing memory above 1 GB increases the number of start events. The Pricing tab is the authority for the current charges.

### How to use this Actor

For a quick first run, use a direct product URL. The following public [BonFood product](https://www.bonfood.cz/losos-keta-steak-volny-lov) had 19 reviews when checked on 17 October 2026:

```json
{
  "targets": [
    "https://www.bonfood.cz/losos-keta-steak-volny-lov"
  ],
  "maxItemsPerProduct": 1
}
```

Click **Start**, inspect the Dataset, then export JSON or CSV. Inspect starRating, reviewDate and the product link. Empty products produce no review rows, and the source date text is preserved separately from the normalized calendar date.

The output cap limits exported rows after review scanning. It does not truncate the monitoring snapshot. Products with no published reviews produce no review rows.

Full product URLs, bare hostnames, legacy review URLs, public AJAX URLs and catalog product objects are accepted. A numeric product ID needs a base store URL:

```json
{
  "storeUrl": "https://www.bonfood.cz",
  "targets": [
    "178",
    {"url": "https://www.bonfood.cz/losos-keta-steak-volny-lov", "id": "178", "name": "Divoký losos keta steak - 1000 g"}
  ],
  "maxItemsPerProduct": 0,
  "monitorId": "bonfood-reviews"
}
```

Duplicate product scopes within one run are exported once. For broader discovery, provide a category URL such as `https://www.bonfood.cz/ryby`, a shop homepage, or the store's public sitemap. A sitemap can contain informational pages as well as products, so inspect discovery counts before increasing limits.

```json
{
  "targets": ["https://www.bonfood.cz/sitemap.xml"],
  "maxProducts": 10,
  "maxDiscoveryPages": 40,
  "maxReviewPages": 10,
  "maxRequests": 100,
  "requestDelayMillis": 500,
  "maxItemsPerProduct": 50
}
```

### Monitor new, updated, and removed records

Keep the same `monitorId` and product scope for repeated checks. The first successful scan creates a baseline; later runs compare the fetched reviews with it.

| changeType | Meaning |
| --- | --- |
| `new` | Review identity was not present in the prior snapshot. |
| `updated` | One or more observed review fields changed; see `changedFields`. |
| `unchanged` | Review fields match the previous observation. |
| `removed` | A complete review scan no longer returned a previously observed review. |

Create an Apify schedule using the same input and monitor ID to run daily. Add `"onlyChangesSince": "2026-10-17T00:00:00Z"` to export recent changes only. The cutoff applies to when the Actor detected a change, rather than the review's written-on date. Rating filters and output limits apply after monitoring, so filtered-out reviews do not become false removals.

Native review IDs provide the strongest identity. When a theme hides them, the Actor derives identity from store, product, nickname and original date. Identical nickname/date combinations need occurrence suffixes; changes to those identifying fields or their ordering can affect continuity. Removal events describe visibility in a completed public scan, not a verified moderation action. Discovery does not emit removals for entire products absent from the current discovery scope.

### API example

Use your Apify token to run the Actor from another application. No merchant API key is needed:

```bash
curl -X POST 'https://api.apify.com/v2/acts/Clintsa~nopcommerce-product-review-extractor/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"targets":["https://www.bonfood.cz/losos-keta-steak-volny-lov"],"maxItemsPerProduct":1}'
```

### Input options

| Field | Purpose |
| --- | --- |
| `targets` | Required array of public URLs, numeric IDs as strings, or catalog objects with `url`, `id`, `name` and optionally `storeUrl`. |
| `storeUrl` | Optional base URL for numeric IDs or relative paths; include any store installation or locale prefix. |
| `maxItemsPerProduct` | Export limit per product; default 100, prefill 1, 0 exports all fetched rows. Removal events count toward this limit. |
| `maxProducts` | Maximum discovered products per target; default 20. |
| `maxDiscoveryPages` | Maximum pages inspected during discovery, including product pages; default 30. |
| `maxReviewPages` | Maximum review pages per product; default 20. Capped scopes are incomplete. |
| `maxRequests` | Maximum HTTP operations per target; default 200, including robots and redirects. Retries may add network attempts. |
| `requestDelayMillis` | Request delay; default 250 milliseconds, with robots crawl delays also respected. |
| `minRating` | Minimum exported rating; default 0 includes unknown ratings. |
| `maxRating` | Maximum exported rating; default 5. |
| `monitorId` | Persistent review monitoring namespace; default `default`. |
| `onlyChangesSince` | Optional ISO timestamp for changes detected on or after the cutoff. |

### Output

A review captured from the BonFood product illustrates the fields; observation and monitoring timestamps vary per run:

```json
{
  "itemId": "a2aeb87089201ea516718ced:hash:19ae5ea0e1fb5d9a1759af86",
  "reviewId": null,
  "identityType": "derived",
  "reviewerNickname": "Julien Labrieux",
  "starRating": 5,
  "reviewTitle": "Naprosto vynikající!",
  "reviewText": "Nejdřív trochu namastit olejem, osolit a grilovat max 4 minuty na každé straně. Opepřit a servirovat.",
  "reviewDate": "2016-06-30",
  "reviewDateRaw": "30.06.2016 17:42",
  "productId": "178",
  "productName": "Divoký losos keta steak - 1000 g",
  "productUrl": "https://www.bonfood.cz/losos-keta-steak-volny-lov",
  "storeUrl": "https://www.bonfood.cz",
  "language": "cs",
  "storeId": null,
  "languageId": null,
  "target": "https://www.bonfood.cz/losos-keta-steak-volny-lov",
  "sourceUrl": "https://www.bonfood.cz/producttab/productreviewstab/178",
  "scrapedAt": "2026-10-17T12:00:00.000Z",
  "changeType": "new",
  "changeDetectedAt": "2026-10-17T12:00:00.000Z",
  "firstSeenAt": "2026-10-17T12:00:00.000Z",
  "lastSeenAt": "2026-10-17T12:00:00.000Z"
}
```

The dataset offers Reviews and Changes table views. The `SUMMARY` key-value record reports requested and successful targets, product successes and failures, fetched review counts, exported rows, request counts, review-scan completeness, warnings and change totals. Nullable fields are present even when a store does not publish a value.

### Use cases

- Compare product-level reputation across public nopCommerce merchants.
- Feed a reputation-monitoring agency's daily review report.
- Identify recurring complaints or praise in a niche marketplace.
- Join review rows to product catalog exports using store URL and product ID.
- Track newly visible reviews and changes to existing public review text.

### FAQ

**Does this extract reviews from every nopCommerce store?** It supports public stores with recognized review markup or the supported public tab. Custom themes, disabled reviews, robots restrictions and access controls can prevent extraction. Store coverage counts are not a tested compatibility guarantee.

**Is ProductReviewsTab a standard nopCommerce API?** It is associated with themes/plugins and is not present on every installation. Core stores may expose standalone review pages or embed the list on the product detail page. The Actor attempts the supported public paths without signing in.

**Do I need a nopCommerce API key, login or proxy?** No. Reading public reviews does not require the credentials sometimes needed to submit a review. The Actor never submits forms or votes. Stores that block direct requests are reported in the summary.

**Does language identify what language the customer wrote?** It identifies the storefront's HTML language tag. It does not translate or classify individual review texts. `storeId` and `languageId` are null unless public metadata exposes them; neither is guessed.

**How does review pagination work?** The Actor follows links and numeric page markers found in recognized review pagers. It stops at the configured cap and detects repeated pages. Custom JavaScript-only loaders without usable page markers may need an additional adapter.

**Why is reviewDate null?** The source date was absent, invalid, or could not be interpreted confidently. `reviewDateRaw` retains the original public label. Normalized dates have no assumed timezone.

**Can I extract only negative reviews?** Set `maxRating` to 2 and `minRating` to 1. All fetched reviews still participate in monitoring, while the dataset contains only matching review events up to the output cap.

### Limitations and responsible use

The Actor extracts public product review rows. It does not retrieve account emails, private profiles, unapproved reviews, login-only content or third-party widgets such as Trustpilot unless they expose the supported nopCommerce markup. Aggregate star ratings alone do not produce review records. Product names can be null for isolated AJAX tabs without accessible product context. A review is a public claim, not proof of a verified purchase or an independent authenticity check.

Respect each store's terms and rate limits and use personal information lawfully. The Actor honors robots.txt, uses public GET requests and does not bypass login walls or CAPTCHA challenges. Review and discovery caps bound the scan; inspect the summary before treating an export as complete.

### Support

Open the Issues tab with the run ID, input and a public example product URL. For a missing field, include the expected visible value and the storefront language so the theme variation can be reproduced.

Related tools: [nopCommerce Product Scraper & Catalog Monitor](https://apify.com/clintsa/nopcommerce-product-catalog-scraper).

# Actor input Schema

## `targets` (type: `array`):

Public product, category, storefront, sitemap, ProductReviewsTab or productreviews URLs. Accepts strings or catalog objects with url, id and name. Numeric IDs need storeUrl.

## `storeUrl` (type: `string`):

Optional public storefront base URL, including any installation or locale prefix. Required when targets contains bare product IDs.

## `maxItemsPerProduct` (type: `integer`):

Output row limit per product after full review scanning and monitoring. Use 0 for all fetched review rows; removal events also count toward the limit.

## `maxProducts` (type: `integer`):

Maximum distinct products discovered from each target. Prefer direct product URLs for a quick run.

## `maxDiscoveryPages` (type: `integer`):

Maximum pages inspected for products, including the starting URL and product pages. Discovery bounds do not imply a complete catalog.

## `maxReviewPages` (type: `integer`):

Maximum recognized review pages followed per product. A capped scan retains unseen prior reviews and emits no removal events.

## `maxRequests` (type: `integer`):

Bounds HTTP operations including robots, redirects, discovery and review requests. A transient retry can add up to two network attempts per operation.

## `requestDelayMillis` (type: `integer`):

Minimum delay between sequential requests to a target. Robots crawl delays are also respected. No proxy is used.

## `minRating` (type: `integer`):

Output-only rating filter, 1 to 5. Use 0 to also include reviews whose public rating is missing. Monitoring still snapshots all fetched reviews.

## `maxRating` (type: `integer`):

Output-only upper star rating, 1 to 5. Set to 2 to focus on low ratings.

## `monitorId` (type: `string`):

Persistent namespace for review snapshots across runs. Keep it for a schedule; change it to start a separate baseline.

## `onlyChangesSince` (type: `string`):

Optional ISO 8601 timestamp; exports only new, updated and removed review events detected since that time.

## Actor input object example

```json
{
  "targets": [
    "https://www.bonfood.cz/losos-keta-steak-volny-lov"
  ],
  "maxItemsPerProduct": 1,
  "maxProducts": 20,
  "maxDiscoveryPages": 30,
  "maxReviewPages": 20,
  "maxRequests": 200,
  "requestDelayMillis": 250,
  "minRating": 0,
  "maxRating": 5,
  "monitorId": "default"
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "targets": [
        "https://www.bonfood.cz/losos-keta-steak-volny-lov"
    ],
    "maxItemsPerProduct": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("clintsa/nopcommerce-product-review-extractor").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 = {
    "targets": ["https://www.bonfood.cz/losos-keta-steak-volny-lov"],
    "maxItemsPerProduct": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("clintsa/nopcommerce-product-review-extractor").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 '{
  "targets": [
    "https://www.bonfood.cz/losos-keta-steak-volny-lov"
  ],
  "maxItemsPerProduct": 1
}' |
apify call clintsa/nopcommerce-product-review-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,clintsa/nopcommerce-product-review-extractor"
        }
    }
}
```

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/jwuParf1upoQ65PkM/builds/duDQ6ovnMyvKMprm0/openapi.json
