# M.Video Russia Electronics Product & Review Scraper (`nimbryxo-studio/m-video-russia-electronics-product-and-review`) Actor

Search, browse categories, or fetch full product detail from mvideo.ru, including price, rating, specifications, images, seller info, and customer reviews.

- **URL**: https://apify.com/nimbryxo-studio/m-video-russia-electronics-product-and-review.md
- **Developed by:** [Nimbryxo-studio](https://apify.com/nimbryxo-studio) (community)
- **Categories:** E-commerce, Automation, Lead generation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## M.Video Russia Electronics Product & Review Scraper

Scrape **mvideo.ru**, one of Russia's largest electronics and appliance retailers, without cookies, logins, or proxy setup. Search the full catalog, browse any category with live brand / condition / price filters, pull complete product detail with seller and store availability, and export customer reviews — all for a chosen Russian city.

### What this actor does

- **Four modes:** `search`, `byCategory`, `productDetails`, `reviews`
- **Full pagination** — search walks every result page (about 2,100+ unique TV listings across ~38 pages at test time), de-duplicated by product ID
- **Live facets** — brand, seller, condition and parallel-import filters are resolved from each response, so the actor uses the IDs the site is actually serving instead of stale hardcoded values
- **City-aware availability** — stock status, pickup stores and delivery dates follow the city you choose (Москва, Санкт-Петербург, Владивосток, Казань, Екатеринбург, Новосибирск and others)
- **Product detail** — prices, promo discounts, bonus rubles, rating, specifications, images, breadcrumbs, similar SKUs, seller/buybox and other marketplace offers
- **Store stock** — optional per-store pickup list with address, metro, coordinates, quantity and schedule
- **Customer reviews** — paginated review export with rating, text, pros/cons, photos, replies and likes; product detail adds the star histogram
- **Empty fields are omitted** — no `null` placeholders anywhere in a record

### Output per product (`recordType: "product"`)

- `productId`, `name`, `modelName`, `brandName`, `brandId`
- `productUrl`, `sourceUrl`
- `categoryId`, `categoryName`, `breadcrumbs[]`, `breadcrumbPath[]` (`{name, categoryId}`)
- `salePrice`, `basePrice`, `promoPrice`, `discountPercent`, `discountAmount`, `discounts[]`, `bonusAmount`, `currency`
- `ratingStar`, `ratingCount`, `totalRating`, `ratingsStats`, `ratingBreakdown`, `reviewsTotal`, `reviews[]`
- `inStock`, `soldOut`, `availabilityStatus`, `availabilityDate`, `storeOnly`, `isPrepayment`, `showcase`, `isPreorder`, `isLastChance`, `isNew`
- `condition`, `productType`, `materialSource`
- `description`, `specifications[]`, `weightKg`, `imageUrl`, `imageUrls[]`, `videos[]`, `images3d[]`, `certificates[]`, `instructions[]`
- `seller` (`{id, name, legalName, inn, ogrn, address, phone, rating, orders, reviews}`), `multiofferCount`, `otherOffers[]`, `similarProducts[]`
- `deliveryDate`, `stockLocation`, `hasExpressDelivery`, `prepaidOnly`
- `stores[]` (`{storeId, name, address, metro, lat, lng, quantity, availabilityDate, schedule, isAllDay}`), `storeCount`, `storeQuantity`
- `cityId`, `cityName`, `regionId`
- `position`, `query`, `source`, `recordType`, `scrapedAt`

Listing modes (`search`, `byCategory`) return the identity, price, stock, rating and image fields available in the catalog response. Detail enrichment (specifications, seller, stores, reviews) is produced by `productDetails`.

### Output per review (`recordType: "review"`, mode = `reviews`)

- `reviewId`, `productId`, `productUrl`
- `rating`, `author`, `date`
- `text`, `pros`, `cons`
- `photos[]`, `responses[]`
- `likes`, `dislikes`, `isPopular`
- `recordType`, `scrapedAt`

### Output per error record (`recordType: "error"`)

Invalid or unavailable product IDs in `productDetails` mode produce an error row instead of being dropped. Error rows carry `errorType` (`invalid_input`), `productId`, `message`, `mode`, `sourceUrl`, `retryable`, `cityId`, `cityName`, `regionId` and `scrapedAt`, and never count toward `maxItems`.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` / `byCategory` / `productDetails` / `reviews` |
| `searchQuery` | string | `телевизор` | Free-text query (mode=search) |
| `city` | string | `Москва` | City name or mvideo city ID; controls stock, stores and delivery |
| `category` | string (select) | `""` | Top-level category (mode=byCategory) |
| `categoryUrl` | string | – | Any category URL or slug/ID; overrides `category` |
| `productUrls` | array | `[]` | Product URLs or numeric IDs (mode=productDetails / reviews) |
| `brands` | array | `[]` | Brand names or slugs, e.g. `Samsung`, `lg` |
| `sellers` | array | `[]` | Seller names or slugs, e.g. `BQ.ru`, `bqru` (mode=byCategory; search has no seller facet) |
| `minPrice` / `maxPrice` | integer | – | Sale-price range in RUB |
| `minRating` | number | – | Minimum rating (0–5); unrated products are excluded when set |
| `minDiscount` | integer | – | Minimum discount percent (0–99) |
| `condition` | string | `any` | `any` / `new` / `refurbished` / `used` / `markdown` / `showcase` (search / category; resolved from the live facet) |
| `fromAbroad` | boolean | `false` | Parallel-import listings only (mode=search) |
| `sortOrder` | string | `popularity` | `popularity` / `priceAsc` / `priceDesc` |
| `maxItems` | integer | `100` | Hard cap on emitted records (0–10,000; `0` = all, capped at 10,000) |
| `maxReviews` | integer | `20` | Reviews per product (0–200; 20 per page) |
| `includeStoreStock` | boolean | `false` | Attach `stores[]` in mode=productDetails |
| `storeLimit` | integer | `20` | Maximum stores per product |
| `includeOtherOffers` | boolean | `true` | Attach `otherOffers[]` in mode=productDetails |
| `failOnEmpty` | boolean | `false` | Mark the run failed when zero records are emitted |
| `proxyConfiguration` | object | automatic | Optional; the actor connects directly first and escalates only if blocked |

#### Example: search with filters

```json
{
  "mode": "search",
  "searchQuery": "телевизор",
  "city": "Москва",
  "brands": ["Samsung", "LG"],
  "minPrice": 30000,
  "maxPrice": 90000,
  "condition": "new",
  "sortOrder": "priceAsc",
  "maxItems": 200
}
```

#### Example: browse a category, used or refurbished only

```json
{
  "mode": "byCategory",
  "categoryUrl": "https://www.mvideo.ru/televizory-i-cifrovoe-tv-1/televizory-65",
  "city": "Санкт-Петербург",
  "condition": "refurbished",
  "minDiscount": 10,
  "maxItems": 100
}
```

#### Example: full detail with stores and seller offers

```json
{
  "mode": "productDetails",
  "productUrls": [
    "https://www.mvideo.ru/products/televizor-general-electronics-ge55lqs2-401211841",
    "402415077"
  ],
  "city": "Москва",
  "maxReviews": 20,
  "includeStoreStock": true,
  "includeOtherOffers": true
}
```

#### Example: export reviews

```json
{
  "mode": "reviews",
  "productUrls": ["400205087"],
  "maxReviews": 200,
  "maxItems": 200
}
```

### Use cases

- **Price monitoring** — track sale prices, promo discounts and bonus rubles across a category
- **Assortment research** — compare brand and seller coverage in Russian electronics retail
- **Catalog enrichment** — pull specifications, images and breadcrumbs for a known SKU list
- **Availability intelligence** — monitor stock and pickup stores by city for selected products
- **Review analytics** — export review text, pros/cons and star distributions for sentiment analysis
- **Marketplace seller tracking** — compare the buybox seller and other offers on marketplace listings

### FAQ

**Do I need cookies, a login, or a proxy?** No. Catalog, product detail and reviews are read from mvideo.ru's public endpoints without an account. The actor connects directly first; if the site temporarily rate-limits a detail or review request, it retries and falls back to a real browser session, and only then to a different Apify Proxy route. If every HTTP route is blocked, it can continue in a browser-only session. You do not configure anything.

**Why does the city matter?** mvideo.ru serves city-specific stock, pickup stores and delivery dates. In testing, catalog prices for fixed products did not differ between cities, so treat the city setting as an availability selector rather than a price-comparison tool.

**How many search results can I get?** Search pages through the source's own cursor. At the time of testing, `телевизор` declared 2,253 results across 38 pages and yielded 2,125 unique products; the source itself does not surface a small number of advertised or duplicate rows. Set `maxItems` to the number you need.

**Why are some fields missing on some products?** Empty fields are omitted. Marketplace rows may lack a description, an M.Video-owned product has no third-party seller, and not every SKU has a rating, discount, store stock or video.

**Are videos and 3D images included?** The fields exist and are filled when mvideo.ru returns them, but most products have none. The actor does not promise video or 3D content.

**What does `condition` guarantee?** The filter is applied through the site's live condition facet. Refurbished and markdown items can be recognized from the product name; marketplace "used" listings do not always expose a machine-readable condition, so treat the echoed condition as the filter you requested, not a per-row certification.

**Can I sort by rating, newest, or discount?** No. Popularity and sale-price ordering are supported. For `priceAsc` / `priceDesc`, the actor sorts the emitted rows by sale price because the source's own ordering is approximate. `minRating` and `minDiscount` are applied as filters instead.

**Why is there no "in stock only" toggle?** In validation, every sampled catalog listing was marked available, so the toggle was a no-op. Use the `inStock` / `soldOut` fields in the output if you need to filter downstream.

**How many reviews can I fetch?** The source serves 20 reviews per page with no login wall. `maxReviews` controls the per-product cap (up to 200); `maxItems` caps the total rows in `reviews` mode.

**Are review filters or date sorting supported?** No. The review list supports useful/rating ordering; the undocumented review filters returned empty results in testing, so they are not exposed.

**Why did a brand or seller filter stop the run?** Filter facets are resolved from the live response. If a requested brand, seller, condition or parallel-import facet is not present for that query or category, the actor stops with a clear message rather than silently returning unfiltered results. Remove that filter or try a broader query/category.

**How fresh is the data?** Every run reads current catalog, price, stock and review data directly from mvideo.ru.

**Is this actor affiliated with mvideo.ru?** No. It is an independent, third-party actor that reads publicly reachable product data. It is not affiliated with, endorsed by, or operated by M.Video.

# Actor input Schema

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

What to fetch.

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

Free-text product search, e.g. телевизор, ноутбук, холодильник. The full result set is paginated automatically.

## `city` (type: `string`):

Russian city name or mvideo city ID (e.g. Москва, Санкт-Петербург, CityCZ_975). City changes stock availability, pickup stores and delivery dates.

## `category` (type: `string`):

Top-level mvideo.ru category to browse. Use `categoryUrl` for any sub-category not listed here.

## `categoryUrl` (type: `string`):

Overrides `category`. Accepts a full mvideo.ru category URL (e.g. https://www.mvideo.ru/televizory-i-cifrovoe-tv-1/televizory-65) or a bare numeric category ID, for sub-categories not in the dropdown.

## `productUrls` (type: `array`):

mvideo.ru product URLs (e.g. https://www.mvideo.ru/products/televizor-...-401211841) or bare numeric product IDs. Used by productDetails and reviews modes.

## `sortOrder` (type: `string`):

Result ordering. Only popularity and price ordering are supported by the source; other orderings are not promised.

## `brands` (type: `array`):

Only return products from these brands. Accepts brand names or mvideo.ru slugs (e.g. `Samsung`, `samsung`, `LG`). The matching facet is resolved from the live response, so no hardcoded IDs are needed. Multiple values are OR'd together.

## `sellers` (type: `array`):

Only return products from these marketplace sellers. Accepts seller names or mvideo.ru seller slugs (e.g. `BQ.ru`, `bqru`). The seller facet exists in category browsing only; the search response has no seller facet, so a search run with sellers set stops with a clear message. Multiple values are OR'd together.

## `minPrice` (type: `integer`):

Drop products cheaper than this (sale price, in Russian rubles). Applied server-side in search/category mode and client-side for detail records.

## `maxPrice` (type: `integer`):

Drop products more expensive than this (sale price, in Russian rubles). Applied server-side in search/category mode and client-side for detail records.

## `minRating` (type: `number`):

Drop products with a customer rating below this (0-5 stars). Applied after catalog fetches (the API has no rating facet). Products with no rating are excluded when this filter is set.

## `minDiscount` (type: `integer`):

Drop products with a smaller discount than this (0-99 percent). Applied after catalog fetches (the API has no discount facet). Products without a discount are excluded when this filter is set.

## `condition` (type: `string`):

Filter by item condition. The matching facet is resolved from the live response; if it is unavailable for a query/category, the run stops with a clear message instead of returning unfiltered results.

## `fromAbroad` (type: `boolean`):

Only return parallel-import listings. Applies to search mode only; ignored in category mode.

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

Hard cap on emitted records (products, or review rows in mode=reviews). Search covers the full result set across all pages, de-duplicated by product ID. Use 0 for all (up to the 10,000 cap).

## `maxReviews` (type: `integer`):

Reviews to fetch per product in mode=productDetails (attached as `reviews[]`) and mode=reviews (one row per review). Paginated 20 at a time; 0 skips review fetching.

## `includeStoreStock` (type: `boolean`):

Fetch per-store pickup availability for the selected city and attach a `stores[]` list.

## `storeLimit` (type: `integer`):

Cap on `stores[]` entries per product when store stock is included.

## `includeOtherOffers` (type: `boolean`):

Fetch the seller/buybox block and attach `otherOffers[]` with prices and seller details when available.

## `failOnEmpty` (type: `boolean`):

Mark the run as failed when zero records are emitted (for example a blocked connection or an empty query).

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

Optional. The actor connects directly first and only escalates to Apify Proxy if mvideo.ru blocks a request. Change this only if you need a specific proxy setup.

## Actor input object example

```json
{
  "mode": "search",
  "searchQuery": "телевизор",
  "city": "Москва",
  "category": "1",
  "productUrls": [
    "https://www.mvideo.ru/products/televizor-general-electronics-ge55lqs2-401211841"
  ],
  "sortOrder": "popularity",
  "brands": [],
  "sellers": [],
  "condition": "any",
  "fromAbroad": false,
  "maxItems": 3,
  "maxReviews": 20,
  "includeStoreStock": false,
  "storeLimit": 20,
  "includeOtherOffers": true,
  "failOnEmpty": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Dataset containing scraped M.Video products (recordType=product), customer reviews (recordType=review), and invalid-input error rows (recordType=error).

# 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",
    "searchQuery": "телевизор",
    "city": "Москва",
    "category": "1",
    "productUrls": [
        "https://www.mvideo.ru/products/televizor-general-electronics-ge55lqs2-401211841"
    ],
    "sortOrder": "popularity",
    "brands": [],
    "sellers": [],
    "condition": "any",
    "fromAbroad": false,
    "maxItems": 3,
    "maxReviews": 0,
    "includeStoreStock": false,
    "storeLimit": 20,
    "includeOtherOffers": false,
    "failOnEmpty": false,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nimbryxo-studio/m-video-russia-electronics-product-and-review").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",
    "searchQuery": "телевизор",
    "city": "Москва",
    "category": "1",
    "productUrls": ["https://www.mvideo.ru/products/televizor-general-electronics-ge55lqs2-401211841"],
    "sortOrder": "popularity",
    "brands": [],
    "sellers": [],
    "condition": "any",
    "fromAbroad": False,
    "maxItems": 3,
    "maxReviews": 0,
    "includeStoreStock": False,
    "storeLimit": 20,
    "includeOtherOffers": False,
    "failOnEmpty": False,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("nimbryxo-studio/m-video-russia-electronics-product-and-review").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",
  "searchQuery": "телевизор",
  "city": "Москва",
  "category": "1",
  "productUrls": [
    "https://www.mvideo.ru/products/televizor-general-electronics-ge55lqs2-401211841"
  ],
  "sortOrder": "popularity",
  "brands": [],
  "sellers": [],
  "condition": "any",
  "fromAbroad": false,
  "maxItems": 3,
  "maxReviews": 0,
  "includeStoreStock": false,
  "storeLimit": 20,
  "includeOtherOffers": false,
  "failOnEmpty": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call nimbryxo-studio/m-video-russia-electronics-product-and-review --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nimbryxo-studio/m-video-russia-electronics-product-and-review"
        }
    }
}
```

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/L2mrRaxKqV5naozzW/builds/PKTIXhzs7ROGYFfPO/openapi.json
