# Google Maps Scraper ($1.20/1000 results) (`api-ninja/google-maps-scraper`) Actor

Extract comprehensive business data from Google Maps, including ratings, emails, social media profiles, photos, and operational details. Perfect for market research and lead generation.

- **URL**: https://apify.com/api-ninja/google-maps-scraper.md
- **Developed by:** [API ninja](https://apify.com/api-ninja) (community)
- **Categories:** Lead generation, Travel
- **Features:** Limited permissions
- **Stats:** 680 total users, 32 monthly users, 97.9% runs succeeded, 30 bookmarks
- **User rating**: 4.94 out of 5 stars

## Pricing

from $1.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.
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

**Google Maps Scraper** is an Apify Actor designed to extract **Google Maps business and location data** at scale through the Local Business Data API. It uses a grid-based **quadtree search** to discover businesses across large or dense areas.

📍 **Search by location & query** (e.g., 'dentists in Berlin')
🔍 **Deep grid search** to bypass 120‑result limit
🧾 **Export to JSON, CSV, Excel, HTML**

**Who is this for?**\
Perfect for **marketing professionals, researchers, and developers** who need large-scale local business data for lead generation or market analysis, without needing to write code.

💡 **Need Reviews?**\
This Actor focuses on discovering places and their details. To **parse detailed reviews** (text, author, dates, stars) for these places, use our companion tool:\
👉 **[Google Maps Reviews Scraper](https://apify.com/api-ninja/google-maps-reviews-scraper)**

***

### Table of contents

- [What does this Google Maps scraper do?](#what-does-this-google-maps-scraper-do)
- [What data can you extract from Google Maps?](#what-data-can-you-extract-from-google-maps)
- [How to scrape Reviews](#how-to-scrape-reviews)
- [Use cases: Google Maps data for leads & local SEO](#use-cases-google-maps-data-for-leads--local-seo)
- [How to scrape Google Maps business data](#how-to-scrape-google-maps-business-data)
- [Tips: performance & accuracy](#tips-performance--accuracy)
- [Limitations & Notes](#limitations--notes)
- [Is it legal to scrape Google Maps?](#is-it-legal-to-scrape-google-maps)
- [Input](#input)
- [Output](#output)
- [Integrations and API](#integrations-and-api)
- [Pricing](#pricing)
- [FAQ](#faq)
- [Support](#support)
- [License](#license)
- [Acknowledgments](#acknowledgments)

***

### What does this Google Maps scraper do?

Google Maps Scraper extracts structured data from **Google Maps** based on your **location** and optional **search query**. It supports both:

1. **Text Search**: Find specific businesses (e.g., "coffee shops in Berlin", "Tesla chargers").
2. **Area Search**: Search around coordinates or recursively within an exact bounding box.

**Key Feature: Deep Search**\
Standard Google Maps searches often limit results to the top ~120 places. This Actor subdivides the search area into smaller "tiles" (quadtree), recursively querying each one to uncover **all available places** in the region, regardless of the display limits.\[[GMaps grids & zoom](https://blog.apify.com/google-places-api-limits/#how-google-maps-scraper-gets-results)]

> **Note on coverage:**\
> Because the Actor relies on Google’s viewport tiles, results may sometimes extend slightly outside the exact requested bounds or vary based on Google's data density. This is normal behavior for "search by area".

***

### What data can you extract from Google Maps?

You can extract the following fields for each place (availability depends on the specific business):

| Category | Data points | Example field in output |
| :--- | :--- | :--- |
| **Basic info** | Name, business categories, Place ID | `name`, `subtypes`, `place_id` |
| **Location** | Address, city, country, coordinates | `full_address`, `latitude`, `longitude` |
| **Contact** | Phone, website, Google Maps URL | `phone_number`, `website`, `place_link` |
| **Contact enrichment (optional)** | Emails and social/contact links from the business web presence | `emails_and_contacts` |
| **Performance** | Rating, review count, price level | `rating`, `review_count`, `price_level` |
| **Metadata** | Business status and hours | `business_status`, `working_hours` |

You can download the dataset in **JSON, CSV, Excel, or HTML table formats** from the Storage tab.

***

### How to scrape Reviews

This Actor is optimized for **Place Discovery**. If your goal is to analyze customer sentiment, extract review text, or monitor feedback, you should use the extracted Place IDs or URLs from this run as input for our specialized reviews scraper.

**Workflow:**

1. **Run Google Maps Scraper** (this Actor) to find businesses.
2. **Copy the `place_link` or `place_id`** from the results.
3. **Run the [Google Maps Reviews Scraper](https://apify.com/api-ninja/google-maps-reviews-scraper)** using those IDs/URLs.

***

### Use cases: Google Maps data for leads & local SEO

- **Generate Leads**: Build lists of local businesses with phone numbers and websites (e.g., "Plumbers in New York").
- **Market Research**: Analyze competitor density and ratings across different neighborhoods.
- **Site Selection**: Evaluate potential locations for new stores based on existing amenities.
- **Data Enrichment**: Verify or update your existing business database with fresh Google Maps data.

#### Why run this scraper on Apify?

Running this Actor on the Apify platform gives you advantages over local scripts:

- **Scheduling**: Schedule recurring scrapes (daily/weekly) to keep your local business data fresh.
- **Proxies**: Uses built‑in proxy rotation for reliable scraping without getting blocked.
- **Integrations**: Connect results directly to CRMs, Google Sheets, or Slack via Zapier/Make.
- **Monitoring**: Track run history, logs, and errors in a single dashboard.

***

### How to scrape Google Maps business data

#### How to scrape Google Maps data without coding

1. **Open the Actor** in the Apify Console.
2. **Go to the Input tab**.
3. **Enter a Query and Location**: e.g., `coffee shops` and `London, UK`. For precise coverage, provide center coordinates and a radius or all four bounding-box coordinates.
4. **Choose the Area**: The Actor uses an exact bounding box first, then center coordinates and radius, then geocodes `location`. Initial business results are used for area inference only as a fallback.
5. **(Optional) Set Filters**: Filter by Local Business Data subtype, verification, or business status.
6. **(Optional) Enable `includeContacts`**: Adds deeper contact enrichment (`emails_and_contacts`) per place. This takes longer and applies an additional per-result Actor charge.
7. **Start the Run**: Click **Start**.
8. **Download Results**: Once finished, go to the **Dataset** tab to export your data.

***

### Tips: performance & accuracy

To get the most out of your runs and optimize Compute Units (CUs):

- **Use smaller locations**: For exhaustive scrapes, targeting specific districts or ZIP codes (e.g., "Manhattan, NY" instead of "New York") often yields better coverage and performance than broad city searches.
- **Validate first**: Start with a small `maxResultCount` (e.g., 50) to verify your search queries and filters are returning the expected data before launching a large run.
- **Deep search control**: Uncheck `scrapeAllPlaces` if you only need the top-ranking results. Enable it only when you need comprehensive coverage of an entire area.
- **Contact enrichment cost/performance**: Enable `includeContacts` only when needed. Seed results can include contacts directly; recursive area results are deduplicated first and then enriched in batches. An additional Actor event charge applies to each enriched output record.

***

### Limitations & Notes

- **Density Limits**: In extremely dense urban areas (e.g., Manhattan), Google might not return every single small business in one pass. For 100% coverage, split your search into smaller sub-districts or use ZIP codes.
- **Viewport Overlap**: Results may occasionally include places slightly outside your requested bounds if they fall within the overlapping map tiles used for searching.
- **Language Bias**: The results' language and formatting can be influenced by the `languageCode` and `regionCode` input parameters.

***

### Is it legal to scrape Google Maps?

This Actor extracts **publicly available business information**. However, you must comply with:

- **Regulations**: GDPR, CCPA, and other data protection laws (especially regarding personal data in reviews, though this Actor primarily targets business info).
- **Terms of Service**: Google's terms regarding crawling and data use. See [Google Maps Platform Terms of Service](https://cloud.google.com/maps-platform/terms).

***

### Input

The input configuration allows you to define the search area, query, and filters. Below are the primary fields:

| Field | Type | Description |
| :--- | :--- | :--- |
| `location` | string | Optional city, address, or area (e.g., "Paris", "NYC"). Either this or `textQuery` is required. |
| `textQuery` | string | Business type or keyword (e.g., "pizza"). Either this or `location` is required. |
| `latitude`, `longitude` | number | Optional center coordinates. Both must be supplied together. |
| `radiusMeters` | number | Radius around center coordinates; defaults to 25,000 meters. |
| `north`, `south`, `east`, `west` | number | Optional exact bounding box. Supply all four values, with `north > south` and `east > west`. Latitude must be between -90 and 90; longitude between -180 and 180. |
| `maxResultCount` | number | Approximate target number of places to return. |
| `scrapeAllPlaces` | boolean | Enable deep grid search for full coverage (slower, more results). |
| `includeContacts` | boolean | If `true`, enriches places with `emails_and_contacts` (emails/social/contact links when available). Slower and billed as an additional per-result Actor event. |
| `languageCode` | string | Language for results (e.g., `en`, `de`, `es`). |

> **Note**: See full configuration options including Place Types, Price Levels, and EV Charging filters in the **Input** tab of the Actor.

For example, a valid bounding box is `{"north":40.78,"south":40.12,"east":-71.85,"west":-72.72}`. With negative longitudes, the less negative value is farther east. Reversed coordinates are rejected with a suggested correction; they are not automatically swapped. Equal coordinate pairs, incomplete boxes, and boxes crossing 180 degrees longitude are not supported.

***

### Output

Results are stored in the default Apify dataset. You can download the dataset in **JSON, CSV, Excel, or HTML table formats** from the **Storage** or **Dataset** tab. The full output schema is also available for review in the Dataset tab.

If `includeContacts` is enabled, records may include an additional `emails_and_contacts` object. This field can be `null` when no contacts are found.

**Example JSON Object:**

```json
{
  "business_id": "0x89c2589a018531e3:0xb9df1f7387a94119",
  "place_id": "ChIJ4zGFAZpYwokRGUGph3Mf37k",
  "name": "Example Pizza",
  "subtypes": ["Pizza restaurant", "Italian restaurant"],
  "full_address": "123 Example St, New York, NY 10001",
  "latitude": 40.7501,
  "longitude": -73.9972,
  "rating": 4.8,
  "review_count": 523,
  "phone_number": "+12125550123",
  "website": "https://example.com",
  "emails_and_contacts": {
    "emails": ["hello@example.com"],
    "socials": ["https://www.instagram.com/example"]
  },
  "place_link": "https://www.google.com/maps/place/...",
  "business_status": "OPEN"
}
```

***

### Integrations and API

You can programmatically trigger this Actor using the [Apify API](https://docs.apify.com/api/v2) or [Apify Client for Python/JS](https://docs.apify.com/sdk).

**Python Example:**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {
    "location": "San Francisco, CA",
    "textQuery": "coffee shops",
    "maxResultCount": 100
}

run = client.actor("api-ninja/google-maps-scraper").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{item['name']} - {item['rating']} stars")
```

***

### Pricing

This Actor uses **pay-per-event pricing** with a **$0.10 minimum total charge per run**.

| Charge | Free plan | Bronze-Diamond plans |
| --- | ---: | ---: |
| Actor start | $0.01 | $0.01 |
| Result saved to the default dataset | $0.01 per result | $0.0012 per result |
| Contact enrichment with `includeContacts` | $0.03 per enriched result | $0.003 per enriched result |

The Actor start event is charged once per GB of memory, with at least one event per run. Contact enrichment is an additional event charge and is not guaranteed to find contact details for every place. Keep `includeContacts` disabled when you only need standard business data. Check the Actor's **Pricing** tab for the latest rates before starting a large run.

***

### Other Google Scraping Tools

If you like this Actor, you might also find these Google tools useful:

- 🔎 **[Google Search Scraper](https://apify.com/api-ninja/google-search-scraper)**: Extract localized organic Google Search results and related keywords.
- ⭐ **[Google Maps Reviews Scraper](https://apify.com/api-ninja/google-maps-reviews-scraper)**: Collect review text, ratings, authors, and review metadata.
- 📸 **[Google Maps Photo Scraper](https://apify.com/api-ninja/google-maps-photo-scraper)**: Extract photos and videos associated with Google Maps places.

***

### FAQ

**Q: Is this a Google Maps API alternative?**\
A: Yes, this actor provides an alternative way to access Google Maps data without the constraints of the official API's rigorous rate limits, specifically useful for bulk data collection.

**Q: Do I need proxies to scrape Google Maps?**\
A: No, you don't need to configure proxies manually. The Apify platform handles proxy rotation and management automatically to ensure reliable extraction.

**Q: Can I use this with no coding via the UI?**\
A: Absolutely. The Actor is designed to be used directly from the Apify Console with a user-friendly interface. No coding skills are required.

**Q: The Actor returned fewer results than I expected – what can I do?**\
A: Try enabling `scrapeAllPlaces` to force a deeper grid search, or break your location down into smaller areas (e.g., search by ZIP code instead of the whole city). Also, ensure `maxResultCount` is high enough.

**Q: My run is timing out or using too many CUs – how do I optimize?**\
A: Reduce the size of your search area or use more specific keywords. If you are scraping a huge area, consider splitting it into multiple runs.

**Q: Can I get email addresses?**\
A: Yes, if you enable `includeContacts`. Unique businesses are enriched with emails/social/contact links in `emails_and_contacts`. Availability is not guaranteed for every place.

***

### Support

If you encounter any issues or have feature requests:

- **Issues**: Please use the **Issues** tab on the Actor page to report bugs or request new features.
- **Email**: apify@dziura.online

***

### License

Apache License 2.0

# Actor input Schema

## `textQuery` (type: `string`):

Business keyword or category to search for, such as 'best pizza', 'hotels', or 'plumbers'. Either Search Query or Location must be provided.

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

City, region, address, or country to search, such as 'New York, NY' or 'Kyiv, Ukraine'. When no explicit coordinates are supplied, the Actor geocodes this location into a bounding box.

## `includeContacts` (type: `boolean`):

Extract emails and social profile links from each business website. This takes longer, may return no contacts for some businesses, and applies an additional per-result contact-enrichment charge.

## `maxResultCount` (type: `integer`):

Maximum number of unique businesses to save. Ignored when Scrape All Places is enabled.

## `scrapeAllPlaces` (type: `boolean`):

Search the full resolved area using recursive subdivision. This can use substantially more provider credits and ignores Maximum Results.

## `subtypes` (type: `array`):

Optional business categories such as 'Pizza restaurant', 'Hotel', or 'Plumber'.

## `verified` (type: `boolean`):

Return only businesses marked as verified.

## `businessStatus` (type: `array`):

Restrict results to one or more business statuses.

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

Optional center latitude. Must be supplied together with Center Longitude.

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

Optional center longitude. Must be supplied together with Center Latitude.

## `radiusMeters` (type: `integer`):

Radius around the center coordinates. Defaults to 25,000 meters.

## `north` (type: `number`):

Northern latitude of an exact bounding box (-90 to 90). Must be greater than south. Supply all four bounding-box values or leave all four empty. Reversed coordinates are rejected, not automatically swapped.

## `south` (type: `number`):

Southern latitude of an exact bounding box (-90 to 90). Must be less than north. Example: north 40.78, south 40.12.

## `east` (type: `number`):

Eastern longitude of an exact bounding box (-180 to 180). Must be greater than west. With negative longitudes, the less negative value is farther east: east -71.85, west -72.72. Boxes crossing 180 degrees longitude are not supported.

## `west` (type: `number`):

Western longitude of an exact bounding box (-180 to 180). Must be less than east. Example: west -72.72, east -71.85.

## `resultsPerRequest` (type: `integer`):

Advanced. Lower values trigger subdivision sooner and can improve coverage, but use more requests. The recommended default is 100.

## `maxDepth` (type: `integer`):

Advanced. Maximum recursive subdivision depth. Higher values can improve dense-area coverage but greatly increase usage.

## `maxAreas` (type: `integer`):

Safety ceiling for area requests, especially during exhaustive searches. Increase carefully because provider usage is metered.

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

Two-letter ISO 639-1 language code for returned data, such as 'en', 'uk', 'de', or 'fr'.

## `regionCode` (type: `string`):

Optional two-letter ISO 3166-1 country code used to bias the search, such as 'US', 'UA', 'DE', or 'FR'. When Location is geocoded, its country code is used automatically.

## Actor input object example

```json
{
  "textQuery": "Best pizza",
  "location": "New York, NY",
  "includeContacts": false,
  "maxResultCount": 40,
  "scrapeAllPlaces": false,
  "radiusMeters": 25000,
  "resultsPerRequest": 100,
  "maxDepth": 8,
  "maxAreas": 2000,
  "languageCode": "en"
}
```

# 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 = {
    "textQuery": "Best pizza",
    "location": "New York, NY"
};

// Run the Actor and wait for it to finish
const run = await client.actor("api-ninja/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 = {
    "textQuery": "Best pizza",
    "location": "New York, NY",
}

# Run the Actor and wait for it to finish
run = client.actor("api-ninja/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 '{
  "textQuery": "Best pizza",
  "location": "New York, NY"
}' |
apify call api-ninja/google-maps-scraper --silent --output-dataset

```

## MCP server setup

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