# Wildberries Scraper - Products, Prices, Reviews (`abotapi/wildberries-marketplace-scraper`) Actor

Scrape Wildberries marketplace: product search with prices (wallet vs retail), discounts, stock, ratings and seller data. Paste product or seller links for review analytics and seller registration info. Incremental monitoring with NEW, UPDATED, REAPPEARED, EXPIRED, resume and MCP export.

- **URL**: https://apify.com/abotapi/wildberries-marketplace-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Stats:** 3 total users, 2 monthly users, 75.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 product records

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

## Wildberries Scraper

Scrape Wildberries (wildberries.ru), the largest marketplace in Russia: search any product keyword and collect structured product records with wallet and retail prices, discount percentages, stock, seller names and legal registration data, ratings and customer reviews. Paste product links to pull a product's review surface, or seller links to get the seller's registry record. Built for price monitoring, seller research and catalog analytics.

### Why This Scraper?

- Search plus URL modes: a keyword search collects result pages in order until your limits or the natural end of the results; pasted search, product and seller links are each classified and read.
- Price intelligence per row: the marketplace's wallet (discounted) price and the retail price are both captured, so the discount percentage, the gap between the two prices and price movement across runs are computed, not guessed.
- Reviews included, not dropped: each product carries its rating summary (average, total count, per-star distribution, counts of text/photo reviews) plus the most recent review rows with text, pros and cons, date and the seller's answer where present.
- Seller layer: every product row names its seller; seller links resolve the registry record with legal name, trademark, INN, OGRN/IP and related registration fields.
- Incremental monitoring: schedule the same search and get only what changed, stamped NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED, with a saved baseline per campaign.
- Resume: an interrupted run can be continued from the previous run id without re-emitting records already collected.
- Pipes results into your apps through MCP connectors (optional) and never changes the dataset when doing so.

### Data You Get

> Sample shape: values are illustrative placeholders, not from a live listing.

| Field | Example value |
|---|---|
| `kind` | `product` |
| `recordId` | `nm:111111111` |
| `nmId` | `111111111` |
| `rootId` | `222222222` |
| `url` | `https://www.wildberries.ru/catalog/222222222/detail.aspx` |
| `name` | `Sample Product One 128 GB White` |
| `brand` | `Sample Brand A` |
| `price` | `27245.0` (wallet price, RUB) |
| `priceRetail` | `50300.0` (retail price, RUB) |
| `discountPercent` | `46` |
| `hasDiscount` | `true` |
| `currency` | `RUB` |
| `rating` | `5` |
| `feedbacksCount` | `23` |
| `stock` | `42` |
| `warehouseIds` | `[218804]` |
| `deliveryDaysMin` / `deliveryDaysMax` | `11` / `30` |
| `supplierId` | `123456789` |
| `supplierName` | `Sample Seller One` |
| `supplierRating` | `4.8` |
| `imageUrl` | basket CDN URL for the product's first image |
| `feedbackSummary.valuation` | `4.9` |
| `feedbackSummary.distribution` | `{"1": 1, "2": 0, "3": 2, "4": 10, "5": 101}` |
| `feedbacks[0].text` | `Sample review text: the product works as described.` |
| `feedbacks[0].rating` | `5` |
| `feedbacks[0].createdDate` | `2026-08-01T12:00:00+03:00` |
| `sellerName` (seller records) | `Sample Seller One` |
| `sellerFullName` (seller records) | `Sample Trade LLC` |
| `inn` / `ogrnip` (seller records) | `0000000000` / `000000000000000` |
| `changeType` (incremental mode) | `NEW` |

### How to Use

Search a keyword (3 products, cheapest possible run):

```json
{
  "mode": "search",
  "query": "iphone",
  "maxItems": 3,
  "maxPages": 1
}
```

Monitor prices on a filtered niche daily:

```json
{
  "mode": "search",
  "query": "running shoes",
  "sortBy": "priceup",
  "priceMin": 3000,
  "priceMax": 8000,
  "minRating": 4,
  "maxItems": 0,
  "maxPages": 5,
  "incrementalMode": true,
  "stateKey": "running-shoes-campaign"
}
```

Read specific pages (search link, product reviews, seller registry):

```json
{
  "mode": "url",
  "urls": [
    "https://www.wildberries.ru/catalog/0/search.aspx?search=headphones",
    "https://www.wildberries.ru/catalog/186510487/detail.aspx",
    "https://www.wildberries.ru/seller/123456789"
  ],
  "maxFeedbacksPerProduct": 10
}
```

Pull full detail cards for a small batch:

```json
{
  "mode": "search",
  "query": "kettle",
  "maxItems": 10,
  "fetchDetails": true,
  "maxFeedbacksPerProduct": 5
}
```

### Input Parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `search` | Search by keyword, or paste links in URL mode. |
| `query` | string | `iphone` | Search mode: the product keyword. |
| `sortBy` | select | `popular` | Popular, price low-to-high, price high-to-low, highest rated, newest. |
| `priceMin` / `priceMax` | integer | empty | Price window in rubles, enforced on the collected rows. |
| `minRating` | integer | empty | Only collect products rated at or above this value. |
| `minFeedbacks` | integer | empty | Only collect products with at least this many reviews. |
| `onlyWithDiscount` | boolean | `false` | Only collect products whose wallet price is below retail. |
| `urls` | array | empty | URL mode: search, product or seller pages, one per line. The filters apply to walked search links too. |
| `fetchDetails` | boolean | `false` | Also fetch the full detail card (description, characteristics) per product. Adds a per-product surcharge. |
| `maxFeedbacksPerProduct` | integer | `5` | Recent review rows attached per product. `0` skips reviews. |
| `maxItems` | integer | `20` | Maximum 20 records by default; `0` means no item limit: the run stops at Max pages or the natural end of the results. |
| `maxPages` | integer | `0` | Pages read per search; 0 or empty uses the built-in limit of 20 pages per scope. |
| `resumeFromRunId` | string | empty | Continue one interrupted run; its records are not returned again. |
| `incrementalMode` | boolean | `false` | Stamp NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED against the saved baseline. |
| `stateKey` | string | empty | Name of the monitoring campaign; different keys never share a baseline. |
| `emitUnchanged` | boolean | `false` | Also return unchanged rows. Returns and bills extra rows. |
| `emitExpired` | boolean | `false` | Also return rows the source no longer lists in a complete scan. Returns and bills extra rows. |
| `mcpConnectors` | array | empty | Optional MCP connectors to export results into. |
| `notionParentPageUrl` | string | empty | Notion parent page for the Notion connector. |
| `maxNotifyListings` | integer | `50` | Cap on items written per connector. |
| `proxy` | proxy | Apify proxy | The marketplace refuses many plain hosting connections; a higher connection tier is recommended for reliable runs. |

### Output Example

> Sample shape: values are illustrative placeholders, not from a live listing.

```json
{
  "kind": "product",
  "recordId": "nm:111111111",
  "nmId": 111111111,
  "rootId": 222222222,
  "url": "https://www.wildberries.ru/catalog/222222222/detail.aspx",
  "name": "Sample Product One 128 GB White",
  "brand": "Sample Brand A",
  "price": 27245.0,
  "priceRetail": 50300.0,
  "discountPercent": 46,
  "hasDiscount": true,
  "currency": "RUB",
  "rating": 5,
  "reviewRating": 4.9,
  "feedbacksCount": 23,
  "stock": 42,
  "warehouseIds": [218804],
  "deliveryDaysMin": 11,
  "deliveryDaysMax": 30,
  "supplierId": 123456789,
  "supplierName": "Sample Seller One",
  "supplierRating": 4.8,
  "imageUrl": "https://basket-10.wbbasket.ru/vol1111/part111111/111111111/images/c246x328/5.webp",
  "feedbackSummary": {
    "valuation": "4.9",
    "valuationSum": 114,
    "distribution": {"1": 1, "2": 0, "3": 2, "4": 10, "5": 101},
    "withText": 100,
    "withPhoto": 20
  },
  "feedbacks": [
    {
      "id": "sampleFeedbackIdAAA111",
      "createdDate": "2026-08-01T12:00:00+03:00",
      "rating": 5,
      "text": "Sample review text: the product works as described.",
      "pros": "Sample pros text",
      "cons": "Sample cons text",
      "userName": "Sample User One",
      "answerText": "Sample seller answer",
      "photosCount": 0
    }
  ],
  "changeType": "NEW",
  "changedFields": [],
  "firstSeenAt": "2026-09-11T00:00:00+00:00",
  "lastSeenAt": "2026-09-11T00:00:00+00:00"
}
```

Notes on coverage, stated plainly:

- The rating summary and review rows come from the marketplace's open review surface, which returns the most recent roughly one thousand review rows per product; older reviews beyond that window are not exposed by that surface.
- Product links in URL mode resolve the review surface keyed by the catalog id in the link; name and price fields are populated in search mode, where the result payload carries them.
- The per-product detail card (description, characteristics) is served from the source's static card storage and is not present for every product; when it is absent the record ships with the search-side fields and the detail surcharge is not applied.
- A product's per-warehouse stock breakdown is not exposed by the open surfaces; records carry the total stock and the warehouses the current offer ships from.

### Send results into your apps (MCP connectors)

You can pipe collected results straight into the apps you already use. Under Apify, open Settings, then API & Integrations, and authorize a connector such as Notion, Linear, Airtable or Apify. Then set `mcpConnectors` in the actor input (and `notionParentPageUrl` when using Notion) and each run also writes a condensed, human-readable summary of every item into the connected app: a title plus the key fields flattened to plain text. The complete record always stays in the Apify dataset; the connector export is a convenience copy and `maxNotifyListings` caps how many items each connector receives per run. Leaving the fields empty changes nothing.

### Plan Requirement

An Apify account with proxy usage enabled is required. The marketplace refuses many plain hosting connections, so for reliable runs choose a higher connection tier in the connection settings if your plan includes one; the actor rotates fresh exits automatically on refusals and tells you plainly in the run log when a run could not read any pages.

# Actor input Schema

## `mode` (type: `string`):

Search looks up products by keyword. URL mode reads specific Wildberries pages you paste: search pages, product pages (reviews) and seller pages.

## `query` (type: `string`):

Search mode: a product keyword, for example 'iphone', 'nike shoes' or a Russian phrase like 'ноутбук'. Used with the sort and filter fields below.

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

URL mode: pages to read, one per line. Search links are walked forward with pagination. Product links return the product's review surface and rating summary. Seller links return the seller's registration data. Multi-value supported.

## `sortBy` (type: `string`):

Ordering of the results. Price ascending and Price descending also re-order the collected rows so the ordering holds.

## `priceMin` (type: `integer`):

Only collect products priced at or above this many rubles, applied to the collected results. Leave empty for no lower bound.

## `priceMax` (type: `integer`):

Only collect products priced at or below this many rubles, applied to the collected results. Leave empty for no upper bound.

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

Only collect products rated at or above this value (integers 1 to 5). Leave empty for no rating filter.

## `minFeedbacks` (type: `integer`):

Only collect products with at least this many customer reviews. Leave empty for no review filter.

## `onlyWithDiscount` (type: `boolean`):

Collect only products whose current wallet price is below the retail price.

## `fetchDetails` (type: `boolean`):

When on, each collected product additionally gets its full detail card (description, characteristics) when the source serves it. Full details add a per-product surcharge.

## `maxFeedbacksPerProduct` (type: `integer`):

Attach up to this many recent customer reviews to each product record (text, rating, date, pros and cons). 0 skips reviews entirely. The rating summary and totals are always included.

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

Maximum number of records to return across the whole run. 0 means no item limit: the run stops at Max pages or at the natural end of the results.

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

Maximum number of result pages to read per search or link. Leave 0 or empty to use the built-in limit of 20 pages per scope; raise it to scan deeper. Max items remains the other stop condition.

## `resumeFromRunId` (type: `string`):

Run id of a previous run of this actor: its collected record ids are seeded as already-seen, so a continued run does not return them again.

## `incrementalMode` (type: `boolean`):

Remember the previous run of the same search and stamp each record NEW, UPDATED, UNCHANGED or EXPIRED. Only changed rows are emitted by default.

## `stateKey` (type: `string`):

Name for this monitoring campaign's saved baseline. Give different searches different keys so their baselines never mix.

## `emitUnchanged` (type: `boolean`):

Also return rows that did not change since the previous run. This returns and bills extra rows.

## `emitExpired` (type: `boolean`):

Also return rows tracked earlier that the source no longer returns in a complete scan. This returns and bills extra rows.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify → Settings → API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write/digest. Leave empty to skip: never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

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

This marketplace refuses many plain hosting connections. For reliable runs choose a higher connection tier in these settings if your plan includes one; the run rotates fresh exits automatically either way and tells you plainly when the selected connection is likely to be refused.

## Actor input object example

```json
{
  "mode": "search",
  "query": "iphone",
  "urls": [
    "https://www.wildberries.ru/catalog/0/search.aspx?search=headphones"
  ],
  "sortBy": "popular",
  "onlyWithDiscount": false,
  "fetchDetails": false,
  "maxFeedbacksPerProduct": 5,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `products` (type: `string`):

No description

## `reviews` (type: `string`):

No description

## `sellers` (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 = {
    "mode": "search",
    "query": "iphone",
    "urls": [
        "https://www.wildberries.ru/catalog/0/search.aspx?search=headphones"
    ],
    "sortBy": "popular",
    "maxFeedbacksPerProduct": 5,
    "maxItems": 20,
    "maxPages": 0,
    "resumeFromRunId": "",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/wildberries-marketplace-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 = {
    "mode": "search",
    "query": "iphone",
    "urls": ["https://www.wildberries.ru/catalog/0/search.aspx?search=headphones"],
    "sortBy": "popular",
    "maxFeedbacksPerProduct": 5,
    "maxItems": 20,
    "maxPages": 0,
    "resumeFromRunId": "",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/wildberries-marketplace-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 '{
  "mode": "search",
  "query": "iphone",
  "urls": [
    "https://www.wildberries.ru/catalog/0/search.aspx?search=headphones"
  ],
  "sortBy": "popular",
  "maxFeedbacksPerProduct": 5,
  "maxItems": 20,
  "maxPages": 0,
  "resumeFromRunId": "",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call abotapi/wildberries-marketplace-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/wildberries-marketplace-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/zljZQ8utZiJ34u4NC/builds/Eae7rHIWp7tzmhbPQ/openapi.json
