# Sección Amarilla Mexico Business Scraper (`hexadatalabs/seccion-amarilla-business-scraper`) Actor

Scrape Sección Amarilla (seccionamarilla.com.mx), Mexico's yellow pages: business name, category, full address, GPS, phone, WhatsApp, website, hours and payment methods. Search by keyword and city or state. Pay per result.

- **URL**: https://apify.com/hexadatalabs/seccion-amarilla-business-scraper.md
- **Developed by:** [Hexadata](https://apify.com/hexadatalabs) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 1,000 business listing (result)s

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

## Sección Amarilla Mexico Business Scraper

Extract business listings from **Sección Amarilla (seccionamarilla.com.mx)**, Mexico's yellow pages, as clean structured JSON: company name, category, full address split into street, colonia, municipality, state and postal code, GPS coordinates, phone numbers, WhatsApp, website, opening hours, accepted payment methods, product and service tags, branches and the logo image.

Give it one or more categories or keywords and an optional city or state. **Pay per result**: you only pay for the businesses you receive, and `maxResults` caps the cost.

### What you can use it for

- **B2B lead generation**: every hardware store, dental clinic, hotel or workshop in a city, with phone, WhatsApp and website.
- **Local-market research**: how many businesses of a type exist per colonia or municipality, with coordinates for mapping.
- **Data enrichment**: match your customer list against a public directory to fill in addresses, postal codes and phones.
- **Directory and app builders**: seed a vertical directory with structured Mexican business data, including opening hours and payment methods.
- **AI agents**: ask for businesses in natural language through MCP (see below).

### Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `searchQueries` | string\[] | `["restaurantes"]` | Categories or free keywords as written on the site (`restaurantes`, `ferreterias`, `hoteles`, `talleres mecanicos`). Each one is a separate search. Give at least one keyword or one `startUrls` entry. |
| `city` | string | `ciudad de mexico` | City or municipality (`guadalajara`, `monterrey`, `puebla`, `cancun`). Leave empty to search all of Mexico. Big-city results include the metro area. |
| `state` | string | – | Mexican state (`jalisco`, `nuevo leon`, `estado de mexico`). Combine with `city` for state + city results, or use it alone for a whole state. |
| `strictLocation` | boolean | `true` | Skip businesses whose state is not the requested one (the `state` given, or the state of the `city` / metro area). The site pads located searches with businesses from other states; see Limits. Set to `false` to keep every row the site returns. |
| `startUrls` | array | – | Custom results URLs, e.g. `https://www.seccionamarilla.com.mx/resultados/dentistas/guadalajara/1`, or a text file with one URL per line. Not filtered by city / state. |
| `maxResults` | integer | `100` | Total cap across all queries. |
| `scrapeDetails` | boolean | `true` | Open each business page for description, opening hours, payment methods, tags, extra phone lines, branches, image and official website. One extra request per business that has a page. |
| `onlyWithWebsite` | boolean | `false` | Skip listings without a website (lead generation). |
| `includeIndividuals` | boolean | `false` | Keep professionals listed under a personal name (see Legal notice). They are saved with `publisherType: "possible_individual"` and **without** phone, WhatsApp or email. |
| `includeEmail` | boolean | `false` | Add the business email published on the listing (business records only). |
| `proxyConfiguration` | object | Apify proxy | Recommended for runs above a few hundred results. |
| `maxConcurrency` | integer | `3` | Keep it low (2–5); the site is a plain directory shared with real users. |

Example:

```json
{
    "searchQueries": ["ferreterias", "materiales para construccion"],
    "city": "guadalajara",
    "state": "jalisco",
    "maxResults": 300,
    "scrapeDetails": true,
    "onlyWithWebsite": false
}
```

### Output

One dataset item per business. Example, a real record (`openingHours` shortened to three days):

```json
{
    "id": "3078452",
    "name": "HUNAN",
    "category": "Restaurantes-Cocina China",
    "description": "LA MEJOR COMIDA CHINA VISITANOS EN REFORMA Y SAN ANGEL",
    "address": "AV PASEO DE LA REFORMA 2210, LOMAS DE CHAPULTEPEC I SECCION, MIGUEL HIDALGO, DF, CP 11000",
    "street": "AV PASEO DE LA REFORMA 2210",
    "neighborhood": "LOMAS DE CHAPULTEPEC I SECCION",
    "city": "MIGUEL HIDALGO",
    "state": "DF",
    "stateName": "Ciudad de México",
    "postalCode": "11000",
    "country": "MX",
    "latitude": 19.406449,
    "longitude": -99.226327,
    "phone": "5555964355",
    "phones": ["5555964355", "5555965011"],
    "whatsapp": null,
    "email": null,
    "website": "http://www.hunan.com.mx",
    "websiteIsMinisite": false,
    "openingHours": [
        { "day": "monday", "opens": "13:30", "closes": "22:00" },
        { "day": "saturday", "opens": "13:30", "closes": "12:00" },
        { "day": "sunday", "opens": "13:30", "closes": "18:00" }
    ],
    "paymentMethods": ["EFECTIVO"],
    "tags": ["COCINA CHINA", "RESTAURANTES CHINOS", "COCINA", "COMIDA", "RESTAURANTES CHINA"],
    "branches": [
        {
            "name": "HUNAN",
            "address": "PEDRO LUIS DE OGAZON 102 DF 01020, GUADALUPE INN, ALVARO OBREGON, DF",
            "phones": ["5555964355"]
        }
    ],
    "imageUrl": "https://graficos.seccionamarilla.com.mx/contentstore/88/2055988_V1-E36182318.gif",
    "listingTier": "DIA",
    "indexingSource": "IAM",
    "publisherType": "business",
    "url": "https://www.seccionamarilla.com.mx/informacion/hunan/restaurantes/distrito-federal/miguel-hidalgo/lomas-de-chapultepec-i-seccion/3078452",
    "mapUrl": "https://www.seccionamarilla.com.mx/mapas/como-llegar/hunan/restaurantes-cocina-china/df/miguel-hidalgo/3078452",
    "searchQuery": "restaurantes",
    "searchLocation": "ciudad de mexico",
    "scrapedAt": "2026-10-26T23:01:47.430Z"
}
```

| Field | Description |
| --- | --- |
| `id` | Sección Amarilla listing id (stable, use it to deduplicate between runs) |
| `name`, `category`, `description` | Business name and specific category as published; description only from the business page |
| `address`, `street`, `neighborhood`, `city`, `state`, `stateName`, `postalCode`, `country` | Full one-line address and its parts; `state` is the site's code (`DF`, `JAL`, `NL`), `stateName` the full name, `postalCode` the 5-digit CP. `city` and `neighborhood` are copied as published: upper case for directory records, mixed case for partner-feed (`SINERGIA`) records |
| `latitude`, `longitude` | Coordinates as published (`null` for basic listings without a map pin) |
| `phone`, `phones`, `whatsapp` | 10-digit Mexican national numbers (dial with +52); `phones` holds every line published, the business page adds extra lines |
| `email` | Business email, only when `includeEmail` is true and the record is a business |
| `website`, `websiteIsMinisite` | Website without tracking parameters; the business's own domain is preferred over a Sección Amarilla-hosted minisite (`minisitios.seccionamarilla.com.mx`, `*.miadn.mx`), which `websiteIsMinisite` flags |
| `openingHours`, `paymentMethods`, `tags`, `branches`, `imageUrl` | Business-page data: hours per weekday (24h), accepted payments as published (`EFECTIVO`, `VISA`...), product/service tags, other branches, logo or ad image URL |
| `listingTier`, `indexingSource` | Advertiser tier code shown by the site (`DIA`, `ORO`, `PLA`, `SPN`, `PIP`, `TMXGMB`...) and the record origin flag (`IAM`, `SINERGIA` or `null`) |
| `publisherType` | `business`, or `possible_individual` for a professional listed under a personal name (only present when `includeIndividuals` is true) |
| `url`, `mapUrl` | Business page and route/map page on seccionamarilla.com.mx |
| `searchQuery`, `searchLocation`, `scrapedAt` | Provenance |

Fields not published for a business are `null`. With `scrapeDetails: false` only listing fields are filled (name, category, address parts, coordinates, main phone, WhatsApp, website, tier), which takes one request per 20 businesses.

### Pricing & cost examples

**$5.00 per 1,000 businesses** (pay per event, charged only for items saved to the dataset; duplicates and errors are never billed). `maxResults` is a hard cost cap. Examples: 1,000 businesses ≈ $5.00 · a prospect list of 200 restaurants in one city ≈ $1.00 · a weekly run with `maxResults: 100` ≈ $0.50/week. Apify platform usage is included in the price.

### Use it from an AI agent (MCP)

Every Apify Actor is available as a tool through the [Apify MCP server](https://mcp.apify.com). Add it to Claude, Cursor, VS Code or any MCP client and ask, for example:

> "Find hardware stores in Zapopan that have a website and tell me which ones open on Saturdays."

The agent calls this Actor with `{"searchQueries":["ferreterias"],"city":"zapopan","state":"jalisco","onlyWithWebsite":true}` and reasons over `openingHours`.

From code, with the Apify API:

```bash
curl -X POST "https://api.apify.com/v2/acts/hexadatalabs~seccion-amarilla-business-scraper/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["hoteles"],"city":"monterrey","state":"nuevo leon","maxResults":50,"scrapeDetails":false}'
```

```python
from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("hexadatalabs/seccion-amarilla-business-scraper").call(run_input={
    "searchQueries": ["talleres mecanicos"], "city": "puebla", "maxResults": 200,
})
for biz in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(biz["name"], biz["phone"], biz["website"], biz["postalCode"])
```

### Limits and notes

- Results come from the public search pages in the site's own order, 20 per page. The site publishes no total count; the Actor follows the pagination until the last page or `maxResults`.
- The first pages hold paying advertisers with full business pages; deeper pages are mostly **basic listings** (name, category, address, phone, no coordinates, no website). Those are saved from the listing data and cost no detail request. The log reports how many.
- Searches by `city`, and even by `state` + `city`, return the metro area plus some businesses from other states (about 1 in 4 rows in a Monterrey, Nuevo León hotel test, independent hotels included, not only chains). With `strictLocation` (default) those rows are skipped before they count towards `maxResults`; the log reports how many. The requested state is the `state` given, or the state of a known city or metro area (`ciudad de mexico` covers DF and Estado de México); for a small town it is inferred from the first results page. Municipalities inside the metro area are kept (a `guadalajara` search includes Zapopan); filter on `city` in the output if you need one municipality only.
- The same business can appear under two listing ids (for example a legacy record and a newer partner-feed record). The Actor deduplicates by id, not by name.
- Spelling: use the words as written on the site (`ferreterias`, not `ferreterías`; accents are stripped automatically). A misspelled keyword gives zero results, not an error. The site answers an unknown or misspelled **city** with businesses from all over Mexico; the Actor detects that, skips the query with a `LOCATION_NOT_RECOGNISED` warning and fails the run when nothing else was saved, so you are not charged for random results.
- If the site changes its HTML the run fails with a clear `SITE_LAYOUT_CHANGED` error instead of returning empty data. Please report it and it will be fixed quickly.
- Keep `maxConcurrency` low. The Actor uses a session pool and retries transient errors up to 3 times. A business page that still fails is saved from its listing data (the log says how many) so the run reaches `maxResults`.
- Looking for every registered business in Mexico, including those not advertised in Sección Amarilla? The official INEGI **DENUE** directory covers 5+ million establishments; see the *Mexico Business Directory (DENUE)* Actor by the same author.

### Legal notice

This Actor collects **publicly available business directory information**: company names, commercial addresses, business phone numbers and websites, as published by the businesses themselves on seccionamarilla.com.mx. It does not log in, does not bypass access controls and respects the site's `robots.txt`.

Some categories (dentists, doctors, lawyers, accountants, psychologists...) list independent professionals under their personal name. To stay clear of personal data, the Actor applies a heuristic on the business name and **skips records that look like a private individual by default**. Set `includeIndividuals: true` only if you have a legal basis under the Mexican LFPDPPP or the data-protection law that applies to you; those records are then saved without phone, WhatsApp or email. Sole-proprietor shops listed under an owner's name with a commercial category (a hardware store, a bakery) are treated as businesses. Email addresses are off by default (`includeEmail`). You are responsible for complying with Sección Amarilla's terms of use and with the data-protection and anti-spam laws that apply to your use of the data.

### Changelog

- **0.1** (2026-10-27) — First public release.

### Support

Found a problem or need another field? Open an issue in the **Issues** tab of this Actor; we answer within 24 hours and ship confirmed fixes within 48 hours.

***

#### En español

Extrae negocios de Sección Amarilla (seccionamarilla.com.mx) con nombre, categoría, dirección completa separada en calle, colonia, municipio, estado y código postal, coordenadas GPS, teléfonos, WhatsApp, sitio web, horarios, formas de pago, productos y servicios, sucursales e imagen. Indica la categoría o palabra clave y opcionalmente la ciudad o el estado. Se cobra por resultado; usa `maxResults` para limitar el costo. Por defecto omite a los profesionistas registrados con su nombre personal (dentistas, médicos, abogados...) y no incluye correos electrónicos. Funciona también como herramienta para agentes de IA mediante el servidor MCP de Apify.

# Actor input Schema

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

Business categories or free keywords to search for, one per line, as written on seccionamarilla.com.mx (for example "restaurantes", "ferreterias", "hoteles", "talleres mecanicos"). Each one becomes a separate search.

## `city` (type: `string`):

City or municipality, for example "ciudad de mexico", "guadalajara", "monterrey", "puebla", "cancun". Leave empty to search all of Mexico. Results for a big city include its metro area.

## `state` (type: `string`):

Mexican state, for example "jalisco", "nuevo leon", "estado de mexico". Combine with a city (state + city) or use it alone for a whole state. The site also lists some businesses from other states; strictLocation drops them.

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

Full Sección Amarilla results URLs to scrape instead of (or in addition to) the queries above, for example https://www.seccionamarilla.com.mx/resultados/dentistas/guadalajara/1 or https://www.seccionamarilla.com.mx/resultados/ferreterias/jalisco/guadalajara/1. A text file with one URL per line is accepted too. Custom URLs are not filtered by city / state.

## `maxResults` (type: `integer`):

Stop after this many businesses in total (across all queries). You are charged per result, so this caps the cost.

## `scrapeDetails` (type: `boolean`):

Open each business page to get the description, opening hours, payment methods, product/service tags, additional phone lines, branches, the logo/ad image and the official website. One extra request per business. Turn it off for a cheaper, listing-only run (name, category, address, coordinates, phone, WhatsApp, website).

## `strictLocation` (type: `boolean`):

The site pads city and state searches with businesses from other states (about 1 in 4 rows in a Monterrey, Nuevo León hotel test). When enabled, rows whose state is not the requested one (the state given, or the state of the city / metro area) are skipped before they count towards maxResults. Turn it off to keep every row the site returns.

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

Skip listings that do not publish any website (useful for lead generation).

## `includeIndividuals` (type: `boolean`):

Some categories (dentists, doctors, lawyers...) contain professionals listed under their own name. By default those records are skipped. When enabled they are kept with publisherType "possible_individual" and WITHOUT phone, WhatsApp or email. Make sure you have a legal basis before enabling this.

## `includeEmail` (type: `boolean`):

Add the contact email published on the listing (business records only). Off by default; enable only if you need it and comply with the applicable data-protection and anti-spam laws.

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

Proxy to use. Apify proxies are recommended for reliable runs.

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

Maximum parallel requests. Keep it low (2–5) to stay polite with the site.

## Actor input object example

```json
{
  "searchQueries": [
    "restaurantes"
  ],
  "city": "ciudad de mexico",
  "startUrls": [],
  "maxResults": 100,
  "scrapeDetails": true,
  "strictLocation": true,
  "onlyWithWebsite": false,
  "includeIndividuals": false,
  "includeEmail": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 3
}
```

# Actor output Schema

## `results` (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 = {
    "searchQueries": [
        "restaurantes"
    ],
    "city": "ciudad de mexico",
    "state": "",
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("hexadatalabs/seccion-amarilla-business-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": ["restaurantes"],
    "city": "ciudad de mexico",
    "state": "",
    "startUrls": [],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("hexadatalabs/seccion-amarilla-business-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": [
    "restaurantes"
  ],
  "city": "ciudad de mexico",
  "state": "",
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call hexadatalabs/seccion-amarilla-business-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hexadatalabs/seccion-amarilla-business-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/hKT8TK3Ewn4iicun0/builds/2bdKA5A2k9vHwli9w/openapi.json
