# Paginasamarillas Scraper (`normdata/paginasamarillas-scraper`) Actor

Search Paginas Amarillas across 8 Latin American countries for B2B leads: phone, WhatsApp, email, website, address and coordinates. Real per-day hours with split shifts, an open-right-now filter, minimum-rating filtering, and full branch and social data other scrapers don't expose.

- **URL**: https://apify.com/normdata/paginasamarillas-scraper.md
- **Developed by:** [Norm Data](https://apify.com/normdata) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $15.00 / 1,000 results

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/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

![Norm Data](https://i.ibb.co/rGbhM5Y8/Chat-GPT-Image-Sep-8-2026-02-20-50-PM.png)

## 🟡 Paginas Amarillas Scraper

Search **Paginas Amarillas** across eight Latin American country sites and get back a clean B2B lead list: phone numbers, WhatsApp, email, website, full address and coordinates, social links, real per-day opening hours, and rating. No login, no account, no browser extension.

Point it at a category or keyword in Argentina, Colombia, Peru, Chile, El Salvador, Guatemala, Panama, or Nicaragua, and get export-ready data for sales prospecting, lead generation, market research, and CRM enrichment.

### 🎯 Who uses it?

#### 📇 Sales & lead-gen teams

Build targeted business lists by category and city, with phone, email, WhatsApp, and website in one export.

#### 📞 Telemarketing & field sales

Filter to businesses that are open right now, checked against their own country's clock, so a call list is never full of closed doors.

#### 📈 Market & territory researchers

Map competitors and suppliers by city and region, with coordinates and every branch a business publishes.

#### 🗂️ CRM and data teams

Match businesses by name, phone, or website and pull social links, hours, and descriptions to enrich existing records.

### ✨ What it does

- **Search:** by category or keyword, across eight country sites, optionally narrowed to one city.
- **Full profile detail:** real per-day opening hours (every shift a business publishes, including a separate lunch and dinner shift on the same day), services, keywords, videos, rating, and the featured review.
- **Contact-quality filters:** keep only businesses with an email, a phone, a website, or a published WhatsApp number.
- **Open-right-now filter:** keep only businesses open at the exact moment the run executes, checked in their own country's timezone.
- **Minimum-rating filter:** keep only businesses at or above a chosen star rating.
- **Premium filter:** keep only paid-advertiser listings, which tend to be more active and carry richer profiles.
- **Paste-a-link shortcut:** give a real results page instead of picking a country and term.

Missing source values are returned as `null`, never invented.

### Why this scraper

- **An open-right-now filter that gets split shifts right.** A restaurant with a lunch shift and a separate dinner shift is correctly marked closed in the gap between them, not open all day just because it opens twice.
- **A rating you can actually filter on.** The published star rating comes straight from its real source field and can be used as a minimum-rating cutoff.
- **Eight country sites, one consistent field set.** Argentina, Colombia, Peru, Chile, El Salvador, Guatemala, Panama, and Nicaragua, all normalized the same way.
- **Contact-quality filters built in.** Every exported row can be a lead you can act on immediately, not a list you still have to clean.
- **Full branch coverage.** Every branch a business publishes comes back with its own address, phones, and map link.

### How it compares

| Capability | This actor | Closest full-featured competitor | Other Paginas Amarillas actors |
|---|:--:|:--:|:--:|
| Countries covered | 8 | 9 | 1 to 3, one actor per country |
| Per-day opening hours with every shift | **yes** | flat hours field | rare |
| **Open-right-now filter** | **yes** | no | no |
| **Minimum-rating filter** | **yes** | no | no |
| Contact-quality filters (email, phone, website, WhatsApp) | yes | yes | rare |
| Multi-branch addresses with per-branch phones | yes | yes | no |
| Search and full profile detail in one run | yes | yes | some split into two actors |

### 📦 What data you get

| Entity | Useful fields |
| --- | --- |
| Business | Name, category, slogan, description, product type, premium flag, logo, gallery images, and the listing and canonical URLs. |
| Contact | Primary and all phone numbers (display and dialable), WhatsApp number and link, email(s), website, and every social link the business publishes. |
| Address & branches | Street, city, region, country, coordinates, map link, and every branch with its own address, phones, and map link. |
| Hours & rating | Per-day opening hours with every shift, an open-right-now flag, the published star rating, and the featured review with its author. |
| Extras | Services, products, keywords, and video links the business lists. |

Every record includes `observedAt` (UTC). Download your dataset from Apify as CSV, JSON, Excel, or XML.

### 💡 Use cases

#### 📇 A WhatsApp-ready outreach list

```json
{ "searchTerm": "abogados", "country": "ar", "location": "buenos aires", "onlyWithWhatsapp": true, "maxBusinesses": 200 }
```

#### 📞 A call list of businesses open right now

```json
{ "searchTerm": "hoteles", "country": "pe", "onlyOpenNow": true, "minRating": "4", "maxBusinesses": 100 }
```

#### 📈 Map every restaurant in a city

```json
{ "searchTerm": "restaurantes", "country": "co", "location": "medellin", "maxBusinesses": 500 }
```

### ⚙️ How the input is organised

**Maximum businesses** sits at the very top, since it applies no matter what you're doing. Below
it, the form is split into three numbered sections:

| Section | What it's for |
| --- | --- |
| **1 · What to search for** | A category or keyword plus a country, or a real results URL pasted in directly. |
| **2 · What to include** | Whether to fetch each listing's full profile detail. |
| **3 · Filters (optional)** | Contact-quality, premium, open-right-now, and minimum-rating filters. Leave them all off to get everything. |

> **Apify Free plan:** every run is limited to a fixed 10-row sample. Upgrade your Apify plan to run your own settings.

### 🛡️ Limits & responsible use

This Actor reads only publicly available Paginas Amarillas listings. It never signs in and never accesses anything gated behind an account.

Business contact details are public directory data, not personal browsing history. Use them in line with Paginas Amarillas' terms and applicable law; prefer B2B outreach and market research over spam.

If a search matches nothing, the run writes a single row with an `error` field instead of failing silently.

### 📧 Contact

Need a scraper for a different site, or found something wrong with this one? norm.data.scrapers@gmail.com

### Local development

```bash
bun install
bun test                # offline: normalization and input parsing, against real fixtures
bun run src/main.ts     # reads storage/key_value_stores/default/INPUT.json
```

# Changelog

This Actor's version history is a separate document: https://apify.com/normdata/paginasamarillas-scraper/changelog.md

# Actor input Schema

## `maxBusinesses` (type: `integer`):

Stop once this many businesses are in the dataset. *(Free plan: always capped at 10.)*

## `searchTerm` (type: `string`):

A business category or keyword, e.g. `restaurantes`, `hoteles`, `abogados`.

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

Which country site to search.

## `location` (type: `string`):

Narrow the search to one city, e.g. `medellin`, `cordoba`. Leave empty to search the whole country.

## `startUrl` (type: `string`):

A real Páginas Amarillas results page, e.g. `https://www.paginasamarillas.com.co/servicios/restaurantes`. When given, the country and search term above are ignored.

## `withDetails` (type: `boolean`):

Also open each listing's own page for opening hours (with every shift), services, keywords, videos, rating and the featured review. Turn off for a faster, list-only run.

## `onlyWithEmail` (type: `boolean`):

Ideal for a cold-email lead list.

## `onlyWithPhone` (type: `boolean`):

Keep only listings that publish at least one phone number.

## `onlyWithWebsite` (type: `boolean`):

Keep only listings that publish a website.

## `onlyWithWhatsapp` (type: `boolean`):

For a WhatsApp outreach list.

## `premiumOnly` (type: `boolean`):

These tend to be more active, higher-intent businesses with richer profiles.

## `onlyOpenNow` (type: `boolean`):

Checked against the business's own country timezone at the moment the run executes. Turns on full profile detail.

## `minRating` (type: `string`):

Keep only businesses rated at or above this. Turns on full profile detail.

## Actor input object example

```json
{
  "maxBusinesses": 10,
  "searchTerm": "restaurantes",
  "country": "co",
  "withDetails": true
}
```

# Actor output Schema

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

One dataset row per business listing.

# 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 = {
    "maxBusinesses": 10,
    "searchTerm": "restaurantes",
    "country": "co",
    "withDetails": true,
    "onlyWithEmail": false,
    "onlyWithPhone": false,
    "onlyWithWebsite": false,
    "onlyWithWhatsapp": false,
    "premiumOnly": false,
    "onlyOpenNow": false,
    "minRating": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("normdata/paginasamarillas-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 = {
    "maxBusinesses": 10,
    "searchTerm": "restaurantes",
    "country": "co",
    "withDetails": True,
    "onlyWithEmail": False,
    "onlyWithPhone": False,
    "onlyWithWebsite": False,
    "onlyWithWhatsapp": False,
    "premiumOnly": False,
    "onlyOpenNow": False,
    "minRating": "",
}

# Run the Actor and wait for it to finish
run = client.actor("normdata/paginasamarillas-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 '{
  "maxBusinesses": 10,
  "searchTerm": "restaurantes",
  "country": "co",
  "withDetails": true,
  "onlyWithEmail": false,
  "onlyWithPhone": false,
  "onlyWithWebsite": false,
  "onlyWithWhatsapp": false,
  "premiumOnly": false,
  "onlyOpenNow": false,
  "minRating": ""
}' |
apify call normdata/paginasamarillas-scraper --silent --output-dataset

```

## MCP server setup

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