# Google Maps Scraper (Places, Phones, Websites, Ratings) (`juliob.rangel/google-maps-places-scraper-fast`) Actor

Search Google Maps for any business type and location and get every place in one table: name, category, rating, review count, phone, website, full address, city, postal code, coordinates, opening status and place ID. Fast, no browser. Export to Excel, CSV or JSON.

- **URL**: https://apify.com/juliob.rangel/google-maps-places-scraper-fast.md
- **Developed by:** [Julio Barcellos Rangel](https://apify.com/juliob.rangel) (community)
- **Categories:** Lead generation, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 place scrapeds

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

## Google Maps Scraper (Places, Phones, Websites, Ratings)

This Google Maps scraper searches Google Maps for any business type and location and returns every place in one table: name, category, rating, review count, phone, website, full address, city, postal code, coordinates, opening status and place ID. It is made for lead generation, local SEO, market research and sales teams. Use it to extract Google Maps data to Excel or CSV, or as a Google Maps business list extractor for any city, with no browser and no login.

### What does Google Maps Scraper do?

The robot runs the same list search that Google Maps runs when you type a query, reads the results 20 places at a time, and turns each place into one row. It does not open a browser.

You tell it what to look for with:

- **Search terms**, written the way you would type them in Google Maps: `dentist`, `coffee shop`, `real estate agency` or `plumber in Miami`.
- **Location**, a city, region or neighborhood added to every search term. With the term `dentist` and the location `Austin, TX`, the robot searches for `dentist in Austin, TX`. When the language starts with `pt`, it uses the Portuguese word instead: `academia em Florianópolis`. Leave the location empty if your terms already include the place.
- **Language and country**, which Google uses for the search and for the text of categories and opening status, for example `en` and `us`, or `pt-BR` and `br`.

For each search the robot keeps reading result pages until it reaches your **Max places per search** or Google has no more places. By default, a place found by more than one search term is returned only once.

What comes out is a table with one row per place: name and categories, rating and number of reviews, local and international phone, website, the full address plus street, neighborhood, city, state, postal code and country code, latitude and longitude, the opening status at the time of the run, a short description when Google has one, time zone, place ID, CID, a Google Maps link and a thumbnail image.

### What data can you extract?

| Field | What it means | Example |
|---|---|---|
| `searchTerm` | Full query sent to Google Maps (term plus location) | `dentist in Austin, TX` |
| `position` | Rank of the place in the results for that query, starting at 1 | `1` |
| `name` | Business name | `Emergency Dentist of Austin` |
| `category` | Main category | `Dentist` |
| `categories` | All categories shown on Google Maps | `["Dentist", "Cosmetic dentist", "Dental clinic"]` |
| `rating` | Average star rating | `4.8` |
| `reviewsCount` | Number of reviews | `90` |
| `phone` | Phone in local format | `(512) 961-6200` |
| `phoneInternational` | Phone in international format | `+1 512-961-6200` |
| `website` | Business website | `https://emergencydentistofaustin.com/` |
| `address` | Full address | `1030 Norwood Park Blvd #324, Austin, TX 78753` |
| `street` | Street and number | `1030 Norwood Park Blvd #324` |
| `neighborhood` | Neighborhood | `Heritage Hills` |
| `city` | City | `Austin` |
| `state` | State or region | `Texas` |
| `postalCode` | Postal or ZIP code | `78753` |
| `countryCode` | Two-letter country code | `US` |
| `latitude` | Latitude | `30.3406789` |
| `longitude` | Longitude | `-97.6924276` |
| `openingStatus` | Open or closed at the time of the run, in the search language | `Open · Closes 8 PM` |
| `description` | Short Google description, when there is one | `Thin-crust slices & pies for dining in or carry out…` |
| `timezone` | Time zone of the place | `America/Chicago` |
| `placeId` | Google place ID | `ChIJpXb4FgrJRIYRyRpdhSsCHHk` |
| `cid` | Google CID (customer ID) of the place | `13243667843430391418` |
| `googleMapsUrl` | Link that opens the place on Google Maps | `https://www.google.com/maps/place/?q=place_id:ChIJpXb4FgrJRIYRyRpdhSsCHHk` |
| `thumbnail` | URL of the place's main photo, small size | `https://lh3.googleusercontent.com/…` |
| `scrapedAt` | When the row was collected (UTC) | `2026-10-10T20:16:13.830Z` |
| `error` | Only on error rows: what went wrong | `No places found` |

Any field that Google does not show for a place (for example `website`, `phone` or `description`) comes back as `null`.

### How to use Google Maps Scraper

1. Open the robot in Apify Console and go to the **Input** tab.
2. Add one or more **Search terms**, one per line, for example `dentist`, `pizza` or `gym`.
3. Type a **Location** such as `Austin, TX`, `Lisbon` or `Curitiba`, or leave it empty if each term already says where.
4. Set **Max places per search**. Google Maps shows about 120 places per search.
5. Set **Language** and **Country**, for example `pt-BR` and `br` for Brazil.
6. Click **Start** and wait for the run to finish.
7. Open the **Output** tab to see the Places table, then export the data as JSON, CSV, Excel or HTML.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `searchTerms` | array of strings (required) | `["dentist"]` | What you would type in Google Maps. One search per entry; repeated terms are removed. |
| `location` | string | empty (the form shows `Austin, TX` as an example) | City, region or neighborhood added to every search term. Leave it empty if the place is already in the terms. |
| `maxPlacesPerSearch` | integer | `40` | Places per search, from 1 to 500. Google shows about 120 per search. |
| `language` | string | `en` | Language of the search, categories and opening status, e.g. `en`, `pt-BR`, `es`, `de`, `fr`. |
| `country` | string | `us` | Two-letter country code Google uses for the search, e.g. `us`, `br`, `gb`, `de`. |
| `skipDuplicates` | boolean | `true` | Return each place only once across all search terms. |
| `proxy` | object | `{"useApifyProxy": true}` | Apify Proxy settings. The default works for most runs. |

Example input:

```json
{
  "searchTerms": ["dentist", "orthodontist"],
  "location": "Austin, TX",
  "maxPlacesPerSearch": 100,
  "language": "en",
  "country": "us",
  "skipDuplicates": true,
  "proxy": { "useApifyProxy": true }
}
```

Example for Brazil, in Portuguese:

```json
{
  "searchTerms": ["academia", "pet shop"],
  "location": "Florianópolis",
  "maxPlacesPerSearch": 25,
  "language": "pt-BR",
  "country": "br"
}
```

### Output example

One real row from the latest run (search `academia` in `Florianópolis`, language `pt-BR`). The thumbnail URL is shortened.

```json
{
  "searchTerm": "academia em Florianópolis",
  "position": 1,
  "name": "Academia Pratique Fitness - Centro de Florianópolis",
  "category": "Academia",
  "categories": ["Academia"],
  "rating": 4.8,
  "reviewsCount": 91,
  "phone": "(31) 4141-1962",
  "phoneInternational": "+55 31 4141-1962",
  "website": "https://pratiquefitness.com.br/unidade/centro-de-florianopolis",
  "address": "R. Francisco Tolentino, 800 - Centro, Florianópolis - SC, 88010-200",
  "street": "R. Francisco Tolentino, 800",
  "neighborhood": "Centro",
  "city": "Florianópolis",
  "state": "Santa Catarina",
  "postalCode": "88010-200",
  "countryCode": "BR",
  "latitude": -27.5947519,
  "longitude": -48.5573804,
  "openingStatus": "Fechado · Abre seg. às 05:30",
  "description": null,
  "timezone": "America/Sao_Paulo",
  "placeId": "ChIJqcbCUCU5J5URR93Cn3xdjJc",
  "cid": "4413557123424838688",
  "googleMapsUrl": "https://www.google.com/maps/place/?q=place_id:ChIJqcbCUCU5J5URR93Cn3xdjJc",
  "thumbnail": "https://lh3.googleusercontent.com/grass-cs/AABkmLf9ChxSOC6G8RFJx05_…=w114-h86-k-no",
  "scrapedAt": "2026-10-10T20:16:18.878Z"
}
```

When a search returns nothing, you get an error row such as `{"searchTerm": "dentist in Austin, TX", "error": "No places found"}`.

### How much does it cost?

The robot uses **pay per event** pricing: you pay **$2.00 per 1,000 places** ($0.002 per place returned) on the Free plan. Platform usage is included in the price, so there is no separate charge for compute or proxy.

| Apify plan | Price per 1,000 places |
|---|---|
| Free | $2.00 |
| Bronze (10% off) | $1.80 |
| Silver (20% off) | $1.60 |
| Gold and higher (30% off) | $1.40 |

Worked examples on the Free plan:

- One search with the default 40 places: **$0.08**.
- One business type in 20 neighborhoods, about 120 places each: about 2,400 places = about **$4.80**, less if duplicates are skipped.
- 10,000 places: **$20.00** (or $14.00 on Gold).

What is **not** charged: error rows (`No places found` and `Google Maps did not respond, try again later`) and places skipped as duplicates.

### Use cases

- **B2B lead lists:** collect local businesses with phone and website for cold calling or outreach.
- **Local SEO and competitor research:** compare ratings and review counts of businesses in an area.
- **Market sizing:** count how many gyms, clinics or restaurants exist in each city or neighborhood.
- **Directories and store locators:** build listings with addresses, coordinates and Google Maps links.
- **Sales territory planning:** plot places on a map with `latitude` and `longitude`.
- **CRM updates:** schedule the same searches every month to catch new businesses and changed phone numbers or websites.
- **Expansion research:** see where competitors are present before opening a new location.

### Tips and limits

- **About 120 places per search.** This is how many places Google Maps shows for one query. For a whole city, run one search per neighborhood or ZIP code; with `skipDuplicates` on, places found twice are returned once.
- **Up to 500 per search.** The robot reads result pages of 20 places, up to 500 per search, and stops early when Google returns a page with fewer than 20 places.
- **Location is optional.** From the API, `location` stays empty unless you send it, so a term like `plumber in Miami` is searched exactly as typed. In the Console form it comes pre-filled with `Austin, TX` as an example; clear it if your terms already say where.
- **Joining word.** Term and location are joined with `in` (or `em` for Portuguese). For other languages you may prefer to write the whole query in each search term and leave the location empty.
- **No emails, no reviews.** The robot returns the rating and the number of reviews, not review texts, and it does not visit websites. For emails, use the Google Maps Email Extractor.
- **Opening status is a snapshot.** `openingStatus` is the text Google shows at the time of the run, not the full weekly schedule.
- **Retries:** each result page is tried up to 4 times with fresh proxy connections. If Google does not answer the first page of a search, you get the error row `Google Maps did not respond, try again later`.

### Use it from the API, Python or JavaScript

JavaScript (Node.js) with the official `apify-client` package:

```javascript
const { ApifyClient } = require('apify-client');

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const input = { searchTerms: ['coffee shop'], location: 'Lisbon', maxPlacesPerSearch: 60, language: 'en', country: 'pt' };
const run = await client.actor('juliob.rangel/google-maps-places-scraper-fast').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Python with the official `apify-client` package:

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_TOKEN')
input = {'searchTerms': ['plumber in Miami'], 'location': '', 'maxPlacesPerSearch': 120}
run = client.actor('juliob.rangel/google-maps-places-scraper-fast').call(run_input=input)
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

You can also connect the robot to Make, Zapier or n8n, export results to Google Sheets, send them to a webhook when a run finishes, or let AI agents call it through the Apify MCP server.

### FAQ

**Do I need a Google account, cookies or a Google Maps API key?**
No. The robot reads public Google Maps search results. You only need an Apify account.

**Can I export the places to Excel or CSV?**
Yes. Download the dataset as JSON, CSV, Excel or HTML from the Output tab, or read it through the API.

**How many places can I get?**
About 120 per search, because that is what Google Maps shows. Add more search terms or split the area into neighborhoods or ZIP codes to get more.

**Does it get emails?**
No. It returns the website of each place. The Google Maps Email Extractor visits those websites and adds emails and social profiles.

**Does it scrape reviews?**
No. You get `rating` and `reviewsCount`, but not the text of reviews.

**Why did I get an error row?**
`No places found` means Google returned nothing for that query. `Google Maps did not respond, try again later` means the first result page could not be loaded after several tries. Error rows are free.

**Is scraping Google Maps legal?**
The robot only collects publicly available business data. You are responsible for complying with Google's terms and with privacy laws such as GDPR and LGPD. Some places are run by individuals (for example a freelancer listed under their own name), and personal data needs a legitimate reason to be processed.

### Related scrapers

- [Google Maps Email Extractor (Leads with Emails & Socials)](https://apify.com/juliob.rangel/google-maps-email-extractor) for the same places plus emails and social profiles from their websites.
- [Website Contact Details Scraper (Emails, Phones, Socials)](https://apify.com/juliob.rangel/website-contact-details-scraper) to enrich the `website` column of an export you already have.
- [LinkedIn Company Scraper (No Login, Fast)](https://apify.com/juliob.rangel/linkedin-company-fast) to add company details from LinkedIn.
- [Instagram Profile Stats Scraper (Followers, Bio, Posts)](https://apify.com/juliob.rangel/instagram-profile-stats) to check the Instagram accounts of local businesses.

***

## Extrator do Google Maps (PT-BR)

Pesquise qualquer tipo de negócio em qualquer cidade e receba todos os lugares em uma tabela: nome, categoria, nota, número de avaliações, telefone, site, endereço completo (rua, bairro, cidade, estado, CEP), coordenadas, status de funcionamento e ID do Google. Use idioma `pt-BR` e país `br`. Você paga só por lugar retornado.

# Actor input Schema

## `searchTerms` (type: `array`):

What you would type in Google Maps, e.g. "dentist", "coffee shop", "plumber in Miami". One search per line.

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

City, region or neighborhood added to every search term, e.g. "Austin, TX" or "Curitiba". Leave empty if the location is already in the search terms.

## `maxPlacesPerSearch` (type: `integer`):

Google Maps shows up to about 120 places per search. For more, split by neighborhood or zip code.

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

Language of categories and opening hours, e.g. en, pt-BR, es, de, fr.

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

Two-letter country code that Google uses for the search, e.g. us, br, gb, de.

## `skipDuplicates` (type: `boolean`):

Return each place only once across all search terms.

## `proxy` (type: `object`):

Apify Proxy settings.

## Actor input object example

```json
{
  "searchTerms": [
    "dentist"
  ],
  "location": "Austin, TX",
  "maxPlacesPerSearch": 40,
  "language": "en",
  "country": "us",
  "skipDuplicates": true,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "searchTerms": [
        "dentist"
    ],
    "location": "Austin, TX",
    "maxPlacesPerSearch": 40
};

// Run the Actor and wait for it to finish
const run = await client.actor("juliob.rangel/google-maps-places-scraper-fast").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 = {
    "searchTerms": ["dentist"],
    "location": "Austin, TX",
    "maxPlacesPerSearch": 40,
}

# Run the Actor and wait for it to finish
run = client.actor("juliob.rangel/google-maps-places-scraper-fast").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 '{
  "searchTerms": [
    "dentist"
  ],
  "location": "Austin, TX",
  "maxPlacesPerSearch": 40
}' |
apify call juliob.rangel/google-maps-places-scraper-fast --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,juliob.rangel/google-maps-places-scraper-fast"
        }
    }
}
```

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/gC4ssUNOGGUXChDoQ/builds/srZjSGN9kWuXuILXq/openapi.json
