# Google Maps Places Scraper: Business Data by Area (`charitable_trousseau/google-maps-places-scraper`) Actor

Search Google Maps for businesses across a whole city, region, postcode or radius. One row per place: name, address, phone, website, categories, rating, review count, opening hours, coordinates. One flat price per place, no add-on fees. Duplicates removed, only places inside your area.

- **URL**: https://apify.com/charitable_trousseau/google-maps-places-scraper.md
- **Developed by:** [Charitable Trousseau](https://apify.com/charitable_trousseau) (community)
- **Categories:** Lead generation, Travel, Developer tools
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 places

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 Places Scraper: Business Data by Area

Search Google Maps for a kind of business across a whole city, district, postcode, region or radius, and get one row per place. One price per place: no add-on fees for details, filters or languages.

### What you can do with it

- List every business of one kind in a city, district or postcode: all dentists in Austin, all restaurants in a Barcelona district.
- Count and map competitors per area with `latitude`, `longitude`, `rating` and `reviewCount`.
- Find every branch of a chain in a city or region by searching for the brand name.
- Find businesses that list no website with the website filter (filtered places are not charged).

### What you get

One record per place:

- **Identity:** `name`, `placeId` (Google's stable ID), `category` and `categories`, `description` when Google has one, `url` (opens the place on Google Maps)
- **Address:** `address` (full, as Google prints it), `street`, `neighborhood`, `city`, `postalCode`, `state`, `countryCode`
- **Position:** `latitude`, `longitude`, `plusCode`, `timezone`
- **Contact:** `phone` (local format), `phoneInternational`, `website`, `domain`, `bookingUrl` when listed
- **Reputation:** `rating`, `reviewCount`
- **Opening hours:** `openingHours`, seven days as Google prints them
- **Status:** `claimed` (false when Google shows "claim this business"), `closed` (permanently or temporarily closed)
- **Features:** `attributes` Google lists as present, for example `Wheelchair accessible entrance`
- **Other IDs:** `cid`, `featureId`, `kgmid`
- **Run details:** `searchTerm`, `location` (the area as it was understood), `language`, `scrapedAt`

```json
{
    "placeId": "ChIJb5gBC-u0RIYRHkntaUcdJGs",
    "name": "ATX Family Dental",
    "category": "Dentist",
    "categories": ["Dentist", "Cosmetic dentist", "Dental clinic", "Emergency dental service", "Pediatric dentist", "Teeth whitening service"],
    "address": "1700 S 1st St, Austin, TX 78704",
    "street": "1700 S 1st St",
    "neighborhood": "Bouldin Creek",
    "city": "Austin",
    "postalCode": "78704",
    "state": "Texas",
    "countryCode": "US",
    "latitude": 30.2482229,
    "longitude": -97.7559705,
    "plusCode": "862466XV+7J",
    "phone": "(512) 717-3147",
    "phoneInternational": "+15127173147",
    "website": "https://www.atxfamilydental.com/",
    "domain": "atxfamilydental.com",
    "rating": 4.9,
    "reviewCount": 915,
    "priceLevel": null,
    "openingHours": [
        { "day": "Thursday", "hours": "8 AM–5 PM" },
        { "day": "Friday", "hours": "8 AM–4 PM" },
        { "day": "Saturday", "hours": "Closed" },
        { "day": "Sunday", "hours": "Closed" },
        { "day": "Monday", "hours": "8 AM–5 PM" },
        { "day": "Tuesday", "hours": "8 AM–5 PM" },
        { "day": "Wednesday", "hours": "8 AM–5 PM" }
    ],
    "timezone": "America/Chicago",
    "description": null,
    "claimed": true,
    "closed": false,
    "attributes": ["Wheelchair accessible entrance", "Wheelchair accessible parking lot", "Wheelchair accessible restroom", "Wheelchair accessible seating"],
    "bookingUrl": "https://www.atxfamilydental.com/book-online/",
    "featureId": "0x8644b4eb0b01986f:0x6b241d4769ed491e",
    "cid": "7720327853776914718",
    "kgmid": "/g/11cn2mvqwc",
    "url": "https://www.google.com/maps/place/?q=place_id:ChIJb5gBC-u0RIYRHkntaUcdJGs",
    "searchTerm": "dentist",
    "location": "Austin, Texas, United States",
    "language": "en",
    "scrapedAt": "2026-10-08T16:50:12.000Z"
}
```

### Input

- **Search terms** — what to look for, one per line: `dentist`, `pizza`, `coworking space`, or a brand name.
- **Locations** — where, one per line: a city, district, region, country or postcode. Every search term is run in every location, so several cities fit in one run.
- **Maximum places per search** — default 200. A search never saves (or charges) more than this.
- **Language** — language of categories, addresses and opening hours.
- **Website filter** and **Skip closed places** — optional, free of charge. Filtered places are not saved.
- **Latitude, longitude, radius** — optional: search a circle around a point instead of a named location.
- **Country** — optional two-letter code; give it with a postcode, since the same digits exist in several countries (`78704` with `US`, `LS1` with `GB`).

If the input names no search term, no location and no coordinates (for example an API call with an empty input), the example search runs: `coffee shop` in Boulder, Colorado, USA.

```json
{
    "searchTerms": ["dentist", "orthodontist"],
    "locations": ["Austin, Texas, USA", "Round Rock, Texas, USA"],
    "maxPlacesPerSearch": 2000
}
```

```json
{
    "searchTerms": ["restaurant"],
    "latitude": 52.5225,
    "longitude": 13.4025,
    "radiusKm": 1.2,
    "language": "de",
    "website": "without"
}
```

### FAQ

#### How do I get all businesses of one type in a city from Google Maps?

Put the kind of business in **Search terms** and the city in **Locations**, and raise **Maximum places per search**. The scraper cuts the area into map tiles and searches each one, so it is not held to what a single map view shows. Expect about 96 to 99% of what Google Maps itself will show for the search, not 100%; the measurements are under "Coverage, measured".

#### How do I get more than 200 results from a Google Maps search?

Google Maps shows at most about 200 places for one map view. This scraper divides the area into tiles, down to about 100 metres wide in the densest streets, and saves each place once. A search for dentists in the whole of Austin, Texas saved 1,332 places.

#### Does it scrape Google Maps reviews or find emails?

No. It returns what Google Maps shows about a business: name, address, phone, website, categories, rating, review count, opening hours and coordinates. It does not collect review texts or reviewer names and does not visit business websites for emails or social profiles.

#### How fast is it?

Measured on 8 October 2026 with the default settings: 50 places in one city took 3 to 17 seconds, 1,332 dentists across Austin 5 minutes 19 seconds, and 5,000 restaurants in Manhattan 2 minutes 4 seconds.

#### How much does it cost?

$1.00 per 1,000 places on Apify's Free plan, plus a start fee of $0.00005 per run, with no add-on fees. Paid Apify plans pay less: Bronze 10%, Silver 20% and Gold 30% less. Runs that fail or return nothing cost nothing.

### How an area is covered

Google Maps shows at most about 200 places for one map view, and on a zoomed-out map it leaves places out. The scraper therefore cuts your area into map tiles, searches each tile, and keeps cutting tiles into four wherever places keep turning up, down to tiles about 100 metres wide in the densest streets. Each place is saved once, however many tiles return it.

**Only places inside your area are saved.** For a named location the outline comes from OpenStreetMap: the administrative boundary of a city, district, region or country, and the real outline of a postcode where OpenStreetMap has one (Germany, France and much of continental Europe). The run log says what each location was understood as, with the size of the area. If OpenStreetMap does not know the place, Google Maps is asked instead and the area is a square around the spot.

**Postcodes without an outline are approximated**, and the log says so:

- **US ZIP codes** use the Census Bureau's ZIP Code Tabulation Area (2020 census). It follows the ZIP code closely, not exactly: in our run for 10001, 40 of 43 places had 10001 in their address and 3 had a neighbouring ZIP code. Give the country (`US`) with a bare ZIP code.
- **The first part of a British or Canadian postcode** (`LS1`, `SW1A`, `M5V`) and other postcodes with no outline anywhere: the square that Google Maps shows for the postcode is searched, and only places whose address carries that postcode are saved (a place with no postcode in its address is kept). Parts of the postcode that reach beyond that square are missed.
- **A full British postcode** (`LS1 4AP`) is a single street: a square of 2 km around it is searched.

### Coverage, measured

Runs on 8 October 2026. "Reference" is a much slower run of the same search that cuts every tile holding anything down to 30 to 125 metres.

| Search | Places saved | Compared with |
|---|---|---|
| Dentists in Austin, Texas | 1,332 | 96.7% of the 1,377 places that this run and the reference run found between them (the reference alone: 98.0%) |
| Dentists, 4 km circle in north Austin | — | default rules reach 96 to 97% of the reference (212 dental places) |
| Restaurants, 1.2 km circle in Berlin Mitte | — | default rules reach 99.0% of the reference (764 places) |
| Restaurants, 0.5 km circle in Manhattan | — | default rules reach 96.7% of the reference (394 places) |
| Coffee shops in Boulder, Colorado | 157 | default rules reach 97.2% of the reference (142 coffee places) |
| Whataburger in Austin, Texas | 19 | published counts are 20 to 21 for addresses in "Austin", which reaches beyond the city boundary |
| Whataburger in San Antonio, Texas | 56 | published count 57 |
| Whataburger in Houston, Texas | 47 | published count 57 for addresses in "Houston", much of which lies outside the city boundary searched |
| Starbucks in Boulder, Colorado | 9 | a store directory lists 9 |

Expect about 96 to 99% of what Google Maps itself will show for the search, not 100%. Google also answers the same search slightly differently from one minute to the next: two runs of the Austin search saved 1,332 and 1,297 places.

### Speed, measured

Runs on 8 October 2026 with the default settings (1 GB of memory).

| Search | Places | Time |
|---|---|---|
| Restaurants in Manhattan, stopped at 5,000 | 5,000 | 2 min 4 s |
| Restaurants in Ciutat Vella, Barcelona (whole district) | 1,664 | 3 min 22 s |
| Dentists in Austin, Texas (whole city) | 1,332 | 5 min 19 s |
| "Meadery" in the whole of Colorado | 66 | 44 s |
| Coffee shops in Boulder, Colorado (the example input) | 157 | 1 min 19 s |
| 50 places in one city (seven countries tried) | 50 | 3 to 17 s |

Dense areas give 500 to 2,400 places a minute. Spread-out searches (a whole city of dentists, a rare business in a large region) give 100 to 250 a minute, because most map tiles hold only a few places. With the run's memory set to 4 GB the same Austin search took 2 min 23 s and the Barcelona search 2 min 6 s.

### Limits to know about

- **No reviews, no emails, no contact enrichment.** This tool returns what Google Maps shows about a business. It does not collect review texts or reviewer names, does not visit business websites for emails or social profiles, and does not look up people.
- **No price level.** Google no longer sends a price level or price range with search results (checked 15 October 2026 on restaurants in Madrid and Manhattan: none of 400 places carried one), so `priceLevel` is always empty. It is kept in the output so existing integrations do not break. Price ranges now appear only on each place's own page, which this scraper does not open.
- **`description`** is Google's short editorial summary. Google writes these mostly for restaurants, bars, hotels and attractions (about 60% of restaurants in our runs); most other businesses, dentists or plumbers for example, have none.
- **Service-area businesses** (plumbers, cleaners, mobile services) that hide their address on Google come without `address` and its parts; their coordinates are still saved.
- **No photos and no popular times.**
- **Review count and weekly hours are missing on a few places** (0 to 5% in our runs). Google answers each request in a fuller or a shorter form at random; the scraper asks again when it gets the shorter one, and a place that never came in the fuller form is saved with `reviewCount` and `openingHours` empty. Places such as hotels have no opening hours on Google at all.
- **`plusCode` is worked out from the coordinates**, in the full form (`862466XV+7J`), not the short form with a town name.
- **`category` follows your search.** Google lists a place's categories in an order that suits the search term, so the same café can come back as "Coffee shop" in one search and "Cafe" in another. `categories` holds all of them.
- **Google decides what matches.** A search for "dentist" also returns some medical clinics; a rare term returns loosely related places. Check `categories` if you need a strict list.
- **Names are in the local language**; categories, addresses and hours follow the language you choose where Google has a translation.
- **City outlines can be smaller than you expect.** "Houston" is the city boundary, not every address with Houston in it. Add the neighbouring towns or use a radius for a wider net.
- **City outlines can also be larger than the built-up city.** "Leeds, UK" is the City of Leeds district, about 33 by 27 km, which takes in towns such as Wetherby and Pudsey. Use a postcode or a radius for the centre only.
- **Postcode areas are exact only where OpenStreetMap has their outline.** Elsewhere they are approximated as described under "How an area is covered".
- **Not supported:** areas that cross the 180th meridian, and circles wider than 500 km.
- **`claimed` and `closed`** are read from marks in Google's data (the "claim this business" link and the closed flag).

### Pricing

You pay per place saved. Places removed by your filters, repeats and places outside your area are not charged. Runs that return nothing cost nothing.

### Reliability

Requests go out from datacenter addresses and are repeated on a new address when one fails; a request refused three times is repeated on residential addresses. Google's cookie-consent and "unusual traffic" pages are recognised and never saved as data. Places are saved as they arrive, so a run that is stopped keeps what it has. If some map tiles could not be read, the run says so and names the search; if more than a tenth could not, the run fails instead of passing off partial data as complete. Every run stores a `SUMMARY` record (key-value store) with, per search: places saved, map tiles read, repeats and out-of-area places dropped, requests and refusals.

### Notes

This scraper collects business listings only. Phone numbers and websites are those the business publishes on Google Maps. It does not collect reviews, reviewer names or any other personal data, and it does not log in.

### Related scrapers

- [Coles Australia Grocery Price Scraper](https://apify.com/charitable_trousseau/coles-au-product-scraper): products, prices and specials from coles.com.au
- [AliExpress Product Search Scraper](https://apify.com/charitable_trousseau/aliexpress-search-scraper): search results by keyword with prices, discounts and units sold
- [eBay Active Listings & Auctions Search Scraper](https://apify.com/charitable_trousseau/ebay-search-scraper): active listings and auctions on five eBay sites
- [Apple App Store Scraper](https://apify.com/charitable_trousseau/app-store-scraper): iOS top charts, search results and app details
- [Zillow ZIP Code Search Scraper](https://apify.com/charitable_trousseau/zillow-search-scraper): homes for sale, rentals and recently sold homes
- [Tripadvisor Places Scraper](https://apify.com/charitable_trousseau/tripadvisor-listings-scraper): hotels, restaurants and things to do for any place
- [Indeed Jobs Scraper](https://apify.com/charitable_trousseau/indeed-jobs-scraper): job listings on 12 Indeed country sites, descriptions optional
- [Glassdoor Jobs Scraper](https://apify.com/charitable_trousseau/glassdoor-jobs-scraper): job listings with salary ranges and employer ratings
- [LinkedIn Jobs Scraper](https://apify.com/charitable_trousseau/linkedin-jobs-scraper): job postings past LinkedIn's 1,000-per-search limit, no login
- [Google Trends Scraper](https://apify.com/charitable_trousseau/google-trends-scraper): interest over time, interest by region, rising queries and trending searches

# Actor input Schema

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

What to look for, one per line, as you would type it into Google Maps: dentist, pizza, coworking space. Do not add the place here; put it under Locations. If the search terms, locations and coordinates are all empty, the example search (coffee shop in Boulder, Colorado, USA) runs.

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

Where to look, one per line: a city, district, region, country or postcode. Add the region or country when the name is common (Springfield, Illinois, USA). Every search term is run in every location, and only places inside the location are saved.

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

Stop each search (one search term in one location) after this many places. The run never saves more than this per search.

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

Language of categories, addresses, opening hours and (where Google has a translation) names.

## `website` (type: `string`):

Keep all places, only places with a website, or only places without one. Filtered places are not saved and not charged.

## `skipClosed` (type: `boolean`):

Leave out places Google marks as permanently or temporarily closed.

## `latitude` (type: `number`):

Instead of (or in addition to) a location by name: the centre of a circle to search, for example 40.7128. Use together with longitude and radius.

## `longitude` (type: `number`):

Centre of the circle, for example -74.006.

## `radiusKm` (type: `number`):

Radius of the circle in kilometres. Used only with latitude and longitude.

## `countryCode` (type: `string`):

Optional. Two-letter country code such as US, GB, DE. Limits where a location name is looked up (useful for postcodes) and sets which country's Google Maps answers. Left empty, the country of each location is used.

## Actor input object example

```json
{
  "searchTerms": [
    "coffee shop"
  ],
  "locations": [
    "Boulder, Colorado, USA"
  ],
  "maxPlacesPerSearch": 200,
  "language": "en",
  "website": "any",
  "skipClosed": false,
  "radiusKm": 5
}
```

# Actor output Schema

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

All places saved by the run.

## `summary` (type: `string`):

Per search: places saved, map tiles read, repeats and out-of-area places dropped, requests and refusals.

# 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": [
        "coffee shop"
    ],
    "locations": [
        "Boulder, Colorado, USA"
    ],
    "maxPlacesPerSearch": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("charitable_trousseau/google-maps-places-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 = {
    "searchTerms": ["coffee shop"],
    "locations": ["Boulder, Colorado, USA"],
    "maxPlacesPerSearch": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("charitable_trousseau/google-maps-places-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 '{
  "searchTerms": [
    "coffee shop"
  ],
  "locations": [
    "Boulder, Colorado, USA"
  ],
  "maxPlacesPerSearch": 200
}' |
apify call charitable_trousseau/google-maps-places-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,charitable_trousseau/google-maps-places-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/2ol93OZ9KfaLEOAm3/builds/hR3MEukQCTONM1Hs2/openapi.json
