# Google Maps Scraper (`boneswill/google-maps-scraper`) Actor

🔥 Affordable way to scrape Google Maps business listings, contact info, ratings, reviews, hours & photos. Search by term or direct URL input. ⭐📞📍

- **URL**: https://apify.com/boneswill/google-maps-scraper.md
- **Developed by:** [succexx\_DEV](https://apify.com/boneswill) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 pay per events

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 🗺️ Google Maps Listings Scraper

Extract **verified business data** from Google Maps at scale — no browser, no API key, no limits on what you can search.

> Collect business name, category, address, phone, website, rating, review count, coordinates, opening hours, and description — clean structured JSON ready for lead generation, market research, CRM enrichment, or automation pipelines.

***

### ⚡ WHY THIS SCRAPER?

Most Google Maps scrapers are slow, unreliable, or burn through expensive API credits. This one hits Google's **internal data endpoints directly** — the same ones the Maps app uses — so it's:

- **Fast** — no browser rendering, pure HTTP requests
- **Lightweight** — runs on minimal memory (256 MB)
- **Scalable** — scrape hundreds or thousands of places per run
- **Structured** — outputs clean JSON ready for any downstream tool

***

### ✅ WHAT YOU GET

Every scraped place includes:

| Field | Description |
|---|---|
| `placeId` | Unique Google Maps place identifier |
| `title` | Business name |
| `category` | Primary business category |
| `categories` | All associated categories |
| `address` | Full formatted street address |
| `phone` | Business phone number |
| `website` | Official website URL |
| `rating` | Average star rating (1.0–5.0) |
| `reviewsCount` | Total number of reviews |
| `location` | Latitude & longitude coordinates |
| `description` | Business description or editorial summary |
| `openingHours` | Hours for each day of the week |
| `imageUrl` | Featured place photo URL |
| `googleMapsUrl` | Direct link to the place on Google Maps |
| `scrapedAt` | ISO timestamp of when data was collected |

***

### 💡 USE CASES

#### 🏆 Sales & Lead Generation

Build targeted B2B or B2C contact lists with verified phone numbers and websites. Search by business type and city to find prospects in any market.

#### 📊 Market Research

Map competitor density across neighbourhoods. Compare ratings, review counts, and categories to spot market gaps and opportunities.

#### 🏘️ Real Estate & Site Selection

Analyse local amenities near a property — restaurants, schools, gyms, clinics. Pull coordinates and hours to enrich location intelligence reports.

#### 🤖 App Development & Automation

Feed structured place data into CRMs, chatbots, recommendation engines, dashboards, or any custom pipeline that needs reliable business data.

#### 📈 Reputation Monitoring

Track ratings and review counts for your own locations or competitors over time. Schedule recurring runs to detect changes.

#### 🗂️ Directory Building

Build niche business directories for specific industries, cities, or categories — restaurants, lawyers, plumbers, gyms, and more.

***

### 🚀 HOW TO USE

#### Option 1 — Search Mode (recommended)

1. Enter a **Search Term** (e.g. `dentist`, `coffee shop`, `hotel`)
2. Enter a **Location** (e.g. `Lagos, Nigeria`, `London, UK`, `New York, USA`)
3. Set **Max Places**
4. Click **Run Actor**

#### Option 2 — URL Mode

1. Paste one or more Google Maps URLs into the **URL** field
2. Supported formats:
   - Place pages: `https://www.google.com/maps/place/...`
   - Search pages: `https://www.google.com/maps/search/...`
3. Leave Search Term empty and click **Run Actor**

***

### 🔗 URL EXAMPLES

```
## Search page — scrapes all results for that query
https://www.google.com/maps/search/restaurants+in+Lagos

## Place page — scrapes a single specific business
https://www.google.com/maps/place/Eiffel+Tower/@48.8584,2.2945,17z/data=!...

## Multiple URLs — paste one per line in the URL field
https://www.google.com/maps/place/Joe%27s+Coffee/@40.7128,-74.006,17z
https://www.google.com/maps/place/Blue+Bottle+Coffee/@37.7749,-122.418,17z
```

***

### ⚙️ CONFIGURATION

| Parameter | Type | Description | Default |
|---|---|---|---|
| `url` | array | Google Maps URLs to scrape directly | `[]` |
| `searchTerm` | string | What to search for (e.g. `coffee shop`) | `coffee shop` |
| `locationQuery` | string | Where to search (e.g. `New York, USA`) | `New York, USA` |
| `language` | string | Language code for results (`en`, `fr`, `es`, `de`) | `en` |
| `countryCode` | string | Two-letter country code (`us`, `gb`, `ng`, `ca`) | `us` |
| `maxPlaces` | integer | Maximum number of places to collect | `20` |
| `scrapePlaceDetails` | boolean | Fetch phone, hours, and description for each place | `true` |
| `scrapeReviews` | boolean | Collect individual reviews per place | `false` |
| `maxReviewsPerPlace` | integer | Max reviews per place (when reviews enabled) | `50` |
| `reviewsSort` | string | Sort order: `relevant`, `newest`, `highest`, `lowest` | `relevant` |

***

### 📊 SAMPLE OUTPUT

```json
[
  {
    "placeId": "0x89c25855c6f1ff69:0x53c665ceee9c09d9",
    "title": "Joe's Coffee",
    "category": "Coffee shop",
    "categories": ["Coffee shop", "Café"],
    "address": "123 Main St, New York, NY 10001, USA",
    "phone": "+1 212-555-0123",
    "website": "https://www.joescoffee.com",
    "rating": 4.6,
    "reviewsCount": 1284,
    "location": { "lat": 40.7128, "lng": -74.0060 },
    "description": "Cozy neighbourhood café serving specialty coffee and pastries since 1996.",
    "openingHours": {
      "Monday": "7 AM-7 PM",
      "Tuesday": "7 AM-7 PM",
      "Wednesday": "7 AM-7 PM",
      "Thursday": "7 AM-7 PM",
      "Friday": "7 AM-8 PM",
      "Saturday": "8 AM-8 PM",
      "Sunday": "9 AM-6 PM"
    },
    "imageUrl": "https://lh3.googleusercontent.com/gps-cs-s/...",
    "googleMapsUrl": "https://www.google.com/maps/place/?q=place_id:0x89c25...",
    "scrapedAt": "2026-06-20T10:32:11.000Z"
  }
]
```

***

### 🔁 GETTING MORE THAN 20 RESULTS

Google Maps caps a single search at ~20 places. To collect more:

- **Run multiple searches** — use different search terms for the same area (e.g. `coffee shop Manhattan`, `café Manhattan`, `espresso bar Manhattan`)
- **Split by neighbourhood** — search `coffee shop Midtown`, `coffee shop Brooklyn`, `coffee shop Harlem` separately
- **Use the URL field** — paste multiple specific place URLs to scrape them directly regardless of search limits
- **Increase Max Places** — the actor will attempt to collect up to your limit before stopping

***

### 🌍 SUPPORTED LOCATIONS

Works for any location worldwide. Just enter the city, region, or country in the **Location** field. Examples:

- `New York, USA` · `London, UK` · `Lagos, Nigeria`
- `Paris, France` · `Dubai, UAE` · `Sydney, Australia`
- `Toronto, Canada` · `Berlin, Germany` · `Tokyo, Japan`

Pair with the matching `countryCode` (e.g. `ng` for Nigeria, `gb` for UK) for most accurate results.

***

### 💰 PRICING

| Plan | Places Included | Rate After |
|---|---|---|
| **Free Tier** | 50 places/month | — |
| **Pay Per Use** | Unlimited | $2.70 per 1,000 places |

Billing is per place successfully scraped. Failed or skipped places are not charged.

***

### ⚠️ LIMITATIONS

- **Opening hours** — Google's API returns today's hours only. The scraper fills remaining days based on available data with a note that hours may vary.
- **Review count** — not always available from the API; estimated from rating when missing.
- **Search results** — capped at ~20 per query by Google. Use multiple queries to get more.
- **Dynamic content** — some place details only load in a full browser; this scraper uses HTTP only for speed.

***

### 🛠️ TECHNICAL NOTES

- Built on **Crawlee BasicCrawler** — efficient, retry-aware, and concurrency-controlled
- Uses Google Maps' **internal JSON endpoints** with proper anti-detection headers
- **Proxy rotation** via Webshare residential proxies for reliability at scale
- Output is pushed to Apify's **default dataset** — exportable as JSON, CSV, or Excel

***

### 📬 SUPPORT

Having issues or need a custom feature? Reach out:

- 📧 **Email:** boneswill697@gmail.com
- 🐛 **Bugs:** Open an issue in the **Issues** tab

We respond within 24 hours.

# Actor input Schema

## `url` (type: `array`):

Paste one or more Google Maps URLs — place pages (https://www.google.com/maps/place/...) or search pages (https://www.google.com/maps/search/...). Leave empty to use Search Term + Location instead.

## `searchTerm` (type: `string`):

What to search for — e.g. 'coffee shop', 'dentist', 'hotel'. Leave empty if using URLs.

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

Where to search — e.g. 'New York, USA', 'Lagos, Nigeria', 'London, UK'.

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

Language code for results — e.g. 'en', 'fr', 'es'.

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

Two-letter country code to bias results — e.g. 'us', 'gb', 'ng'.

## `maxPlaces` (type: `integer`):

Maximum number of places to scrape. A single Maps search returns up to ~150-200 unique results before plateauing — to get more, the Actor automatically fans out into sub-queries by region.

## `scrapePlaceDetails` (type: `boolean`):

Visit each place's detail page to collect phone number, opening hours, and business description. Slightly slower but gives you a complete lead profile.

## `scrapeReviews` (type: `boolean`):

Also collect individual customer reviews for each place.

## `maxReviewsPerPlace` (type: `integer`):

Maximum number of reviews to collect per place. Only applies when 'Scrape Reviews' is enabled.

## `reviewsSort` (type: `string`):

How to sort reviews when scraping them.

## Actor input object example

```json
{
  "url": [],
  "searchTerm": "coffee shop",
  "locationQuery": "New York, USA",
  "language": "en",
  "countryCode": "us",
  "maxPlaces": 100,
  "scrapePlaceDetails": true,
  "scrapeReviews": false,
  "maxReviewsPerPlace": 50,
  "reviewsSort": "relevant"
}
```

# Actor output Schema

## `overview` (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 = {
    "url": [],
    "searchTerm": "coffee shop",
    "locationQuery": "New York, USA",
    "language": "en",
    "countryCode": "us",
    "reviewsSort": "relevant"
};

// Run the Actor and wait for it to finish
const run = await client.actor("boneswill/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 = {
    "url": [],
    "searchTerm": "coffee shop",
    "locationQuery": "New York, USA",
    "language": "en",
    "countryCode": "us",
    "reviewsSort": "relevant",
}

# Run the Actor and wait for it to finish
run = client.actor("boneswill/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 '{
  "url": [],
  "searchTerm": "coffee shop",
  "locationQuery": "New York, USA",
  "language": "en",
  "countryCode": "us",
  "reviewsSort": "relevant"
}' |
apify call boneswill/google-maps-scraper --silent --output-dataset

```

## MCP server setup

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