# eMAG.ro Product & Price Scraper – Search, Category & Offers (`openharvest/emag-scraper`) Actor

eMAG.ro scraper for search results, category listings and product pages: price, previous price, discount, rating, review count, stock, seller, badges and images, plus every seller offer for price comparison, brand and specifications. Romania. No login, no browser.

- **URL**: https://apify.com/openharvest/emag-scraper.md
- **Developed by:** [Enes Bulanık](https://apify.com/openharvest) (community)
- **Categories:** E-commerce, Automation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 products

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

## eMAG.ro Product & Price Scraper – Search, Category & Offers

eMAG.ro scraper for product search results, category listings and product pages: price, previous price, discount, rating, review count, stock, seller and images, plus **every seller offer** on a product (marketplace price comparison), brand, specifications and description. Romania. No login, no browser.

Use it instead of a general web crawler when you need clean eMAG.ro prices and the full list of marketplace sellers for a product in one row.

**Price: $1.20 per 1,000 listing products, $3 per 1,000 products with full details and all seller offers.** Errors and empty searches are free.

### What data do you get from eMAG.ro?

From **search and category pages** (fast, 60 products per request):

- **Product** – name, URL, eMAG product code (PNK), product ID, offer ID, image
- **Price** – current price in RON, struck-through previous price, manufacturer's recommended price (PRP) and discount %
- **Rating** – average rating and number of reviews
- **Stock** – availability text (`În stoc`, `Ultimele 3 produse`, `Precomandă`…)
- **Seller** – who sells the buy-box offer and whether it is eMAG itself
- **Badges** – Top Favorite, Super Preț, Genius and other campaign badges
- **Category** – category ID, name and full department path, position on the page

With **Include product details and all seller offers** (or when you give a product URL), each product also gets:

- **Brand and part number (MPN)**
- **Specifications** as a name → value object (e.g. `"Sistem de operare": "iOS"`)
- **Description** (plain text), **all images**, **breadcrumbs**
- **All seller offers**, cheapest first: seller name, seller ID, seller rating and positive-feedback %, price, previous price, lowest price of the last 30 days, stock code, return period, whether it is the buy-box offer and whether eMAG sells or ships it
- **Min and max price across sellers** and the number of sellers

### Use cases

- **Price monitoring** – track prices and discounts of your products or competitors on eMAG.ro every day.
- **Marketplace seller analysis** – see who else sells the same product, at what price and with what rating; find out who holds the buy box.
- **Assortment and category research** – export a whole category with prices, ratings and review counts.
- **MAP / PRP compliance** – compare seller prices with the recommended retail price.
- **Retail and e-commerce analytics for Romania** – feed eMAG data into spreadsheets, BI tools or AI pipelines.

### How to scrape eMAG.ro

1. Click **Try for free** / **Start**.
2. Type one or more **Search keywords** (e.g. `casti wireless`) and/or paste **eMAG.ro URLs** – category pages (`https://www.emag.ro/telefoane-mobile/c`), filtered or brand pages, search pages or product pages.
3. Set **Max products per keyword / URL**, pick a **Sort order** and decide whether you need **product details and all seller offers**.
4. Click **Start**, then download the data as JSON, CSV, Excel or HTML, or connect it to Make, Zapier, Google Sheets, webhooks or the Apify API.

### Input

| Field | Type | Description |
|---|---|---|
| `searchQueries` | array of strings | Keywords to search on eMAG.ro, e.g. `casti wireless`. |
| `startUrls` | array of strings | eMAG.ro category, brand/filter, search or product URLs, or bare product codes (`DN2N7G2BM`). |
| `maxItems` | integer | Max products per keyword / URL. `0` = all (eMAG shows up to 100 pages × 60). Default `60`. |
| `includeDetails` | boolean | Open every product page and add specifications, description, images and all seller offers. Default `false`. |
| `sort` | string | `relevance` (default), `price-asc`, `price-desc`, `reviews`, `newest`, `discount`. |
| `proxyConfiguration` | object | Optional. The Actor switches to Apify Proxy on its own if eMAG blocks it. |

Example input:

```json
{
    "searchQueries": ["casti wireless"],
    "startUrls": [
        "https://www.emag.ro/telefoane-mobile/brand/apple/c",
        "https://www.emag.ro/telefon-mobil-apple-iphone-18-pro-256gb-5g-burgundy-mjrr4zd-a/pd/DN2N7G2BM/"
    ],
    "maxItems": 100,
    "sort": "price-asc",
    "includeDetails": false
}
```

### Output

Each dataset item has a `type`: `product` or `error`. Product rows have `detailLevel` set to `listing` (from search/category cards) or `full` (product page plus seller offers). Real sample output (shortened):

**Listing product**

```json
{
    "type": "product",
    "detailLevel": "listing",
    "source": "search",
    "searchQuery": "casti wireless",
    "page": 1,
    "position": 7,
    "productId": 102925881,
    "offerId": 273557010,
    "pnk": "DZ68XV3BM",
    "name": "Casti Apple Airpods Pro 3, Carcasa MagSafe (USB-C)",
    "url": "https://www.emag.ro/casti-apple-airpods-pro-3-carcasa-magsafe-usb-c-mfhp4zm-a/pd/DZ68XV3BM/",
    "price": 1249.99,
    "currency": "RON",
    "previousPrice": null,
    "recommendedRetailPrice": null,
    "discountPercent": null,
    "rating": 4.78,
    "reviewCount": 222,
    "availability": "În stoc",
    "sellerName": "eMAG",
    "soldByEmag": true,
    "isGenius": true,
    "badges": ["Top Favorite"],
    "categoryId": 2416,
    "categoryName": "Casti Wireless",
    "categoryTrail": "TV, Audio-Video & Foto/Playere, Boxe & Casti/Casti Wireless",
    "imageUrl": "https://s13emagst.akamaized.net/products/102926/102925881/images/res_9ece9931dcc5bbfd309ee2bb6bcadb79.jpg",
    "scrapedAt": "2026-10-08T10:41:25.124Z"
}
```

**Product with details and all seller offers**

```json
{
    "type": "product",
    "detailLevel": "full",
    "source": "product",
    "pnk": "DN2N7G2BM",
    "name": "Telefon mobil Apple iPhone 18 Pro, 256GB, 5G, Burgundy",
    "brand": "Apple",
    "partNumber": "MJRR4ZD/A",
    "price": 7699.9,
    "currency": "RON",
    "rating": 5,
    "reviewCount": 18,
    "availability": "Precomandă",
    "availabilityCode": "preorder",
    "sellerName": "eMAG",
    "soldByEmag": true,
    "breadcrumbs": ["Laptop, Tablete & Telefoane", "Telefoane mobile & accesorii", "Telefoane Mobile", "Telefoane Mobile Apple"],
    "specifications": { "Sistem de operare": "iOS", "Model procesor": "Apple A20 Pro", "Dimensiune ecran": "6.3 inch" },
    "images": ["https://s13emagst.akamaized.net/products/141457/141456450/images/res_1d3fb7bd99d5f1fea115fdc30468909f.jpg"],
    "offersCount": 5,
    "minOfferPrice": 7699.9,
    "maxOfferPrice": 12840.01,
    "offers": [
        { "sellerName": "eMAG", "sellerId": 1, "sellerRating": 4.8, "sellerPositiveFeedbackPercent": 95, "price": 7699.9, "availabilityCode": "preorder", "isMainOffer": true, "soldByEmag": true, "fulfilledByEmag": true, "returnPeriodDays": 0 },
        { "sellerName": "evomag", "sellerId": 112144, "sellerRating": 4.5, "sellerPositiveFeedbackPercent": 87, "price": 8442.1, "previousPrice": 8550.21, "availabilityCode": "limited_stock_qty", "isMainOffer": false, "returnPeriodDays": 14 },
        { "sellerName": "Flanco", "sellerId": 199, "sellerRating": 4.8, "sellerPositiveFeedbackPercent": 96, "price": 8599.99, "availabilityCode": "in_stock", "isMainOffer": false, "returnPeriodDays": 14 }
    ]
}
```

**Error (free)**

```json
{
    "type": "error",
    "input": "https://www.emag.ro/categorie-inexistenta-xyz/c",
    "errorCode": "NOT_FOUND",
    "error": "eMAG returned \"page not found\" for https://www.emag.ro/categorie-inexistenta-xyz/c. Check the category URL."
}
```

Possible `errorCode` values: `INVALID_INPUT`, `NOT_FOUND`, `NO_RESULTS`, `DETAIL_FAILED`, `BLOCKED`, `SCRAPE_FAILED`.

The dataset has ready-made views in Apify Console: **Overview**, **Seller offers** and **Errors (free)**.

### Pricing

This Actor uses **pay-per-event** pricing – you pay only for the products you get. Platform usage and proxies are included.

| Event | Price | When it is charged |
|---|---|---|
| `product` | **$0.0012** per product ($1.20 / 1,000) | Each product from a search or category page |
| `product-detail` | **$0.003** per product ($3 / 1,000) | Each product with details and all seller offers (instead of `product`, not on top of it) |
| Errors | **Free** | Invalid URLs, missing pages, empty searches, blocked requests |

Examples:

| Job | Cost |
|---|---|
| 60 search results for one keyword | 60 × $0.0012 = **$0.072** |
| 1,000 products from a category | **$1.20** |
| 100 products with details and seller offers | **$0.30** |

Duplicate products inside one run are skipped and not charged. Tip: set **Max cost per run** in the run options – the scraper stops cleanly when your budget is reached.

### Use with AI agents (MCP)

AI agents can call this Actor as a tool through the Apify MCP server (`https://mcp.apify.com`). Ask your agent, for example, *"Find the 20 cheapest wireless headphones on eMAG.ro with at least 4.5 stars"* or *"Who sells the iPhone 18 Pro on eMAG and at what price?"*. Example tool input:

```json
{
    "searchQueries": ["casti wireless"],
    "maxItems": 20,
    "sort": "price-asc"
}
```

For the seller comparison, pass the product URL in `startUrls` – product URLs always return the full record with every seller offer.

### FAQ

**Do I need an eMAG account?**
No. The scraper reads public eMAG.ro pages that anyone can open without logging in.

**Which countries are supported?**
eMAG Romania (`emag.ro`). eMAG Bulgaria (`emag.bg`) and Hungary (`emag.hu`) block automated traffic, so their URLs return a free `INVALID_INPUT` row for now.

**How many products can I get?**
eMAG shows 60 products per page and at most 100 pages for any search or category (6,000 products). For bigger categories, use several filtered or brand URLs (e.g. `/telefoane-mobile/brand/apple/c`).

**Why does a search return a category?**
eMAG redirects some keywords (e.g. `laptop`) straight to a category page. The scraper follows the redirect and scrapes that category.

**What is `previousPrice` vs. `recommendedRetailPrice`?**
`previousPrice` is the struck-through price eMAG shows (by EU rules, the lowest price in the 30 days before a discount). `recommendedRetailPrice` is the manufacturer's recommended price (PRP). `discountPercent` uses the previous price when present, otherwise the PRP.

**Why are some fields null on listing rows?**
Brand, specifications, description and the seller-offer list are only on product pages. Turn on **Include product details and all seller offers** to get them.

**What happens if eMAG blocks the scraper?**
eMAG rate-limits busy IP addresses with a captcha page. The Actor then switches to Apify Proxy automatically (datacenter first, then Romanian residential IPs) and retries. If it still cannot get through, you get a free `BLOCKED` row and are not charged.

**Can I run it on a schedule?**
Yes. Use Apify Schedules to track prices daily and compare runs.

### Is it legal to scrape eMAG.ro?

This Actor extracts only **publicly available product and offer data** that eMAG.ro shows to every visitor without login. It does not collect reviewer names, user profiles or any other personal data, and it sends requests at a polite rate (small concurrency, delays and backoff). Seller names are business names shown on the public offer list. Make sure your use of the data complies with eMAG's terms of use and applicable laws (e.g. GDPR, database and copyright law). If you are unsure, consult a lawyer.

### Related actors

Other actors by the same developer:

- **Shopify & WooCommerce Products Scraper – Any Store, Schema.org** – prices, stock and variants from any online store
- **Keyword Suggestions – Google, YouTube, Amazon & Bing Autocomplete** – find the product keywords people search for
- **Google Trends Scraper – Interest Over Time & Related Queries** – check demand for a product category in Romania
- **Sitemap URL Extractor – All URLs from sitemap.xml & robots.txt** – list every product URL of a shop

### Support & feedback

Found a bug or missing field? Open an issue in the **Issues** tab with the eMAG.ro URL.

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords to search on eMAG.ro, exactly as you would type them in the eMAG search box (Romanian works best, e.g. <code>casti wireless</code>, <code>laptop gaming</code>). If eMAG maps a keyword to a category, the category is scraped. Leave empty if you only use URLs below.

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

eMAG.ro URLs. Category, brand or filtered listings (<code>https://www.emag.ro/telefoane-mobile/c</code>, <code>https://www.emag.ro/telefoane-mobile/brand/apple/c</code>), search pages (<code>https://www.emag.ro/search/tv</code>) and product pages (<code>https://www.emag.ro/.../pd/DN2N7G2BM/</code>) or bare product codes (<code>DN2N7G2BM</code>). Product pages always return full details with all seller offers.

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

Maximum number of products to save for each search keyword or listing URL (eMAG shows 60 per page, up to 100 pages). Set 0 for no limit. You pay per product, so this also caps your cost.

## `includeDetails` (type: `boolean`):

Open every product page and add brand, part number, specifications, description, all images, breadcrumbs and the full list of seller offers (seller, seller rating, price, stock, return period). Slower and charged as a 'product-detail' event instead of 'product'.

## `sort` (type: `string`):

Order of search and category results, using eMAG's own sort options.

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

Usually not needed - eMAG.ro works without a proxy. If eMAG blocks the run, the Actor switches to Apify Proxy automatically. Set your own proxy here only if you want full control.

## Actor input object example

```json
{
  "searchQueries": [
    "casti wireless",
    "iphone 17",
    "espressor"
  ],
  "startUrls": [
    "https://www.emag.ro/telefoane-mobile/c",
    "https://www.emag.ro/telefon-mobil-apple-iphone-18-pro-256gb-5g-burgundy-mjrr4zd-a/pd/DN2N7G2BM/"
  ],
  "maxItems": 100,
  "includeDetails": false,
  "sort": "price-asc",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All scraped items in the default dataset (JSON, CSV, Excel and more via the dataset export).

## `files` (type: `string`):

Records saved in the default key-value store, e.g. the run summary.

# 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 = {
    "searchQueries": [
        "casti wireless"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("openharvest/emag-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 = {
    "searchQueries": ["casti wireless"],
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("openharvest/emag-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 '{
  "searchQueries": [
    "casti wireless"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call openharvest/emag-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,openharvest/emag-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/rfqQ6w7eBZw3I71Oc/builds/xJBJz12DMEV8Hccpi/openapi.json
