# Google Maps Scraper - Places, Phones, Ratings, No Browser (`clearfetch/google-maps-scraper`) Actor

Scrape Google Maps search results without a browser: name, category, address, phone, website, rating, review count, opening hours, coordinates and place ID for up to ~200 places per search. Any keyword and location, filters for rating, phone and website.

- **URL**: https://apify.com/clearfetch/google-maps-scraper.md
- **Developed by:** [Nada Hanad](https://apify.com/clearfetch) (community)
- **Categories:** Lead generation, Travel, Automation
- **Stats:** 2 total users, 1 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 Scraper - Places, Phones, Ratings, No Browser

Scrape Google Maps search results without a browser: every place's name, category, address, phone, website, rating,
review count, opening hours, coordinates and place ID, for any search term in any city. Up to about 200 places per
search, fast, because it reads the same data the Maps app loads instead of rendering pages. **$1.00 per 1,000
places.** No login, no API key, no proxy.

### What data you get

One row per place, same columns every time (named like the usual Google Maps exports, so existing sheets and
integrations keep working):

- `title`, `categoryName`, `categories`, `placeId`, `cid`, `url` (opens the place in Google Maps)
- `address`, `street`, `city`, `postalCode`, `state`, `countryCode`, `neighborhood`, `lat`, `lng`, `timezone`
- `phone` (international format) and `phoneUnformatted`, `website`, `domain`
- `totalScore` (rating), `reviewsCount`, `openingHours` (every day of the week), `imageUrl`
- `searchString` and `rank` (position in Google's list)
- With **Find emails and social profiles** on: `emails`, `facebooks`, `instagrams`, `linkedIns`, `twitters`,
  `youtubes`, `tiktoks`, `pinterests` from each place's own website

### How to use

1. Type what you are looking for (`dentist`, `coffee shop`, `plumber`), one per line, and where (`Austin, TX`).
2. Pick how many places per search, and optionally keep only places rated above a score, with a phone number or with
   a website.
3. Run it, then download CSV, Excel or JSON, or pull the rows through the API.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `searchStringsArray` | array | — | Search terms, one per line. Also `searchTerms`, `queries`. |
| `locationQuery` | string | — | Where to search, e.g. `Austin, TX`. `locations` (array) searches several places. |
| `maxCrawledPlacesPerSearch` | integer | `50` | Per term and location. Google lists up to about 200; 0 means all. |
| `startUrls` | array | `[]` | Google Maps search links or place links from the browser. |
| `countryCode` | string | — | Two letters, e.g. `de`, to favour one country when a city name exists in several. |
| `language` | string | `en` | Language of categories, hours and addresses. |
| `minRating` | number | `0` | Leave out places rated below this. |
| `skipWithoutPhone` | boolean | `false` | Only places with a phone number. |
| `skipWithoutWebsite` | boolean | `false` | Only places with a website. |
| `scrapeContacts` | boolean | `false` | Read each place's website for emails and social profiles. |
| `maxPagesPerSite` | integer | `3` | Website pages read per place. |
| `skipWithoutEmail` | boolean | `false` | Only places whose website gave an email. |
| `timeoutSecs` | integer | `30` | Per request. |
| `proxyConfiguration` | object | off | Not needed. |

### Output example

A real row from a run with `"searchStringsArray": ["dentist"], "locationQuery": "Austin, TX"` on 2026-09-30:

```json
{
  "ok": true,
  "type": "place",
  "title": "ATX Family Dental",
  "categoryName": "Dentist",
  "categories": [
    "Dentist",
    "Cosmetic dentist",
    "Dental clinic",
    "Emergency dental service",
    "Pediatric dentist",
    "Teeth whitening service"
  ],
  "address": "1700 S 1st St, Austin, TX 78704, United States",
  "street": "1700 S 1st St",
  "city": "Austin",
  "postalCode": "78704",
  "state": "Texas",
  "countryCode": "US",
  "neighborhood": "Bouldin Creek",
  "lat": 30.2482229,
  "lng": -97.75597049999999,
  "phone": "+1 512-717-3147",
  "phoneUnformatted": "+15127173147",
  "website": "https://www.atxfamilydental.com/",
  "domain": "atxfamilydental.com",
  "totalScore": 4.9,
  "reviewsCount": 911,
  "openingHours": [
    {
      "day": "Wednesday",
      "hours": "8 am–5 pm"
    },
    {
      "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"
    }
  ],
  "timezone": "America/Chicago",
  "imageUrl": "https://lh3.googleusercontent.com/grass-cs/ACvplmPTjIfy6SJVu08J9Ml1pnxITskX_fUa-FefeD9CFzR8mqYfhNfOAqaRuXo0d79aElej6RbD9lYVR1_OcRUzJ0PWpI5jwfmULv8PTXAWvEY6pl5qL5EYBvcqUkSU2Hmuhh-_42D7=w800",
  "placeId": "ChIJb5gBC-u0RIYRHkntaUcdJGs",
  "cid": "7720327853776914718",
  "fid": "0x8644b4eb0b01986f:0x6b241d4769ed491e",
  "url": "https://www.google.com/maps/search/?api=1&query=ATX%20Family%20Dental&query_place_id=ChIJb5gBC-u0RIYRHkntaUcdJGs",
  "searchString": "dentist in Austin, TX",
  "rank": 1,
  "scrapedAt": "2026-09-30T09:45:01.127Z"
}
```

A search or link that cannot be read comes back as one row with `ok: false` and a plain reason, such as
`Google Maps found no places for this search`. Those rows are free.

### Pricing

**$1.00 per 1,000 places** ($0.001 each). With **Find emails and social profiles** on, places whose website gave at
least one email or profile cost $2.00 per 1,000 more. Places left out by your filters, repeats (a place found by two
searches is written once) and failed searches are free.

Paid Apify plans pay less: 10% off on Bronze, 20% on Silver and 30% on Gold and higher tiers.

### Use cases

- **Lead lists**: every dentist, plumber or restaurant in a city with phone, website and rating, ready for a CRM.
- **Local market research**: how many competitors are in an area, how they are rated and how many reviews they have.
- **Store locators and directories**: addresses, coordinates and opening hours for a category or a brand.
- **Enrichment**: add Google ratings, review counts and place IDs to a list of businesses.

### FAQ

**Do I need a Google API key?** No. The Actor reads Google Maps the way its own web app does. There is no quota and
no key to manage.

**How many places can one search return?** Google Maps lists up to about 200 places for one search. For more, split
the area (`dentist in North Austin`, `dentist in South Austin`) or add related terms; repeats are merged and not
charged twice.

**The city name exists in several countries.** Write the country in the location (`Manchester, UK`) or set
`countryCode`.

**Is it legal?** It reads business listings that anyone can see on Google Maps without logging in. You are
responsible for how you use the data, including rules for contacting businesses.

### Integrations

Run it from the Apify API or a client library, schedule it in Apify Console, or connect it to n8n, Make, Zapier or
any MCP client through Apify's integrations. Results are available as JSON, CSV, Excel and through the dataset API.

### More tools from clearfetch

- [Google Maps Email Extractor](https://apify.com/clearfetch/google-maps-email-extractor): the same places with emails and social profiles, set up for lead lists
- [Website Contact Extractor](https://apify.com/clearfetch/website-contact-extractor): emails, phones and social links from any list of websites
- [Tech Stack Detector](https://apify.com/clearfetch/tech-stack-detector): what each business's website runs on
- [Broken Link Checker](https://apify.com/clearfetch/broken-link-checker): check a list of websites for dead links

### Changelog

- **1.1.0** (2026-09) — emails and social profiles from each place's website, "only places with an email" filter.
- **1.0.0** (2026-09) — first release: search terms × locations, search and place links, all place fields from
  the result list, rating/phone/website filters.

# Actor input Schema

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

What to look for, one per line, as you would type it into Google Maps: "dentist", "coffee shop", "plumber". Each term is searched in every location below.

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

Where to search, e.g. "Austin, TX", "Berlin, Germany" or "Manchester, UK". Name the country for city names that exist in several. Several places: use "locations" through the API.

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

Places per search term and location. Google Maps lists up to about 200 for one search; 0 means all of them.

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

Google Maps search links (google.com/maps/search/...) or place links (google.com/maps/place/...), copied from the browser.

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

Two-letter country code that biases results toward that country, e.g. de, gb, fr. Empty uses the location as written.

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

Language for categories, hours and addresses, e.g. en, de, es.

## `minRating` (type: `number`):

Leave out places rated below this (1-5). Left-out places are not charged. 0 keeps all.

## `skipWithoutPhone` (type: `boolean`):

Leave out places without a phone number. Not charged.

## `skipWithoutWebsite` (type: `boolean`):

Leave out places without a website. Not charged.

## `scrapeContacts` (type: `boolean`):

Read each place's website (home page plus contact and imprint pages) for email addresses and Facebook, Instagram, LinkedIn, X, YouTube, TikTok and Pinterest profiles. Charged as a separate event, only for places where something was found.

## `maxPagesPerSite` (type: `integer`):

Pages read on each website: the home page plus the most likely contact pages.

## `skipWithoutEmail` (type: `boolean`):

Leave out places whose website gave no email address (turns on the website lookup). Left-out places are not charged. "Max places per search" still counts places read from Google Maps.

## `timeoutSecs` (type: `integer`):

Per request.

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

Not needed. Google Maps answers Apify's own servers.

## Actor input object example

```json
{
  "searchStringsArray": [
    "dentist"
  ],
  "locationQuery": "Austin, TX",
  "maxCrawledPlacesPerSearch": 20,
  "startUrls": [],
  "countryCode": "",
  "language": "en",
  "minRating": 0,
  "skipWithoutPhone": false,
  "skipWithoutWebsite": false,
  "scrapeContacts": false,
  "maxPagesPerSite": 3,
  "skipWithoutEmail": false,
  "timeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Places with name, category, address, phone, website, rating, review count, opening hours and coordinates. Searches and links that could not be read appear with ok=false and a reason, and are not charged.

# 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": [
        "dentist"
    ],
    "locationQuery": "Austin, TX",
    "maxCrawledPlacesPerSearch": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("clearfetch/google-maps-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 = {
    "searchStringsArray": ["dentist"],
    "locationQuery": "Austin, TX",
    "maxCrawledPlacesPerSearch": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("clearfetch/google-maps-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 '{
  "searchStringsArray": [
    "dentist"
  ],
  "locationQuery": "Austin, TX",
  "maxCrawledPlacesPerSearch": 20
}' |
apify call clearfetch/google-maps-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,clearfetch/google-maps-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/8AzESDcMiQu2IaH5f/builds/YnQ2ENREvh06c0o0m/openapi.json
