# Google Maps Scraper — Business Leads, Phones & Ratings (`muhammadafzal/google-maps-scraper`) Actor

Scrape Google Maps for local business leads: name, phone, website, address, rating, review count, hours and coordinates. USD 4 per 1,000 places.

- **URL**: https://apify.com/muhammadafzal/google-maps-scraper.md
- **Developed by:** [Muhammad Afzal](https://apify.com/muhammadafzal) (community)
- **Categories:** Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 4 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.20 / 1,000 place saveds

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 — Business Leads, Phones & Ratings

Google Maps Scraper turns a search such as "dentists in Chicago" into a list of local businesses from Google Maps with name, phone number, website, full address, star rating, review count, opening hours, categories, GPS coordinates and claimed status. It is built for lead generation, local market research and AI pipelines, and costs USD 4 per 1,000 places on the FREE tier (USD 3.20 per 1,000 on GOLD), with no Google account or Google Maps API key needed.

**Free users: maximum 20 results per run.** Paid Apify plans use the full Max Results Per Query value.

### What data does this Google Maps scraper extract?

Every place is one dataset row:

| Field | Example | Notes |
|---|---|---|
| `title` | `Sote Coffee Roasters` | Business name |
| `phoneNumber` | `+1646-318-9152` | `null` when Google shows none |
| `website` | `https://sotecoffeeroasters.com/` | `utm_` tracking parameters removed; `null` when none |
| `address` | `329 Amsterdam Ave, New York, NY 10023` | Full formatted address |
| `city`, `postalCode`, `countryCode` | `New York`, `10023`, `US` | Address parts for filtering and CRM import |
| `rating`, `ratingCount` | `4.8`, `486` | Star rating and number of Google reviews (the count, not the text) |
| `openingHours` | `{ "Monday": "7:00 AM–6:00 PM", "Sunday": "Closed" }` | By weekday, including `Closed` and `Open 24 hours` |
| `type`, `types` | `Coffee shop`, `["Coffee shop", "Bakery"]` | Main category and all listed categories |
| `isClaimed` | `true` | Whether the owner has claimed the Google Business Profile |
| `priceLevel` | `$$` | `$` to `$$$$` when Google shows one |
| `latitude`, `longitude` | `40.7808931`, `-73.9797338` | GPS coordinates |
| `thumbnailUrl` | `https://lh3.googleusercontent.com/...` | Main photo URL; turn off with `includePhotos: false` |
| `placeId`, `cid`, `fid`, `googleUrl` | `ChIJwR4noh5ZwokREcz36jnEQbo` | Google identifiers and a direct Maps link |
| `searchQuery`, `scrapedAt` | `coffee shops near Central Park` | The query that found the place, and when |
| `description` | `null` | Kept for compatibility; always empty |

Each run also writes an `OUTPUT` record with per-query counts (found, saved, duplicates, below minimum rating), the effective settings and the final status.

### How do I scrape Google Maps for local business leads?

Type the business type and the place into one query, set a limit, and run.

1. **Search Queries:** one search per line, for example `plumbers in Dallas TX` or `hotels near Central Park`.
2. **Max Results Per Query:** 1–200, default 20. A busy search lists about 100 places; in the 2026-10-24 tests a limit of 200 returned 189–190.
3. Optional: **Country Code** and **Language** (12 countries, 9 languages), **Location Coordinates** to search a city-level map area around `latitude,longitude`, and **Minimum Rating** to keep only well-reviewed places.
4. Click **Start**, then download the dataset as CSV, Excel or JSON.

Roofers in three cities, rated 4.0 or higher:

```json
{
  "searchQueries": ["roofers in Dallas TX", "roofers in Austin TX", "roofers in Houston TX"],
  "maxResults": 50,
  "countryCode": "us",
  "minRating": 4.0
}
```

Bakeries around São Paulo city center:

```json
{
  "searchQueries": ["padaria"],
  "locationCoords": "-23.5505,-46.6333",
  "countryCode": "br",
  "languageCode": "pt",
  "maxResults": 40
}
```

A place found by several of your queries is saved and charged once.

### When should I use it, and when not?

**Use it when** you need names, phones, websites, addresses, ratings and review counts for local businesses in any category and city, for outreach lists, competitor maps or local SEO audits.

**Use another Actor when:**

- You want restaurants with top review text: [Google Maps Restaurant Scraper](https://apify.com/muhammadafzal/google-maps-restaurant-scraper).
- You need emails as well as phones for a specific trade: [Lawyer Leads Scraper](https://apify.com/muhammadafzal/lawyer-lead-scraper), [Contractor Leads Scraper](https://apify.com/muhammadafzal/contractor-lead-scraper) or [HVAC Leads Scraper](https://apify.com/muhammadafzal/hvac-lead-scraper).
- You need German directory data with emails: [Gelbe Seiten Scraper](https://apify.com/muhammadafzal/gelbe-seiten-scraper). For Korea: [Kakao Map Scraper](https://apify.com/muhammadafzal/kakao-map-scraper).

### Use it from an AI assistant

Google Maps Scraper works from Claude, ChatGPT, Cursor or any MCP client through Apify's MCP server. Add it with `https://mcp.apify.com/?tools=muhammadafzal/google-maps-scraper`, then ask, for example: "Find 30 dentists in Chicago on Google Maps with phone numbers, websites and ratings above 4.5."

### Google Maps scraper API: an alternative to the Places API

Run the Actor from your own code and get the same place data without a Google Cloud project or Places API key.

JavaScript:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('muhammadafzal/google-maps-scraper').call({
    searchQueries: ['plumbers in Dallas TX', 'HVAC contractors in Houston TX'],
    maxResults: 50,
    minRating: 4.0,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Found ${items.length} businesses`);
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("muhammadafzal/google-maps-scraper").call(
    run_input={"searchQueries": ["dentists in Chicago IL"], "maxResults": 20}
)
for place in client.dataset(run.default_dataset_id).iterate_items():
    print(place["title"], place["phoneNumber"], place["rating"])
```

You can also schedule runs or connect the Actor to Make, Zapier or n8n through Apify integrations.

### What does the output look like?

Two places from the 2026-10-26 prefill run (`coffee shops near Central Park`), shortened:

```json
[
  {
    "placeId": "ChIJwR4noh5ZwokREcz36jnEQbo",
    "title": "Sote Coffee Roasters",
    "address": "329 Amsterdam Ave, New York, NY 10023",
    "phoneNumber": "+1646-318-9152",
    "website": "https://sotecoffeeroasters.com/",
    "rating": 4.8,
    "ratingCount": 486,
    "latitude": 40.7808931,
    "longitude": -73.9797338,
    "type": "Coffee shop",
    "types": ["Coffee shop"],
    "priceLevel": null,
    "openingHours": { "Monday": "7:00 AM–6:00 PM", "Friday": "7:00 AM–7:00 PM", "Sunday": "7:00 AM–6:00 PM" },
    "description": null,
    "cid": "13421224117575076881",
    "googleUrl": "https://www.google.com/maps/place/?q=place_id:ChIJwR4noh5ZwokREcz36jnEQbo",
    "isClaimed": true,
    "city": "New York",
    "postalCode": "10023",
    "countryCode": "US",
    "scrapedAt": "2026-10-26T07:44:04.556Z",
    "searchQuery": "coffee shops near Central Park"
  },
  {
    "placeId": "ChIJK4Gklg1ZwokRmDGLQSxEaUI",
    "title": "Sip and Co",
    "address": "41 W 58th St, New York, NY 10019",
    "phoneNumber": "+1516-960-2283",
    "website": "http://sipandco.co/",
    "rating": 4.5,
    "ratingCount": 785,
    "type": "Coffee shop",
    "types": ["Coffee shop", "Bakery", "Breakfast restaurant", "Cafe"],
    "isClaimed": true,
    "postalCode": "10019"
  }
]
```

### Pricing: how much does Google Maps data cost?

Google Maps Scraper uses pay-per-event pricing. Platform usage is included in the event prices.

| Event | FREE | BRONZE | SILVER | GOLD | PLATINUM / DIAMOND |
|---|---:|---:|---:|---:|---:|
| Place saved (one dataset row) | USD 0.004 | USD 0.0039 | USD 0.0038 | USD 0.0032 | USD 0.0032 |
| Actor start, per started GB of allocated memory | USD 0.006251 | USD 0.006094 | USD 0.005938 | USD 0.005 | USD 0.005 |

Free users: maximum 20 results per run. Runs use 256 MB by default, so one start event is charged. Worked totals:

- 20 places on FREE: 20 × USD 0.004 + USD 0.006251 = **USD 0.0863**
- 1,000 places on FREE: 1,000 × USD 0.004 + USD 0.006251 = **USD 4.0063** (GOLD: **USD 3.205**)

Duplicate places across your queries are not charged twice, and a search that finds nothing charges no places.

### What are the limits?

- **Speed:** the 20-place prefill run finished in 11 seconds. Paid runs search up to 3 queries at a time.
- **No review text, no emails:** it returns the rating and review count, not reviews, and Google Maps listings do not contain emails. One main photo per place.
- **Coverage per query** depends on what Google Maps lists for that search. Split large areas into several queries (for example by neighborhood).
- **Targeting:** a country-wide search usually honors the city in your query, but some phrasings miss it. For exact targeting, set **Location Coordinates** and keep only the business type in the query.
- **Missing fields:** hours, phone, website and price level are `null` when Google does not show them.
- **Early stop:** if many searches in a row find no new places, the run stops and its status message lists the skipped queries.

### FAQ

#### Is there a free Google Maps scraper?

You can run this one on Apify's free plan, within the free-plan cap shown under Pricing. Paid plans have no cap. Every plan pays the per-place prices.

#### Is it legal to scrape Google Maps?

This Actor collects publicly visible business listing data. You are responsible for how you use it: follow Google's terms, data-protection laws such as GDPR when a listing identifies a person, and anti-spam rules for outreach.

#### Can I scrape phone numbers and addresses from Google Maps?

Yes. `phoneNumber` and `address` (plus `city`, `postalCode` and `countryCode`) are returned wherever Google lists them, with the website and coordinates.

#### Does it extract reviews or emails?

No. It returns the star rating and number of reviews, not review text, and Google Maps listings do not include emails.

#### Do I need a Google Maps API key?

No. You only need an Apify account; the Actor handles data access.

#### How do I export Google Maps data to Excel or CSV?

Open the run's dataset and export it as Excel, CSV, JSON, XML or HTML, or fetch it through the dataset API.

#### Can I search several cities in one run?

Yes. Add one query per city, such as `dentists in Chicago` and `dentists in New York`. Each place records the `searchQuery` that found it.

### Related Actors

Local business and lead tools from the same developer:

- [Google Maps Restaurant Scraper](https://apify.com/muhammadafzal/google-maps-restaurant-scraper) for restaurants with top reviews
- [Yellow Pages Scraper USA](https://apify.com/muhammadafzal/yellow-pages-us-scraper) for US directory listings
- [Gelbe Seiten Scraper](https://apify.com/muhammadafzal/gelbe-seiten-scraper) for German business leads with emails
- [HdL Municipal Business License Lookup](https://apify.com/muhammadafzal/hdl-municipal-business-license-lookup) for city business-license records
- [Franchise Direct Scraper](https://apify.com/muhammadafzal/franchise-direct-scraper) for franchise opportunity data

### Legal and compliance

Google Maps Scraper collects business information that Google Maps shows publicly. It does not log in or bypass access controls. You are responsible for complying with Google's terms, GDPR and other privacy laws, and anti-spam rules such as CAN-SPAM and the TCPA when you contact businesses. This is not legal advice.

Last verified: 2026-10-26

# Actor input Schema

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

One or more Google Maps searches, each with a business type and a place (e.g. 'restaurants in Austin TX', 'plumbers in Chicago', 'hotels near Central Park'). Each query returns up to Max Results Per Query places; duplicate places across queries are saved once.

## `locationCoords` (type: `string`):

Optional 'latitude,longitude' (e.g. '40.7128,-74.0060' for New York City). When set, the search runs on a city-level map view centered there instead of the whole country. Leave empty to search by country.

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

Two-letter country code for search localization (e.g., 'us' for United States, 'gb' for United Kingdom).

## `languageCode` (type: `string`):

Language code for search results (e.g., 'en' for English, 'es' for Spanish).

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

Maximum places to save per search query (1–200). Google Maps usually lists about 100 places for a busy search; narrow searches return fewer. Default 20.

## `includePhotos` (type: `boolean`):

Include the URL of each place's main photo. Turn off for smaller output.

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

Only return places with rating >= this value (0 = no filter). Set to 4.0 for highly-rated businesses.

## `maxRequestRetries` (type: `integer`):

How many times to retry a search that fails temporarily. Values above 3 are treated as 3.

## Actor input object example

```json
{
  "searchQueries": [
    "coffee shops near Central Park"
  ],
  "locationCoords": "",
  "countryCode": "us",
  "languageCode": "en",
  "maxResults": 20,
  "includePhotos": true,
  "minRating": 0,
  "maxRequestRetries": 3
}
```

# Actor output Schema

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

Link to the dataset with one record per Google Maps place.

## `runSummary` (type: `string`):

OUTPUT record with per-query counts, settings, stop reason and status.

# 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": [
        "coffee shops near Central Park"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("muhammadafzal/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 = { "searchQueries": ["coffee shops near Central Park"] }

# Run the Actor and wait for it to finish
run = client.actor("muhammadafzal/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 '{
  "searchQueries": [
    "coffee shops near Central Park"
  ]
}' |
apify call muhammadafzal/google-maps-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,muhammadafzal/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/Osrcq5fVcfchVlxsJ/builds/y7ISajeY2KVGqofKM/openapi.json
