Wildberries Scraper - Products, Prices, Reviews
Pricing
from $1.20 / 1,000 product records
Wildberries Scraper - Products, Prices, Reviews
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.
Pricing
from $1.20 / 1,000 product records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
5
Total users
2
Monthly active users
14 days ago
Last modified
Categories
Share
Wildberries Scraper: Products, Prices, Reviews & Seller Data
Wildberries Scraper turns wildberries.ru, the largest marketplace in Russia, into structured product, review and seller data. Search any keyword and collect wallet (discounted) and retail prices, discount percentages, stock, ratings and seller identity for every result, or paste product links for their review surface and seller links for the seller's legal registration record. Export to JSON, CSV or Excel, or read the dataset straight through the API.
Why This Scraper?
- Two ways in. A keyword search that walks result pages in order, or pasted links (search, product or seller pages), each classified and read on its own path.
- Wallet vs retail pricing. Both prices come straight from the marketplace's own pricing object; the discount percentage and discount flag are computed from those two values, never guessed.
- Reviews per product. A rating summary (average, total count, per-star distribution, counts with text or photo) plus the most recent review rows, capped to the number you choose.
- Seller identity. Every search result row names its seller (id, storefront name, rating); pasted seller links resolve the seller's legal registration record (name, trademark, INN, OGRN/IP and related fields).
- Incremental monitoring. For recurring runs: records are classified NEW, UPDATED or UNCHANGED against a saved baseline by default. EXPIRED needs the current run to have Emit expired on and to scan the whole scope end to end; REAPPEARED only ever follows a record an earlier such run already marked EXPIRED.
- Resume. Continues one interrupted run without re-emitting or re-billing the records it already collected.
- MCP export. Pipes results into your apps through MCP connectors (optional) and never changes the dataset when doing so.
Use Cases
- Price monitoring: track wallet vs retail prices and discount depth across a niche on a schedule, and see exactly what changed since the last run.
- Seller and marketplace research: map which sellers dominate a category, along with their storefront rating and legal registration details.
- Catalog and assortment analytics: build structured datasets of products, stock levels and delivery windows for a search or category.
- Customer feedback analysis: pull rating distributions and review text to gauge sentiment for a product line.
- Competitive intelligence: paste a competitor's product or seller links to track their pricing and review growth over time.
Data You Get
Sample shape: values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
kind | "product" (also "seller") |
recordId | "nm:264193008" |
nmId | 264193008 |
rootId | 264193000 |
url | "https://www.wildberries.ru/catalog/264193000/detail.aspx" |
name | "Ceramic Travel Mug 350 ml Slate Blue" |
brand | "Zelwick" |
price / currency | 1290.0 (wallet price) / "RUB" |
priceRetail | 2150.0 (retail price, RUB) |
discountPercent / hasDiscount | 40 / true |
rating / reviewRating | 4 / 4.6 |
feedbacksCount | 812 |
stock / warehouseIds | 156 / [512033] |
deliveryDaysMin / deliveryDaysMax | 12 / 36 |
sizes | per-size list with name, optionId, warehouse, delivery estimates, wallet price, retail price |
brandId, siteBrandId, subjectParentId, kindId, entity, matchId, supplierFlags, pics, totalQuantity, time1, time2, wh, dtype, dist, logs, panelPromoId, viewFlags, nmReviewRating, nmFeedbacks | card identifiers and delivery details as the marketplace reports them (null when absent) |
| New fields | The fields from sizes down are excluded from the incremental comparison, so existing baselines do not report UPDATED because they appeared. |
supplierId / supplierName / supplierRating | 71820456 / "Orinvale Trade" / 4.7 |
imageUrl | a product image URL on the marketplace's own CDN |
feedbackSummary.valuation / .distribution | "4.6" / {"1": 12, "2": 9, "3": 41, "4": 210, "5": 540} |
feedbacks[0].text / .rating | "Keeps tea hot for hours, exactly as pictured." / 5 |
sellerFullName / inn / ogrnip (seller records) | "Individual Entrepreneur Orinvale D.K." / "5027098431" / "321500000045678" |
changeType (incremental mode) | "NEW" |
Seller records carry the seller's legal name, trademark, INN, OGRN/IP, KPP and related registration fields in place of the product fields above. A product read from a pasted product link carries only the review surface (rating summary and review rows); its name, price, rating and seller fields are empty, since that surface does not carry them, only search mode does. 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 detail surcharge is not applied, and in incremental mode the previous run's description and characteristics are carried forward instead of being cleared. 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. 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.
How to Use
- Pick a mode:
search(by keyword) orurl(paste search, product or seller links). - Fill in the fields for that mode, and switch on reviews or full details if you need them.
- Set Max items (and Max pages for deep searches) to control run size and cost, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
Search a keyword (3 products, cheapest possible run):
{"mode": "search","query": "iphone","maxItems": 3,"maxPages": 1}
Monitor a filtered niche daily:
{"mode": "search","query": "running shoes","sortBy": "priceup","priceMin": 3000,"priceMax": 8000,"minRating": 4,"maxItems": 0,"maxPages": 5,"incrementalMode": true,"stateKey": "running-shoes-campaign"}
In URL mode, leaving the links field untouched reads one example per supported page type (a search page, a product page, a seller page).
Read specific pages (search link, product reviews, seller registry):
{"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/250150687"],"maxFeedbacksPerProduct": 10}
Pull full detail cards for a small batch:
{"mode": "search","query": "kettle","maxItems": 10,"fetchDetails": true,"maxFeedbacksPerProduct": 5}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/wildberries-marketplace-scraper").call(run_input={"mode": "search", "query": "iphone", "maxItems": 20})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["name"], item["price"], item["supplierName"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/wildberries-marketplace-scraper').call({mode: 'search', query: 'iphone', maxItems: 20,});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Resume and recurring updates
Two different things, easy to confuse:
- Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset id and the actor skips every record it already collected there, so you don't pay twice. In search mode it re-walks the search from page one on every run (already-collected records are recognized by id and skipped, not re-billed), so if a previous run's stop was Max pages itself rather than Max items, raise Max pages before resuming; otherwise the resumed run hits the same page limit again without ever reaching the further, unread pages. - Incremental mode (
incrementalMode) is for running this same search again and again (for example daily) and getting only what changed. Each record is classifiedNEW,UPDATED(withchangedFields), orUNCHANGED(suppressed and not billed unlessemitUnchangedis on) by default.EXPIREDonly appears when the current run hasemitExpiredon and scans the whole scope end to end: not resumed, not stopped by Max items or Max pages, no unreadable pages.REAPPEAREDonly appears for a record an earlier such run already markedEXPIRED.stateKeynames or shares the stored baseline; different keys never share one. A record isUPDATEDwhen a compared field changes: price, discount, stock, rating, review count and review totals, name, brand, seller, delivery times, warehouses, colors, image, description or characteristics. The attached review rows, the position in the results and the scrape time are never compared (they are still returned).ignoreFieldsForChangeslets you leave further fields out of the comparison, including nested ones with a dotted name such asfeedbackSummary.withPhoto. With incremental mode off, output is exactly as before.
Supported links and filters
URL mode accepts these page shapes (hosts wildberries.ru, www.wildberries.ru, by.wildberries.ru, kz.wildberries.ru, wildberries.uz and search.wb.ru):
| Shape | Example | What you get |
|---|---|---|
| Search | /catalog/0/search.aspx?search=headphones | Product rows, walked page by page; the filters below apply |
| Product | /catalog/186510487/detail.aspx (also /catalog/<id>.aspx) | Review surface: rating summary and review rows |
| Seller | /seller/250150687 | Seller legal registration record |
Category, brand and promotion pages are not supported: with Ignore URL failures on (the default) each one is skipped with a warning in the log naming the reason; with it off, every unsupported link is still logged and the run then fails once, with the count of unsupported links. Leaving the links field untouched reads one example per supported shape (the three above). Max items per link caps each link; empty splits Max items evenly.
Search filters: sort order, minimum and maximum price, minimum rating, minimum review count, discounted-only, and delivery time (4 to 120 hours). Aliases keyword, sort_by, price_range and is_sale are accepted for API callers. Each product row also carries card details (size list, delivery estimates, brand and category identifiers); these extra fields are excluded from the incremental comparison so existing baselines do not report UPDATED because they appeared.
Reviews: Max reviews per product defaults to 20, is capped at 1000 (the open review surface exposes roughly the latest thousand), and each row includes helpful and unhelpful vote counts. A larger default makes each record bigger; review rows never trigger UPDATED.
Output views
The dataset has these views: Results (overview), Products, Review summary, Sellers, Reviews (one row per review), and Changes (incremental). Every run writes an OUTPUT record in the key-value store with the run summary (records by kind, skipped links, unreadable pages, whether the time limit cut the scan short).
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.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | Search by keyword, or paste links in URL mode. |
query | string | iphone | Search mode: the product keyword. |
deliveryTime | string | empty (any) | Keep products deliverable within 4, 12, 24, 48, 72 or 120 hours. A client-side approximation applied to the collected results (shortest delivery estimate across sizes); products with no delivery estimate on their card are left out, and the log reports how many. |
includeMetaData | boolean | false | Add the raw card metadata object (meta) to each product. |
urls | array | one search link, one product link and one seller link | URL mode: search, product or seller pages, one per line. Category, brand and promotion pages are not supported and are skipped with a warning in the log. The filters apply to walked search links too. |
ignoreUrlFailures | boolean | true | Skip unsupported links with a warning and keep reading the rest. Off fails the run on any unsupported link. |
maxItemsPerUrl | integer | (none) | Cap on records read from each link. Empty splits Max items evenly. |
sortBy | string | popular | Popular, price low-to-high, price high-to-low, highest rated, newest. |
priceMin | integer | (none) | Only collect products priced at or above this many rubles, enforced on the collected rows. |
priceMax | integer | (none) | Only collect products priced at or below this many rubles, enforced on the collected rows. |
minRating | integer | (none) | Only collect products rated at or above this value (1-5). |
minFeedbacks | integer | (none) | Only collect products with at least this many customer reviews. |
onlyWithDiscount | boolean | false | Only collect products whose current wallet price is below the retail price. |
fetchDetails | boolean | false | Also fetch the full detail card (description, characteristics) per product when the source serves it. Adds a per-product surcharge only when that card is actually served. |
maxFeedbacksPerProduct | integer | 20 | Recent review rows attached per product (reviewer, rating, date, text, seller reply, helpful votes). 0 skips reviews; values above 1000 are capped at 1000. Larger values make each record larger. |
maxItems | integer | 20 | Maximum number of records to return across the whole run. In URL mode it is split evenly across the pasted links. 0 means no item limit: the run stops at Max pages or the natural end of the results. |
maxPages | integer | 0 | Maximum result pages read per search or link. 0 uses the built-in limit of 20 pages per scope. |
resumeFromRunId | string | (none; prefill empty) | Run id of a previous run; its collected record ids are seeded as already-seen. |
incrementalMode | boolean | false | Remember the previous run of the same search and stamp each record NEW, UPDATED or UNCHANGED by default (REAPPEARED/EXPIRED need Emit expired too, plus a complete scan). |
stateKey | string | (none) | Name for this monitoring campaign's saved 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. |
ignoreFieldsForChanges | array | (none) | Field names (dotted for nested) left out of UPDATED change detection; they are still returned. |
mcpConnectors | array | (none) | Optional MCP connectors to export results into. |
notionParentPageUrl | string | (none) | Notion parent page for the Notion connector. |
maxNotifyListings | integer | 50 | Cap on items written per connector. |
proxyConfiguration | object | (none; prefill selects the Residential connection group) | Connection settings. Datacenter connections do not work here; keep the Residential prefill. |
Output Example
Sample shape: values are illustrative placeholders, not from a live listing.
{"kind": "product","recordId": "nm:264193008","nmId": 264193008,"rootId": 264193000,"url": "https://www.wildberries.ru/catalog/264193000/detail.aspx","name": "Ceramic Travel Mug 350 ml Slate Blue","brand": "Zelwick","price": 1290.0,"priceRetail": 2150.0,"priceLogistics": 79.0,"discountPercent": 40,"hasDiscount": true,"currency": "RUB","rating": 4,"reviewRating": 4.6,"feedbacksCount": 812,"stock": 156,"warehouseIds": [512033],"deliveryDaysMin": 12,"deliveryDaysMax": 36,"supplierId": 71820456,"supplierName": "Orinvale Trade","supplierRating": 4.7,"imageUrl": "https://basket-10.wbbasket.ru/vol2641/part264193/264193008/images/c246x328/4.webp","description": "Ceramic travel mug with double-wall insulation, a spill-resistant lid and a silicone grip band.","characteristics": [{"group": "Materials", "name": "Body material", "value": "Ceramic"},{"group": "Materials", "name": "Lid material", "value": "Silicone"}],"feedbackSummary": {"valuation": "4.6","valuationSum": 812,"distribution": {"1": 12, "2": 9, "3": 41, "4": 210, "5": 540},"withText": 305,"withPhoto": 88},"feedbacks": [{"id": "wbfb7f3a29d1","createdDate": "2026-07-14T09:22:00+03:00","rating": 5,"text": "Keeps tea hot for hours, exactly as pictured.","pros": "Sturdy lid, good grip","cons": "Slightly heavier than expected","userName": "Dmitry K.","answerText": "Thanks for the feedback, glad it is working out for you.","photosCount": 1}],"changeType": "NEW","changedFields": [],"firstSeenAt": "2026-09-20T00:00:00+00:00","lastSeenAt": "2026-09-20T00:00:00+00:00"}
Plan Requirement
An Apify account with proxy usage enabled is required. Datacenter connections do not work for this marketplace: it answers every plain request, on every connection tier, with a browser access check (HTTP 498) instead of the page, so the actor earns a session token with a real browser and rotates fresh exits on refusals. Residential access is the recommended selection and is what the input prefills. If the selected connection is unavailable the actor escalates to the residential pool and then to a backup connection (Apify free plans do not include residential proxies; upgrade at https://apify.com/pricing or supply your own proxy URLs, which are used exactly as given).
What you see in the run log:
- When the selected connection is unavailable: "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable. For residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs."
- When pages are then served by the backup connection: "Served over the backup connection (the default connection was unavailable)."
- When the proxy connection is refused for the account and nothing could be read, the run fails with: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required: https://apify.com/pricing. If you entered your own proxy URLs, check that their credentials are valid."
- When residential is unavailable and the backup also reads nothing, the run fails with: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Wildberries pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again."
- When no results page loads for any other reason, the run fails with: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later."
A run that could not load any page therefore ends as failed with a plain message instead of reporting an empty success. Runs are aware of the platform time limit: they stop starting new reads before the limit and end honestly instead of being cut off mid-flight.
Pricing and billing
The Pricing tab shows the live rates; this page does not quote amounts. Three events exist:
- Product record (
apify-default-dataset-item): once per record pushed to the dataset (product, review-surface or seller record). Unchanged rows suppressed by incremental mode are not pushed and not billed. - Detail enrichment (
detail-enrichment): once per product, only when Fetch details is on and the detail card was actually served for that product. Products without a served card are not charged. - Actor start (
apify-actor-start): once per run, scaled per GB of run memory.
Use Max items to cap the cost of any run. Reviews are capped at 1000 per product.
FAQ
How much does it cost?
You pay per record returned, with the optional full detail card billed only for the products it was actually fetched for, never merely for switching the option on. The Pricing tab shows the current rates. Use Max items to cap the cost of any run.
Is it legal to scrape Wildberries?
This actor collects only publicly available marketplace data. You are responsible for how you use it: follow Wildberries' terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product listings and prices are generally facts, but brand names, images and seller registration data may be subject to third-party rights.
Can I get only new or changed products on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode with a State key for the campaign. Each run then returns only new and updated records, and unchanged ones are not billed unless you turn that on too.
What is the difference between Resume and Incremental mode?
Resume continues ONE specific interrupted run so you don't pay for records it already collected. Incremental mode is for running the SAME search again and again (for example daily) and getting only what changed since last time, using a saved baseline. They solve different problems and can be used independently or together.
Why did my run fail instead of returning an empty dataset?
If the site refuses every request, or answers with a page that has lost its expected product data, the run stops with a clear message so "no results" is never confused with "nothing could be read". Run it again in a few minutes. If only some pages could not be read while others returned records, the run still succeeds and its status message says so.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
🔗 Want more classifieds data?
Pair this actor with these related scrapers from the same team:
| 🏷️ Avito.ru Scraper Scrape structured listings from Avito.ru by region, category, filters, or direct URL... | 🏷️ bol.com Scraper Scrape bol.com products: title, price, list price and discount, EAN, brand, images... |
| 🏷️ Vinted Multi-Country Scraper Scrape Vinted across 27 country marketplaces: keyword search with brand, price and... | 🏷️ Kleinanzeigen.de Scraper Scrape Kleinanzeigen.de ads by keyword, category, location, price, seller type, or search... |
| 🏷️ Curtsy Fashion Resale Scraper Scrape Curtsy, the US secondhand fashion marketplace: listings with brand, size, list vs... | 🏷️ 2dehands & 2ememain Scrape classifieds from 2dehands.be and 2ememain.be by keyword, filters, or URLs. Returns... |
💬 Support
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.