# eMAG Seller Scraper – Vendors, Contacts & Categories (`sergiumeserias/emag-seller-scraper-vendors-contacts-categories`) Actor

Discover and enrich public eMAG marketplace seller profiles across Romania, Bulgaria, and Hungary, including company details, public contacts, categories, and resumable exports. Proxy support improves routing but does not guarantee access.

- **URL**: https://apify.com/sergiumeserias/emag-seller-scraper-vendors-contacts-categories.md
- **Developed by:** [Sergiu Adrian](https://apify.com/sergiumeserias) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.50 / 1,000 full seller profiles

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 Seller Scraper – Vendors, Contacts & Categories

Discover eMAG marketplace sellers and export public company profiles, contact details, and category relationships across **Romania, Bulgaria, and Hungary**.

Use it for marketplace research, seller intelligence, lead qualification, category analysis, and competitive mapping. Runs are resumable, country-aware, and designed to minimize duplicate requests.

### What you can extract

- Seller name, seller ID, slug, and public profile URL
- Company name, tax ID, VAT ID, trade-register number, and status
- Registered and fiscal addresses, country, CAEN, bank, and IBAN when publicly displayed
- Public phone number and email, with full, masked, or availability-only output
- Seller rating, positive-rating percentage, and product counts when available
- Seller-to-category relationships in a separate export
- Run report with progress, blocked URLs, retries, billing events, and checkpoint data

### Three data packages

#### Seller discovery

Find unique seller identities from official category sitemaps, category filters, search pages, and product pages. Best for building a low-cost seller directory.

#### Full seller database

Discover sellers and visit each public seller page to add company, registration, address, rating, phone, and email fields.

#### Marketplace intelligence

Includes full seller profiles plus a separate seller-category dataset for category coverage and assortment analysis.

### Supported marketplaces

| Country | Domain | Proxy region |
| --- | --- | --- |
| Romania | `emag.ro` | Romania |
| Bulgaria | `emag.bg` | Bulgaria |
| Hungary | `emag.hu` | Hungary |

Choose one country or **All countries**. Multi-country runs process marketplaces sequentially so every request uses the matching regional proxy configuration.

### Quick start

1. Select a data package.
2. Choose Romania, Bulgaria, Hungary, or All countries.
3. Leave start URLs empty to use the official category sitemap, or provide category, search, product, seller, or sitemap URLs.
4. Set a maximum charge and seller limit.
5. Start the run and export sellers as JSON, CSV, Excel, XML, or JSONL.

#### Recommended full Romania run

```json
{
  "operation": "FULL",
  "targetCountry": "RO",
  "startUrls": [{ "url": "https://www.emag.ro/sitemaps/categories-index.xml" }],
  "contactMode": "full",
  "maxVendors": 25000,
  "maxListingPages": 2500,
  "maxVendorFilterPages": 2500,
  "maxConcurrency": 3,
  "delaySeconds": 4,
  "followProducts": false,
  "followPagination": false
}
```

### Output

#### Sellers dataset

The default dataset contains either discovery records or enriched seller profiles. Important fields include:

```json
{
  "marketplace": "ro",
  "seller_name": "Example Seller",
  "company_name": "EXAMPLE COMPANY SRL",
  "cui": "12345678",
  "vat_id": "RO12345678",
  "reg_com": "J40/1234/2024",
  "registered_address": "București, Romania",
  "country": "Romania",
  "phone": "+40...",
  "email": "contact@example.ro",
  "seller_url": "https://www.emag.ro/example/123456/v"
}
```

Fields not displayed publicly by eMAG are returned as `null`, never invented.

#### Seller categories dataset

Marketplace Intelligence runs also provide one row per seller-category relationship with seller ID, category URL, category name, and category-level product count when available.

#### Run report

`RUN_REPORT` records progress, retries, access challenges, recovery usage, output counts, pricing-event counts, and resume information.

### Reliable long runs

- Stable proxy sessions keep cookies and browser fingerprints together.
- A proxy-pool circuit breaker checkpoints and stops the run after repeated tunnel failures across several endpoints, preventing hours of compute without progress.
- Requests are rate-limited per session, not only globally.
- Retries are limited to transient network and server errors.
- Access challenges are logged, checkpointed, and skipped; proxy use does not guarantee access.
- Optional recovery fetching is disabled by default, capped when enabled, and does not solve CAPTCHA.
- Checkpoints persist discovered sellers, completed categories, pending work, and output IDs.
- `resumeFromRunId` continues unfinished work, copies each prior seller only once, prefers the richest duplicate record, and does not requeue completed profiles.
- Spending-limit responses stop the crawler cleanly after saving progress.

### Pricing

This Actor uses pay-per-event pricing so small tests remain inexpensive and full marketplace databases scale predictably.

| Event | Suggested price |
| --- | ---: |
| Actor start | Apify default |
| Vendor discovered | `$0.0025` |
| Full profile extracted | `$0.0065` |
| Seller-category relationship | `$0.0005` |

A full profile run with about 16,000 unique sellers is approximately `$104`, while discovery-only is approximately `$40`. Marketplace Intelligence adds seller-category events. Always set a maximum run charge in Apify Console.

### Data responsibility

This Actor extracts information displayed on public marketplace pages. It does not log into seller accounts, send messages, or solve CAPTCHA. Availability depends on eMAG, regional access, and site changes.

Public contact details can still be personal data, especially for sole traders. Users are responsible for a lawful purpose, data minimization, retention, applicable privacy law, eMAG terms, and electronic-marketing consent rules. Do not use extracted contacts for unsolicited outreach without the required legal basis and consent.

### Local tests

```bash
npm install
npm test
```

The test suite covers seller discovery, company/contact parsing, masking, proxy-session selection, transient retries, proxy-outage stopping, blocked-page detection, recovery limits, deduplicated resume behavior, pricing events, and Actor schemas.

### Support

When reporting an issue, include the run ID, marketplace country, operation, and affected public URL. Never include proxy credentials or API tokens.

# Actor input Schema

## `operation` (type: `string`):

Discovery exports seller identities. Full profiles adds public company and contact fields. Intelligence also exports seller-category relationships.

## `targetCountry` (type: `string`):

Run one marketplace or all three sequentially with the matching country proxy pool.

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

Leave empty to use the official category sitemap for the selected marketplace. Custom URLs must match the selected country.

## `contactMode` (type: `string`):

Full exports public phone and email values. Masked partially hides them. None returns only has_phone and has_email flags.

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

Copies completed results and restores unfinished requests from a previous run of this Actor without charging copied results again.

## `maxVendors` (type: `integer`):

Hard cap across the selected countries.

## `maxListingPages` (type: `integer`):

Maximum listing pages per country.

## `maxSitemapPages` (type: `integer`):

Maximum sitemap index and sitemap files per country.

## `maxProductPages` (type: `integer`):

Fallback discovery limit. Vendor filters are preferred because they use fewer requests.

## `maxVendorFilterPages` (type: `integer`):

Usually one request per category where the visible filter is truncated.

## `followPagination` (type: `boolean`):

Follow visible next-page links on category and search pages.

## `followProducts` (type: `boolean`):

Use only when category seller filters are insufficient; increases cost and runtime.

## `useVendorFilters` (type: `boolean`):

Extract seller IDs directly from the public Livrat de filter.

## `maxConcurrency` (type: `integer`):

Separate sticky sessions with isolated cookies. Higher values can increase blocking.

## `delaySeconds` (type: `integer`):

Minimum seconds between requests made by the same stable session.

## `maxRequestRetries` (type: `integer`):

Retries network and temporary server failures only. Access challenges are recorded and skipped.

## `wafFallbackEnabled` (type: `boolean`):

Optional paid recovery fetch for blocked public pages. It does not solve CAPTCHA and does not guarantee access.

## `maxWafFallbackCalls` (type: `integer`):

Hard cap for paid recovery child runs.

## `wafFallbackMaxChargeUsd` (type: `number`):

Maximum child-run charge in USD.

## `userAgent` (type: `string`):

Identifiable User-Agent sent with requests.

## Actor input object example

```json
{
  "operation": "FULL",
  "targetCountry": "RO",
  "startUrls": [
    {
      "url": "https://www.emag.ro/sitemaps/categories-index.xml"
    }
  ],
  "contactMode": "full",
  "maxVendors": 25000,
  "maxListingPages": 2500,
  "maxSitemapPages": 1000,
  "maxProductPages": 0,
  "maxVendorFilterPages": 2500,
  "followPagination": false,
  "followProducts": false,
  "useVendorFilters": true,
  "maxConcurrency": 3,
  "delaySeconds": 4,
  "maxRequestRetries": 2,
  "wafFallbackEnabled": false,
  "maxWafFallbackCalls": 0,
  "wafFallbackMaxChargeUsd": 0.07,
  "userAgent": "VendwiserResearchBot/1.0 (public marketplace research)"
}
```

# Actor output Schema

## `sellers` (type: `string`):

No description

## `sellerCategories` (type: `string`):

No description

## `runReport` (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 = {
    "startUrls": [
        {
            "url": "https://www.emag.ro/sitemaps/categories-index.xml"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sergiumeserias/emag-seller-scraper-vendors-contacts-categories").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 = { "startUrls": [{ "url": "https://www.emag.ro/sitemaps/categories-index.xml" }] }

# Run the Actor and wait for it to finish
run = client.actor("sergiumeserias/emag-seller-scraper-vendors-contacts-categories").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 '{
  "startUrls": [
    {
      "url": "https://www.emag.ro/sitemaps/categories-index.xml"
    }
  ]
}' |
apify call sergiumeserias/emag-seller-scraper-vendors-contacts-categories --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sergiumeserias/emag-seller-scraper-vendors-contacts-categories"
        }
    }
}
```

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/ngWyGlOW6LBzNy0cO/builds/5hS5hKlND33M0yV5J/openapi.json
