# PagineGialle Scraper — Italian Business Leads (`emastra/pagine-gialle-scraper`) Actor

Extract Italian business leads from PagineGialle.it with emails, phone numbers, WhatsApp contacts, websites, locations, ratings, social profiles, flat output, automatic deduplication, and per-query or global result limits.

- **URL**: https://apify.com/emastra/pagine-gialle-scraper.md
- **Developed by:** [Emiliano Mastragostino](https://apify.com/emastra) (community)
- **Categories:** Lead generation, Automation, Developer tools
- **Stats:** 139 total users, 7 monthly users, 97.9% runs succeeded, 2 bookmarks
- **User rating**: 4.32 out of 5 stars

## Pricing

from $7.00 / 1,000 business records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## PagineGialle Scraper — Italian Business Leads Scraper (paginegialle.it) 🇮🇹

> 🇮🇹 **Sviluppato in Italia** per il mercato italiano.\
> 🇬🇧 **Developed in Italy** for the Italian market.

***

#### Quick Navigation / Scorciatoie

- [🇮🇹 Versione Italiana](#versione-italiana)
- [🇬🇧 English Version](#english-version)
- [⚙️ Technical Setup & API Docs (Input/Output)](#technical-documentation-and-api-reference)
- [🛠️ Support & Contacts](#maintenance-and-support)

***

### 🇮🇹 Versione Italiana

Estrai lead aziendali strutturati da [PagineGialle.it](https://www.paginegialle.it), la directory italiana di Pagine Gialle.

Inserisci categorie e località, incolla URL specifici dei risultati di ricerca di paginegialle.it, oppure combina le due modalità. L’Actor restituisce record aziendali pronti per attività di lead generation, con deduplicazione automatica, indicatori sulla qualità dei contatti, tracciamento delle query e limiti globali o per singola ricerca.

Progettato per esecuzioni lunghe e affidabili, può elaborare numerose categorie, località, CAP e URL di ricerca diretti in una sola esecuzione, mantenendo pulito il dataset finale. Quando la deduplicazione è attiva, vengono addebitati solo i record aziendali unici effettivamente salvati nel dataset.

L’Actor è pensato come generatore di dataset di lead aziendali italiani, non come scraper generico. Ogni riga salvata è quindi strutturata per facilitare analisi, filtri e workflow successivi.

#### Perché usare questo scraper di Pagine Gialle?

Usa l’Actor per:

- Creare liste di lead B2B italiani.
- Raccogliere indirizzi email, numeri di telefono, contatti WhatsApp, siti web e profili social disponibili pubblicamente.
- Analizzare mercati locali, concorrenti e fornitori di servizi.
- Esportare dati aziendali in CSV, Excel, Google Sheets, CRM o workflow Apify.
- Eseguire estrazioni di grandi dimensioni basate su più ricerche, senza che i record duplicati incidano sui limiti o sul budget di fatturazione.

#### Funzionalità principali

- **Input semplice e combinabile** — inserisci categorie e località, URL diretti dei risultati di ricerca di PagineGialle oppure entrambi. L’Actor prepara automaticamente gli URL di partenza.
- **Adatto a esecuzioni lunghe** — combina numerose categorie, località, CAP e URL in un’unica esecuzione, con limiti per query, limiti globali, deduplicazione e riepiloghi finali.
- **Deduplicazione automatica** — attiva per impostazione predefinita in ogni esecuzione e basata sugli identificatori univoci dei profili aziendali di PagineGialle.
- **Fatturazione successiva alla deduplicazione** — quando la deduplicazione è attiva, i duplicati ignorati non vengono salvati nel dataset e non vengono addebitati come risultati.
- **Output semplice e pronto all’uso** — un record aziendale per ogni riga del dataset, ideale per CSV, Excel, Google Sheets e importazioni nei CRM.
- **Indicatori sulla qualità dei contatti** — filtra rapidamente i record in base alla presenza di email, telefono, cellulare, WhatsApp, sito web, profili social o alla possibilità complessiva di contattare l’azienda.
- **Limiti flessibili sui risultati** — controlla il numero massimo di aziende salvate nell’intera esecuzione o per ciascuna query.
- **Estrazione affidabile** — paginazione automatica, rotazione dei proxy e mitigazione dei blocchi.

#### Come estrarre dati da PagineGialle

1. Inserisci una o più categorie aziendali e località, incolla gli URL dei risultati di ricerca di PagineGialle oppure combina le due opzioni.
2. Configura facoltativamente `maxItems`, `maxItemsPerQuery` e `deduplicateResults` nella [sezione tecnica](#technical-docs).
3. Avvia l’Actor dalla Console Apify o tramite API.
4. Scarica i lead aziendali ottenuti in JSON, CSV, Excel, XML o in un altro formato supportato dal dataset.

***

### 🇬🇧 English Version

Extract structured business leads from [PagineGialle.it](https://www.paginegialle.it), Italy’s Yellow Pages directory.

Enter categories and locations, paste specific paginegialle.it search-result URLs, or combine both input methods. The Actor returns lead-ready business records with automatic deduplication, contactability flags, query-source metadata, and global or per-query result limits.

Designed for reliable long-running jobs, it can process many categories, locations, Italian postal codes (CAPs), and direct search URLs in a single run while keeping the final dataset clean. When deduplication is enabled, only unique business records successfully saved to the dataset are billed.

The Actor is designed as a dataset builder for Italian business leads rather than as a generic scraper. Each saved row is therefore structured for analysis, filtering, and downstream workflows.

#### Why use this Pagine Gialle scraper?

Use the Actor to:

- Build Italian B2B lead lists.
- Collect publicly listed email addresses, phone numbers, WhatsApp contacts, websites, and social profiles.
- Research local markets, competitors, and service providers.
- Export business data to CSV, Excel, Google Sheets, CRMs, or Apify workflows.
- Run large multi-query extractions without duplicate records counting toward your limits or billing budget.

#### Key features

- **Simple, combinable input** — provide categories and locations, direct PagineGialle search URLs, or both. No mode selection is required.
- **Designed for long runs** — combine many categories, locations, postcodes, and URLs in a single run, with per-query limits, global limits, deduplication, and run summaries.
- **Automatic deduplication** — enabled by default within each run and based on reliable PagineGialle profile identifiers.
- **Billing after deduplication** — when deduplication is enabled, skipped duplicates are not saved to the dataset and are not billed as results.
- **Lead-ready output** — each dataset row contains one business record, suitable for CSV, Excel, Google Sheets, and CRM imports.
- **Contactability flags** — quickly filter records by the presence of email, phone, mobile phone, WhatsApp, website, social profiles, or overall contactability.
- **Flexible result limits** — control the maximum number of businesses saved across the entire run or for each individual query.
- **Reliable extraction** — automatic pagination, proxy rotation, and blocking mitigation.

#### How to scrape PagineGialle

1. Enter one or more business categories and locations, paste direct PagineGialle search-result URLs, or combine both options.
2. Optionally configure `maxItems`, `maxItemsPerQuery`, and `deduplicateResults` in the [technical setup](#technical-docs).
3. Run the Actor from Apify Console or through the API.
4. Download the resulting business leads in JSON, CSV, Excel, XML, or another dataset-supported format.

***

### ⚙️ Technical Documentation & API Reference

#### Input Configuration

| Field                | Type    | Description                                                                                                                                                                                |
| :------------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `categories`         | array   | Business categories in Italian, such as `"dentisti"`, `"avvocati"` or `"ristoranti"`. Must be used together with `locations`, unless `searchUrls` is provided.                             |
| `locations`          | array   | Locations expressed as city names, province codes, or CAPs/postcodes, for example `"Roma"`, `"MI"` or `"00121"`. Must be used together with `categories`, unless `searchUrls` is provided. |
| `searchUrls`         | array   | PagineGialle search-result URLs. Can be used on their own or together with `categories` and `locations`.                                                                                   |
| `maxItems`           | integer | Maximum number of businesses saved across the entire run. Use `0` for no global limit. Default: `0`.                                                                                       |
| `maxItemsPerQuery`   | integer | Maximum number of businesses saved for each category/location pair or direct search URL. Use `0` for no per-query limit. Default: `0`.                                                     |
| `deduplicateResults` | boolean | Removes duplicate PagineGialle profiles within the current run. Default: `true`.                                                                                                           |

Valid input patterns are:

- `categories` + `locations`
- `searchUrls`
- `categories` + `locations` + `searchUrls`

Each category is combined with each location. For example, two categories and three locations generate six separate searches. Overlapping results are deduplicated by default. For `searchUrls`, use search-result URLs copied from your browser.

##### Input Examples

```json
{
    "searchUrls": ["https://www.paginegialle.it/ricerca/avvocati/milano"]
}
```

```json
{
    "categories": ["dentisti"],
    "locations": ["Roma", "00121"]
}
```

```json
{
    "categories": ["dentisti", "commercialisti"],
    "locations": ["Roma", "FI", "00121"],
    "searchUrls": ["https://www.paginegialle.it/ricerca/avvocati/milano"],
    "maxItems": 700,
    "maxItemsPerQuery": 100,
    "deduplicateResults": true
}
```

***

#### Extracted Data Fields

| Data Group             | Example Fields                                                                                              |
| ---------------------- | ----------------------------------------------------------------------------------------------------------- |
| **Business details**   | `company_name`, `business_category`, `description`                                                          |
| **Contact data**       | `email`, `emails` (array), `phone`, `phones` (array), `secondary_phone`, `whatsapp`, `whatsapps`            |
| **Online presence**    | `website`, `website_domain`, `facebook_url`, `instagram_url`, `tiktok_url`, `logo_url`                      |
| **Location**           | `address`, `postcode` (CAP), `city`, `province`, `region`, `country`, `latitude`, `longitude`               |
| **Ratings**            | `rating_average`, `rating_count`                                                                            |
| **Lead-quality flags** | `has_email`, `has_phone`, `has_mobile_phone`, `has_whatsapp`, `has_website`, `has_social`, `is_contactable` |
| **Query attribution**  | `query_category`, `query_location`, `query_input_type`, `query_strategy`, `query_id`, `query_search_url`    |
| **Source metadata**    | `profile_url`, `profile_id`, `source`, `search_url`, `source_page_number`, `scraped_at`                     |

*Note: Scalar fields may be `null` when PagineGialle does not provide a value. Collection fields are returned as arrays and may be empty.*

- `has_mobile_phone` uses a conservative heuristic for identifying Italian mobile numbers and may return `false` when a number cannot be identified with sufficient confidence.
- `is_contactable` is `true` when the business has at least one email address, phone number, WhatsApp number, or website. A social profile alone does not set this flag.

##### Output Example (JSON)

```json
{
    "company_name": "Monti Studio",
    "business_category": "Studi commercialisti",
    "description": "Lo STUDIO MONTI fornisce ai propri clienti servizi professionali in materia fiscale e del lavoro.",
    "website": "[https://www.montistudio.eu](https://www.montistudio.eu)",
    "website_domain": "montistudio.eu",
    "email": "info@montistudio.it",
    "emails": ["info@montistudio.it"],
    "phone": "06 5812270",
    "phones": ["06 5812270", "333 7430257"],
    "secondary_phone": "333 7430257",
    "whatsapp": "333 7430257",
    "whatsapps": ["333 7430257"],
    "address": "Via Costanza Baudana Vaccolini, 5",
    "postcode": "00153",
    "city": "Roma",
    "province": "RM",
    "region": "Lazio",
    "country": "Italy",
    "latitude": 41.87813,
    "longitude": 12.46669,
    "rating_average": 5,
    "rating_count": 3,
    "profile_url": "[https://www.paginegialle.it/montistudioroma](https://www.paginegialle.it/montistudioroma)",
    "profile_id": "0ec6b49e-c36e-41f4-9221-79797f606906",
    "logo_url": "[https://img.italiaonline.it/0WO5p000003g9yRGAQ/IOL4YOU_LOGO_1647186095662.gif](https://img.italiaonline.it/0WO5p000003g9yRGAQ/IOL4YOU_LOGO_1647186095662.gif)",
    "facebook_url": "[https://www.facebook.com/montistudio.roma/](https://www.facebook.com/montistudio.roma/)",
    "instagram_url": null,
    "tiktok_url": null,
    "has_email": true,
    "has_phone": true,
    "has_mobile_phone": true,
    "has_whatsapp": true,
    "has_website": true,
    "has_social": true,
    "is_contactable": true,
    "contact_channels": ["email", "phone", "whatsapp", "website"],
    "query_category": "commercialisti",
    "query_location": "Roma",
    "query_input_type": "category_location",
    "query_strategy": "category_location",
    "query_id": "category_location:commercialisti:roma",
    "query_search_url": "[https://www.paginegialle.it/ricerca/commercialisti/Roma](https://www.paginegialle.it/ricerca/commercialisti/Roma)",
    "source": "paginegialle.it",
    "search_url": "[https://www.paginegialle.it/ricerca/commercialisti/Roma](https://www.paginegialle.it/ricerca/commercialisti/Roma)",
    "source_page_number": 1,
    "scraped_at": "2026-07-02T10:00:00.000Z"
}
```

***

#### Deduplication, Limits, and Billing

Deduplication is enabled by default and applies within a single run. The Actor identifies duplicates using reliable PagineGialle profile identifiers: `profile_id` and normalized `profile_url`.

The first matching record is saved. Any matching records found later are skipped rather than merged. The Actor does not deduplicate records by company name, phone number, address, email, or website domain. Records without a reliable profile identifier cannot be safely deduplicated and are therefore treated as unique.

When deduplication is enabled, skipped duplicates:

- are not saved to the dataset;
- are not billed as saved results;
- do not count toward `maxItems`;
- do not count toward `maxItemsPerQuery`.

Billing therefore applies only to final business records that remain after deduplication and limit checks and are successfully saved to the dataset.

- `maxItems` controls the total number of businesses saved across the entire run.
- `maxItemsPerQuery` applies separately to each category/location pair and each direct search URL. It is useful for distributing coverage more evenly across multiple searches.
- Deduplication does not persist across separate Actor runs. If `deduplicateResults` is disabled, duplicate records may be saved, counted toward limits, and billed normally.

##### 🇮🇹 Limiti per gli utenti del piano gratuito Apify

Per gli utenti con un piano Apify gratuito, questo Actor restituisce al massimo **100 risultati per esecuzione** e **200 risultati al giorno**. Il conteggio giornaliero si azzera a mezzanotte UTC e considera solo i record unici salvati.

Quando il limite viene raggiunto, l’esecuzione si conclude regolarmente con i risultati già raccolti e lo spiega nel messaggio di stato. Con un piano Apify a pagamento non si applica alcun limite: valgono solo i tuoi `maxItems` e `maxItemsPerQuery`.

##### 🇬🇧 Limits for Apify free-plan users

For users on a free Apify plan, this Actor returns at most **100 results per run** and **200 results per day**. The daily counter resets at midnight UTC and counts only final unique saved records.

When a limit is reached, the run finishes normally with the results collected so far and explains the limit in its status message. On a paid Apify plan no such cap applies — only your own `maxItems` and `maxItemsPerQuery` do.

***

#### Run Summary and Deduplication State

The default dataset contains business records only. Run metadata is stored separately in the default key-value store:

- `RUN_SUMMARY` — query counts, saved records, duplicates removed, contact coverage, limits, and failure statistics.
- `DEDUPE_STATE` — a snapshot of the deduplication state for the current run.

These records are not added to the dataset, do not appear as business leads, and are not billed as dataset results. `DEDUPE_STATE` is useful for monitoring long-running jobs.

***

#### Tips for Better Coverage

- Use multiple CAPs (italian postcodes) to cover a large city more precisely.
- Paste specific filtered PagineGialle search URLs when you need full control over the original search.
- Combine generated category/location searches with direct URLs in the same run.
- Use `maxItemsPerQuery` to distribute results more evenly across multiple searches.
- Use `maxItems` to control the total number of saved records and your overall budget.
- Keep `deduplicateResults` enabled for large runs involving overlapping locations or multiple geographic areas.

A broad PagineGialle search may return only a limited number of results. Using multiple postcodes or specific filtered search URLs can increase coverage. When searches overlap, deduplication prevents the same PagineGialle profiles from being saved and billed more than once within the same run.

***

### 🛠️ Maintenance and Support

This Actor is actively maintained.

- 📬 [Contact the developer](https://apify.com/emastra)
- 🐞 [Report a bug or issue](https://console.apify.com/actors/T5n7hWZSyuPw3soJo/issues)
- ✨ [Request a feature or custom scraper](https://apify.com/emastra)

# Actor input Schema

## `categories` (type: `array`):

Business categories to search for, in Italian. Examples: dentisti, commercialisti, ristoranti.

## `locations` (type: `array`):

Locations to search on PagineGialle. You can enter city names, province codes, or CAP/postcodes. Examples: Roma, Milano, MI, 00121.

## `searchUrls` (type: `array`):

Optional. Paste direct PagineGialle search result URLs for full control. If you also provide categories and locations, the actor will scrape both and remove duplicates.

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

Maximum number of unique businesses to save across the whole run. Use 0 for no limit.

## `maxItemsPerQuery` (type: `integer`):

Maximum number of unique businesses to save for each category/location combination or direct search URL. Use 0 for no per-query limit.

## `deduplicateResults` (type: `boolean`):

Recommended. Remove duplicate businesses found across overlapping locations, CAPs, province searches, or search URLs.

## Actor input object example

```json
{
  "categories": [
    "dentisti"
  ],
  "locations": [
    "Roma",
    "FI",
    "00122"
  ],
  "searchUrls": [
    "https://www.paginegialle.it/ricerca/avvocati/milano"
  ],
  "maxItems": 0,
  "maxItemsPerQuery": 0,
  "deduplicateResults": true
}
```

# Actor output Schema

## `businesses` (type: `string`):

The scraped business records: name, category, contacts (email, phone, WhatsApp, website, social), location, ratings, lead flags, and query attribution. One item per unique business.

## `runSummary` (type: `string`):

Run-level statistics: per-query breakdown, record counts, duplicate rate, contact coverage, and which limits were reached.

## `dedupeState` (type: `string`):

Snapshot of the deduplication keys (profile IDs and normalized profile URLs) seen during the run, plus dedupe statistics.

# 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 = {
    "categories": [
        "dentisti"
    ],
    "locations": [
        "Roma",
        "FI",
        "00122"
    ],
    "searchUrls": [
        "https://www.paginegialle.it/ricerca/avvocati/milano"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("emastra/pagine-gialle-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 = {
    "categories": ["dentisti"],
    "locations": [
        "Roma",
        "FI",
        "00122",
    ],
    "searchUrls": ["https://www.paginegialle.it/ricerca/avvocati/milano"],
}

# Run the Actor and wait for it to finish
run = client.actor("emastra/pagine-gialle-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "categories": [
    "dentisti"
  ],
  "locations": [
    "Roma",
    "FI",
    "00122"
  ],
  "searchUrls": [
    "https://www.paginegialle.it/ricerca/avvocati/milano"
  ]
}' |
apify call emastra/pagine-gialle-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=emastra/pagine-gialle-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/T5n7hWZSyuPw3soJo/builds/P2C4Q8tvfx1PeeAUj/openapi.json
