# Google Maps Scraper 0.2 Per 1 000 Places (`esdrasdw/google-maps-scraper-0-2-per-1-000-places`) Actor

$0.05 per 1,000 places. Extract businesses from Google Maps with phone, website, address, rating and coordinates.

- **URL**: https://apify.com/esdrasdw/google-maps-scraper-0-2-per-1-000-places.md
- **Developed by:** [Esdrasdw](https://apify.com/esdrasdw) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.20 / 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.

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

**$0.05 per 1,000 places.** Turn any Google Maps search into a clean contact list.

Type what you would type into Maps — `bakery`, `dentist`, `auto repair` — pick a
city, and get back every business it finds with **phone, website, address,
rating and coordinates**, ready for a spreadsheet, a CRM or a cold-call list.

No login, no API key, no browser automation on your side.

### Why people use it

- **Sales prospecting** — every dentist in a city, with phone numbers, in one file.
- **Agency lead lists** — filter for businesses rated below 4.0, or with no
  website, and you have a pitch list.
- **Market research** — how many competitors in a neighborhood, how they rate,
  where they cluster.
- **Store and territory planning** — coordinates for every location, mapped.

### How to use it

1. Put one or more terms in **Search terms**, one per line.
2. Set the **Location** — a city, state or country.
3. Choose **Places to extract** per term.
4. Optionally switch on a filter, so you only pay for rows you can act on.
5. Run it, then export as JSON, CSV, Excel or HTML.

Each search term is run against the location, so three terms and one city give
you three lists in a single run.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `searchStringsArray` | array | `["bakery"]` | What to look for, one per line |
| `locationQuery` | string | `Curitiba, PR, Brazil` | Where to look |
| `maxCrawledPlacesPerSearch` | integer | `100` | Cap per search term |
| `language` | string | `pt-BR` | Language of the results |
| `skipPlacesWithoutPhone` | boolean | `false` | Only businesses with a phone |
| `skipPlacesWithoutWebsite` | boolean | `false` | Only businesses with a website |
| `minimumStars` | string | any | Drop anything rated below this |
| `selected_fields` | array | 9 standard | Which columns to return |

The filters run **before** billing. A row you filter out is a row you do not
pay for.

#### Example input

```json
{
  "searchStringsArray": ["dentist", "orthodontist"],
  "locationQuery": "Miami, FL, United States",
  "maxCrawledPlacesPerSearch": 200,
  "language": "en",
  "skipPlacesWithoutPhone": true,
  "minimumStars": "4.0"
}
```

### Output

```json
{
  "nome": "Padaria Guarani",
  "categoria": "Padaria",
  "endereco": "Rua Chichorro Júnior, 442 - Cabral, Curitiba - PR, 80030-430",
  "cidade": "Curitiba - PR",
  "telefone": "+55 41 3057-0733",
  "site": "https://www.padariaguarani.com.br/",
  "nota": 4.6,
  "avaliacoes": 1271,
  "link_maps": "https://www.google.com/maps/place/?q=place_id:ChIJtwYA7Sjk3JQR4SJ6s6nBEzs"
}
```

#### Every field available

| Field | Description |
|---|---|
| `nome` | Business name |
| `categoria` | Primary category |
| `categorias` | Every category Google lists |
| `endereco` | Full address as one line |
| `rua` | Street and number |
| `bairro` | Neighborhood |
| `cep` | Postal code |
| `cidade` | City and state |
| `estado` | State, spelled out |
| `pais` | Country code |
| `telefone` | Phone, formatted |
| `telefone_digitos` | Phone as digits only, for CRM import |
| `site` | Website |
| `nota` | Average rating |
| `avaliacoes` | Number of reviews |
| `situacao` | Open now, or when it opens next |
| `descricao` | Google's short description of the business |
| `imagem` | Photo URL |
| `latitude` / `longitude` | Coordinates |
| `place_id` | Google place ID |
| `cid` / `kgmid` | Google's other identifiers |
| `fuso_horario` | Time zone |
| `link_maps` | Direct link to the listing |
| `busca` | Which of your search terms found this row |
| `posicao` | Where it ranked in the results |

Fields Google does not publish for a given business are left out of that row
rather than sent as empty text, so a CSV stays readable.

#### Ready-made views

The results tab ships with five layouts, so you rarely need to rearrange
columns yourself:

| View | For |
|---|---|
| **Overview** | Everything in the default set |
| **Lead generation** | Name, phone, website — a call list |
| **Contact info** | Postal address split into columns |
| **Rating** | Sorted by how well reviewed they are |
| **Map data** | Coordinates and identifiers |

### API

Replace `<TOKEN>` with your API token from **Settings → Integrations**.

#### Run and get the results in one call

```bash
curl -X POST "https://api.apify.com/v2/acts/<ACTOR_ID>/run-sync-get-dataset-items?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
        "searchStringsArray": ["bakery"],
        "locationQuery": "Curitiba, PR, Brazil",
        "maxCrawledPlacesPerSearch": 200
      }'
```

Best for small and medium jobs — the connection stays open until the run
finishes, so allow a generous client timeout.

#### Start a run and collect it later

```bash
## 1. start
curl -X POST "https://api.apify.com/v2/acts/<ACTOR_ID>/runs?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchStringsArray": ["dentist"], "locationQuery": "Miami, FL", "maxCrawledPlacesPerSearch": 1000}'

## 2. poll until "status": "SUCCEEDED"
curl "https://api.apify.com/v2/actor-runs/<RUN_ID>?token=<TOKEN>"

## 3. download, in whatever format you need
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&format=csv"
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("<TOKEN>")

run = client.actor("<ACTOR_ID>").call(run_input={
    "searchStringsArray": ["dentist", "orthodontist"],
    "locationQuery": "Miami, FL, United States",
    "maxCrawledPlacesPerSearch": 300,
    "skipPlacesWithoutPhone": True,
})

for place in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(place["nome"], place.get("telefone"), place.get("nota"))
```

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<TOKEN>' });

const run = await client.actor('<ACTOR_ID>').call({
    searchStringsArray: ['coffee shop'],
    locationQuery: 'Lisbon, Portugal',
    maxCrawledPlacesPerSearch: 150,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`${items.length} places`);
```

#### Run summary

Alongside the dataset, each run writes an `OUTPUT` record with a per-search
breakdown:

```json
{
  "ok": true,
  "total_items": 340,
  "searches": [
    { "search": "dentist", "location": "Miami, FL", "count": 200 },
    { "search": "orthodontist", "location": "Miami, FL", "count": 140 }
  ]
}
```

If a search cannot be completed, its entry carries an `erro` field and whatever
was already collected stays in the dataset. A partial result is never reported
as a full one.

### Notes and limits

- **Narrow beats broad.** `pizza in Vila Madalena, São Paulo` returns better
  data than `pizza in Brazil`. Google itself caps how deep any single search
  goes, so several tight searches beat one enormous one.
- Google returns a finite list per search. Asking for more places than exist
  simply returns everything available.
- Duplicates are removed within a run by place ID.
- Coverage measured on real runs: **phone 97%**, **rating and review count
  100%**, **photo 100%**, **website ~80%**.
- `descricao` is Google's own editorial summary. Google writes those mostly for
  restaurants, cafés and hotels — around 75% of a restaurant search has one,
  and a search for dentists or law firms will have almost none. That is
  Google's data, not a gap in the scraper.

### Support

Found a bug, or need a field that is not on the list? Open an issue on the
**Issues** tab with the input you used and the run ID.

### Disclaimer

This is an unofficial tool and is not affiliated with, endorsed by, or
sponsored by Google LLC. It collects only publicly available business
listings. You are responsible for how you use the data, including compliance
with applicable laws, the target site's terms, and privacy rules such as GDPR
and LGPD when the data concerns identifiable people.

# Actor input Schema

## `searchStringsArray` (type: `array`):

What you are looking for. One per line — each term is searched in every location below.

## `locationQuery` (type: `string`):

City, region or country to search in. Example: Curitiba, PR, Brazil

## `maxCrawledPlacesPerSearch` (type: `integer`):

Maximum number of businesses per search term.

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

Language of the results.

## `skipPlacesWithoutPhone` (type: `boolean`):

Skip businesses that do not publish a phone number.

## `skipPlacesWithoutWebsite` (type: `boolean`):

Skip businesses that do not publish a website.

## `minimumStars` (type: `string`):

Skip businesses rated below this.

## `selected_fields` (type: `array`):

Leave as is for the standard set.

## Actor input object example

```json
{
  "searchStringsArray": [
    "bakery"
  ],
  "locationQuery": "Curitiba, PR, Brazil",
  "maxCrawledPlacesPerSearch": 100,
  "language": "pt-BR",
  "skipPlacesWithoutPhone": false,
  "skipPlacesWithoutWebsite": false,
  "minimumStars": "",
  "selected_fields": [
    "nome",
    "categoria",
    "endereco",
    "cidade",
    "telefone",
    "site",
    "nota",
    "avaliacoes",
    "link_maps"
  ]
}
```

# Actor output Schema

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

All places found.

## `summary` (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 = {
    "searchStringsArray": [
        "bakery"
    ],
    "locationQuery": "Curitiba, PR, Brazil",
    "maxCrawledPlacesPerSearch": 100,
    "language": "pt-BR",
    "selected_fields": [
        "nome",
        "categoria",
        "endereco",
        "cidade",
        "telefone",
        "site",
        "nota",
        "avaliacoes",
        "link_maps"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("esdrasdw/google-maps-scraper-0-2-per-1-000-places").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 = {
    "searchStringsArray": ["bakery"],
    "locationQuery": "Curitiba, PR, Brazil",
    "maxCrawledPlacesPerSearch": 100,
    "language": "pt-BR",
    "selected_fields": [
        "nome",
        "categoria",
        "endereco",
        "cidade",
        "telefone",
        "site",
        "nota",
        "avaliacoes",
        "link_maps",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("esdrasdw/google-maps-scraper-0-2-per-1-000-places").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 '{
  "searchStringsArray": [
    "bakery"
  ],
  "locationQuery": "Curitiba, PR, Brazil",
  "maxCrawledPlacesPerSearch": 100,
  "language": "pt-BR",
  "selected_fields": [
    "nome",
    "categoria",
    "endereco",
    "cidade",
    "telefone",
    "site",
    "nota",
    "avaliacoes",
    "link_maps"
  ]
}' |
apify call esdrasdw/google-maps-scraper-0-2-per-1-000-places --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,esdrasdw/google-maps-scraper-0-2-per-1-000-places"
        }
    }
}

```

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/Izsz65lWToNfHwmHI/builds/rynWJobKsHANK2og5/openapi.json
