# Europages Scraper - B2B Companies & Contacts (`crawloop/europages-scraper`) Actor

Scrape Europages B2B company profiles across Europe. Get phone, email, VAT ID, address, GPS, certificates and contacts. Keyword, country, supplier type or profile URL. Fast curl_cffi HTTP; smart enrich on Apify.

- **URL**: https://apify.com/crawloop/europages-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** Lead generation, Other
- **Features:** Limited permissions
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 company 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

## Europages Scraper - B2B Companies & Contacts

> **Disclaimer:** Unofficial tool — not affiliated with, sponsored by, or endorsed by Europages or its affiliates. Data is read from publicly accessible pages only. No login. You are responsible for complying with applicable law (including GDPR where personal data appears) and the site’s terms. No warranty on accuracy or availability. Provided for informational and research use.

> **Contact-data controls:** Phone/WhatsApp/fax and email fields are omitted from the dataset by default. Enable `includePhones` and/or `includeEmails` only for contacts already published on public pages and only when you have a lawful basis. Any contact-field examples below assume that explicit opt-in; otherwise those fields are absent.

| Europages (Europe) | WLW (DACH) | KvK Handelsregister (NL) |
| :--- | :--- | :--- |
| **Europages Scraper** ◄── you are here | [WLW Scraper](https://apify.com/crawloop/wlw-scraper) | [KvK Handelsregister Scraper](https://apify.com/crawloop/kvk-handelsregister-scraper) |
| Multi-country EU directory, VAT, contacts, certificates | DE / AT / CH suppliers, phone, email, VAT, contacts | Dutch Chamber of Commerce search + KvK lookup |

**Europages scraper** for Apify — extract **European B2B company profiles** from the Europages directory into clean JSON. Collect **manufacturers, distributors, wholesalers and service providers** with **phone, email, VAT ID, street address, GPS coordinates, certificates**, named **contact persons**, and optional **product catalog cards**.

Ideal for **supplier sourcing**, **sales prospecting**, **CRM enrichment**, **market mapping**, and **compliance / firmographic research** across 15+ Europages language markets (DE, EN, FR, ES, IT, NL, PL, and more). Fast HTTP crawl of Nuxt SSR payloads via `curl_cffi` — no headless browser.

### Use cases

| Use case | What you get |
| :--- | :--- |
| **Find European suppliers** | Keyword / category listings with company id, city, country, website |
| **Lead & contact lists** | Phone, email, and named managers from company profiles |
| **Firmographics & compliance** | VAT ID, founding year, employee range, ISO / CE certificates |
| **Geo & territory mapping** | Street address plus latitude / longitude |
| **Product landscape** | Optional product cards from each company catalog |
| **Multi-country runs** | Same company UUID across DE / EN / FR / ES / IT / … locales |

### When to use this Actor

- You need **Europages B2B company data** as structured dataset rows
- You want **keyword, country, or supplier-type filters** (manufacturer, distributor, service, wholesaler)
- You prefer **startUrls** for specific company profiles or listing pages
- You need a **fast, browser-free** Europages crawl on Apify

### When not to use this Actor

- **Guaranteed email on every profile** — many free listings publish phone and website only
- **Authenticated / gated Europages fields** — public SSR payload only
- **Sending RFQs** through the Europages contact form — this Actor is read-only extraction
- **Non-Europages directories** — use a source-specific Actor instead

### Key features

- **Keyword search** — builds Europages SEO listing URLs (`/unternehmen/…`, `/companies/…`)
- **Category & start URLs** — paste listing pages or company profile links
- **15+ locales** — `de`, `en`, `fr`, `es`, `it`, `nl`, `pl`, `pt`, `tr`, `cs`, and more
- **Country & supplier-type filters** — manufacturers, distributors, services, wholesalers
- **Detail enrichment** — `fetchDetails` for VAT, contacts, certificates, geo, documents
- **Smart enrich** — skip profile fetch when listing already has email + phone + website
- **Optional products** — `includeProducts` attaches catalog cards from the profile
- **Streaming results** — dataset rows appear while the run is in progress
- **Deduped push** — unique by `companyId` / `uuid` within a run
- **Pagination controls** — `maxPages` + `maxItems` for predictable run size
- **Lightweight & resilient** — `curl_cffi` Chrome TLS fingerprinting, proxy session rotation on WAF challenges

### Input parameters

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `searchKeywords` | Array | `["pumps"]` | Keywords → Europages listing URLs. |
| `categoryUrls` | Array | `[]` | Direct listing / category URLs. |
| `startUrls` | Array | `[]` | Company profiles and/or extra listings. |
| `language` | String | `"de"` | Market locale / host (e.g. `de`, `en`, `fr`). |
| `country` | String | — | Optional country slug for keyword URLs (e.g. `deutschland`). |
| `supplierType` | String | — | `production`, `distribution`, `service`, `wholesaler`, … |
| `fetchDetails` | Boolean | `true` | Open profile pages for full fields (see smartEnrich). |
| `smartEnrich` | Boolean | `true` | Skip profile fetch when listing already has email+phone+website. Set `false` for max VAT/contacts coverage. |
| `includeProducts` | Boolean | `false` | Attach product cards from profiles (forces detail fetch). |
| `maxItems` | Integer | `50` | Max dataset rows (`0` = unlimited within `maxPages`). |
| `maxPages` | Integer | `3` | Max listing pages per list URL. |
| `concurrency` | Integer | `3` | Parallel detail workers (1–15; keep low if WAF challenges). |
| `proxyConfiguration` | Object | residential | Apify Proxy settings (residential recommended). |

#### Example — German pump manufacturers

```json
{
  "searchKeywords": ["pumpen"],
  "language": "de",
  "country": "deutschland",
  "supplierType": "production",
  "fetchDetails": true,
  "smartEnrich": false,
  "includeProducts": false,
  "maxItems": 100,
  "maxPages": 5,
  "concurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

#### Example — English CNC suppliers + profile URLs

```json
{
  "searchKeywords": ["cnc"],
  "language": "en",
  "startUrls": [
    { "url": "https://www.europages.co.uk/en/company/mustertechnik-gmbh-100001" }
  ],
  "fetchDetails": true,
  "maxItems": 50,
  "maxPages": 2,
  "concurrency": 3
}
```

### Output

Each dataset item is one Europages company. Example fields (fictional sample for illustration):

```json
{
  "recordType": "company",
  "companyId": "100001",
  "uuid": "00000000-0000-4000-8000-000000000001",
  "name": "Mustertechnik GmbH",
  "slug": "mustertechnik-gmbh-100001",
  "language": "de",
  "url": "https://www.europages.de/de/firma/mustertechnik-gmbh-100001",
  "description": "Example industrial supplier description for documentation only.",
  "websiteUrl": "https://www.mustertechnik.example/",
  "email": "info@mustertechnik.example",
  "phoneNumber": "+493012345678",
  "businessTypes": ["production"],
  "mainBusinessArea": "Maschinenbau",
  "keywords": ["CNC", "Zerspanung"],
  "languages": ["de", "en"],
  "city": "Berlin",
  "countryCode": "DE",
  "countryName": "Deutschland",
  "address": {
    "street": "Musterstrasse 1",
    "zipcode": "10115",
    "city": "Berlin",
    "countryCode": "DE",
    "countryName": "Deutschland",
    "latitude": 52.52,
    "longitude": 13.405
  },
  "foundingYear": 1998,
  "employeeCount": "20-49",
  "vatId": "DE000000000",
  "vatAvailable": true,
  "distributionArea": "international",
  "certificates": ["DIN EN ISO 9001:2015", "ISO 9001"],
  "certificatesCount": 2,
  "contactPersons": [
    {
      "firstName": "Erika",
      "lastName": "Mustermann",
      "email": "erika.mustermann@mustertechnik.example",
      "phoneNumber": "+493012345679",
      "executiveType": "executive"
    }
  ],
  "documents": [{ "url": "https://cdn.example.com/catalog.pdf", "title": "Katalog" }],
  "logoUrl": "https://cdn.example.com/logos/mustertechnik.png",
  "listUrl": "https://www.europages.de/unternehmen/deutschland/hersteller%20fabrikant/pumpen.html",
  "enriched": true,
  "scrapedAt": "2026-07-27T14:15:21Z"
}
```

`enriched` is `true` when a company profile page was successfully parsed. With `smartEnrich: true`, listing-only rows that already have email + phone + website stay `enriched: false` but still include those contact fields.

### Workflow

1. Build listing URLs from `searchKeywords`, `categoryUrls`, and/or `startUrls`
2. Paginate Europages listing pages and parse Nuxt `__NUXT_DATA__` company rows
3. Deduplicate by `companyId` / `uuid`
4. Optionally enrich each profile (contacts, VAT, certificates, geo, documents) — or smart-skip
5. Stream rows to the default dataset (PPE event `scraped-company`)

### Tips for better results

- Prefer **residential proxy** for larger crawls; keep `concurrency` at **2–4**
- Use **`smartEnrich: true`** (default) for speed; set **`smartEnrich: false`** when you need VAT / contact persons on every row
- Use **country** + **supplierType** with keywords to narrow manufacturers vs distributors
- Set `fetchDetails: false` for a fast listing-only pass
- Match `language` to the market you care about (descriptions and labels follow the locale)
- Need **DACH-focused** Wer liefert was coverage? Use [WLW Scraper](https://apify.com/crawloop/wlw-scraper)
- Need **register identity** (HRB, EUID, LEI, officers)? Use [North Data Scraper](https://apify.com/crawloop/northdata-scraper)

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/europages-scraper').call({ searchKeywords: ['pumpen'], language: 'de', country: 'deutschland', supplierType: 'production', fetchDetails: true, maxItems: 50 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.slice(0, 5));
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient(token)
run = client.actor("crawloop/europages-scraper").call(
    run_input={"searchKeywords": ["pumpen"], "language": "de", "country": "deutschland", "supplierType": "production", "fetchDetails": True, "maxItems": 50}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("name"), item.get("email"), item.get("city"))
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/crawloop~europages-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchKeywords":["pumpen"],"language":"de","country":"deutschland","supplierType":"production","fetchDetails":true,"maxItems":50}'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp). Connect your Apify account, then call `crawloop/europages-scraper`.

Example prompts:

- "Run Europages Scraper for keyword pumpen in Germany, max 50, return name, email, phoneNumber, city"
- "Find European manufacturers of pumps with VAT and contact persons"
- "Chain Europages then WLW Scraper for DACH-only supplier coverage"
- "Chain Europages then North Data Scraper to add HRB / EUID to supplier leads"

### Suite next step

For DACH-only Wer liefert was coverage, use [WLW Scraper](https://apify.com/crawloop/wlw-scraper). For Dutch Chamber of Commerce identity (KvK number, legal form, address), use [KvK Handelsregister Scraper](https://apify.com/crawloop/kvk-handelsregister-scraper). For EU commercial-register identity (court, number, officers), run [North Data Scraper](https://apify.com/crawloop/northdata-scraper).

### Related Actors

| Actor | Use for |
| :--- | :--- |
| **Europages Scraper** ◄── you are here | Europe-wide B2B directory, multi-locale, VAT & contacts |
| [WLW Scraper](https://apify.com/crawloop/wlw-scraper) | DACH (DE / AT / CH) B2B suppliers from Wer liefert was |
| [KvK Handelsregister Scraper](https://apify.com/crawloop/kvk-handelsregister-scraper) | Dutch Chamber of Commerce public search + KvK lookup |
| [North Data Scraper](https://apify.com/crawloop/northdata-scraper) | EU commercial-register identity, officers, published financials |
| [1688 Scraper](https://apify.com/crawloop/1688-scraper) | China-domestic wholesale offers, MOQ, factory flags |
| [Alibaba Product Scraper](https://apify.com/crawloop/alibaba-product-scraper) | Alibaba.com FOB ladders, MOQ, Gold / Verified |

# Actor input Schema

## `includePhones` (type: `boolean`):

Off by default. Include phone, mobile, WhatsApp, or fax fields already published on public pages only when you have a lawful basis.

## `includeEmails` (type: `boolean`):

Off by default. Include email fields already published on public pages only when you have a lawful basis.

## `searchKeywords` (type: `array`):

Keywords turned into Europages SEO listing URLs (e.g. pumps → /unternehmen/pumps.html or /companies/pumps.html).

## `categoryUrls` (type: `array`):

Direct Europages listing URLs (keyword, country, or supplier-type filtered pages).

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

Company profile URLs and/or extra listing URLs to crawl.

## `language` (type: `string`):

Europages locale used to build keyword search URLs and default host.

## `country` (type: `string`):

Optional country slug for keyword searches (e.g. deutschland, france, italy). Applied to searchKeywords URLs.

## `supplierType` (type: `string`):

Optional business-type filter for keyword searches.

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

When true, open company profiles for full contacts, VAT, certificates, and geo (subject to smartEnrich). When false, output listing-level rows only.

## `smartEnrich` (type: `boolean`):

When true with fetchDetails, skip a profile request if the listing already has email, phone and website (faster, fewer WAF hits). Set false to always open profiles for VAT/contacts/certificates.

## `includeProducts` (type: `boolean`):

Attach product cards from the company profile (name, description, image). Forces a detail fetch even with smartEnrich.

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

Stop after this many dataset records. 0 = unlimited (still bounded by maxPages).

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

Maximum listing pages to crawl per search/category URL.

## `concurrency` (type: `integer`):

Parallel company-detail workers (each uses its own HTTP + proxy session). Prefer 2–4 behind residential proxy.

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

Apify Proxy settings. Residential recommended for larger crawls.

## Actor input object example

```json
{
  "includePhones": false,
  "includeEmails": false,
  "searchKeywords": [
    "pumps"
  ],
  "categoryUrls": [],
  "startUrls": [],
  "language": "de",
  "supplierType": "",
  "fetchDetails": true,
  "smartEnrich": true,
  "includeProducts": false,
  "maxItems": 50,
  "maxPages": 3,
  "concurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Default dataset items (company profiles).

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/europages-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/europages-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 '{}' |
apify call crawloop/europages-scraper --silent --output-dataset

```

## MCP server setup

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