# Google Maps Scraper API — Emails, Reviews, Photos & Leads (`pro100chok/google-maps-scraper`) Actor

Google Maps scraper and Google Places API alternative: extract business names, phones, websites, hours, ratings and reviews — plus emails and 7 social profiles pulled from each place's website. Bypass Google's 120-place limit. Export JSON, CSV, Excel. From $3/1k places, no API key.

- **URL**: https://apify.com/pro100chok/google-maps-scraper.md
- **Developed by:** [Raven](https://apify.com/pro100chok) (community)
- **Categories:** Lead generation, E-commerce, Travel
- **Stats:** 64 total users, 30 monthly users, 99.6% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.90 / 1,000 place scrapeds

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/platform/actors/running/actors-in-store#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 Scraper — Emails, Reviews & Contact Details

**Extract data from thousands of Google Maps places** — business name, category, full address, phone number, website, opening hours, rating, reviews, and images — and **enrich every place with emails and social media profiles** pulled from its website. Export to Excel, CSV, JSON, or HTML, run via API, schedule and monitor runs, or integrate with your favorite tools. No code, no Google Maps API key, no daily quotas.

🚀 Build a lead list of any local business in any city in minutes — every barbershop in Berlin, every dentist in Texas, every coffee shop in Tokyo — with the **owner's email already extracted** from their website.

### 📍 What is Google Maps Scraper?

Google Maps Scraper is a no-code web scraping tool that extracts business data from Google Maps at scale. Give it a search term (for example `barber shop`, `dental clinic`, or `coffee`) plus a location, and it returns every matching place with full contact details — names, addresses, phone numbers, websites, ratings, reviews, opening hours, and photos — then enriches each place with **emails and social links** scraped from its website.

It's a flexible, affordable **Google Places API alternative**: no per-request key, no small result caps, and no complicated setup — just the business data you actually need, ready to export.

### 🎯 What can you do with it?

- 🧲 **Lead generation** — build targeted B2B lists with verified emails and phone numbers for cold outreach
- 📍 **Local SEO & GMB audits** — competitor analysis, listing monitoring, and NAP citation building
- 🍽️ **Market research** — analyze competitor density, ratings, and reviews in any area
- 🛒 **Franchise & market-entry research** — map every competitor in a region with full contact details
- 🤖 **AI / LLM pipelines** — clean, structured business data for downstream models
- 📊 **Real-estate & retail scouting** — find the right neighborhood by category density

### 📦 What data does Google Maps Scraper extract?

| Group | Fields |
|---|---|
| **Identification** | `name`, `place_id`, `google_maps_url`, `category`, `categories[]`, `description` |
| **Address** | `address` (full), `city`, `state`, `zip_code`, `country_code` (ISO-2), `area` (neighborhood), `plus_code` |
| **Coordinates** | `latitude`, `longitude` |
| **Contact** | `phone`, `website`, `email` (primary), `emails[]` (all found) |
| **Social profiles** | `facebook`, `instagram`, `twitter`, `linkedin`, `youtube`, `tiktok`, `telegram` |
| **Reputation** | `rating` (0–5), `reviews_count`, `price_level` (`$`–`$$$$`) |
| **Status** | `permanently_closed`, `temporarily_closed` |
| **Hours** | `opening_hours` (full 7-day schedule) |
| **Reviews** (add-on) | `reviews[]` — `text`, `rating`, `author`, `publishedAt`, `authorAvatar`, `authorProfileUrl`, `authorId`, `reviewId`, `photos[]` |
| **Images** (add-on) | `images[]` — direct image URLs (no binaries, just links) |

### ⚡ Why this Google Maps Scraper

- ✅ **Emails included in the base price** — every place with a website is enriched with business emails. Most competing scrapers charge this as a separate add-on
- ✅ **Bypass Google's 120-place limit** — turn on `deepSearch` and the scraper splits any city into sub-areas to return thousands of places per search term
- ✅ **Full Google reviews** — pull reviews per place with text, rating, author, date, and photos
- ✅ **7 social networks auto-extracted** — Facebook, Instagram, X (Twitter), LinkedIn, YouTube, TikTok, and Telegram links from each place's website
- ✅ **International-ready** — accurate address parsing worldwide: ISO-2 country code, city, state, postal code, and neighborhood, all separated cleanly
- ✅ **No code + full API** — run from the UI, or via API in Python and Node.js, with scheduling, webhooks, and integrations
- ✅ **Export anywhere** — Excel, CSV, JSON, or HTML; results stream in real time
- ✅ **Pay only for results** — transparent pay-per-event pricing, no subscription, no minimum spend

### 💰 How much does it cost?

**From $3 / 1,000 places — with emails included.** This scraper uses Apify's **pay-per-event** pricing, so you only pay for what you actually extract:

| Event | When you pay | Price (USD) |
|---|---|---|
| **`place`** | One place pushed to the dataset | **$0.003** |
| **`contact`** | A unique email enriched from a website | **$0.002** |
| **`review`** | One review attached to a place (when `includeReviews` is on) | **$0.0005** |
| **`image`** | One image URL attached (when `includeImages` is on) | **$0.0002** |

**Real-world cost examples:**

- 🏪 **1,000 barbershops with emails** → 1,000 × $0.003 + ~400 unique emails × $0.002 ≈ **$3.80**
- 🍽️ **100 restaurants + 50 reviews each + 20 photos each** → $0.30 + $2.50 + $0.40 ≈ **$3.20**
- 🌆 **Full coverage of a mid-size city (3,000 places)** → ~$10

Cap any run with **Default run options → Max total charge** so you never overspend. Duplicate emails are charged once per run, and junk/placeholder emails (`noreply@`, `example.com`, etc.) are filtered out before billing.

#### Why pay-per-event pricing?

You pay for concrete results — places, emails, reviews, images — not for compute time or opaque "credits." A run that returns 500 places costs the same whether it takes one minute or ten, so pricing is predictable and easy to budget.

### 🚀 How do I use Google Maps Scraper?

No coding required:

1. Click **Try for free** and open the input form.
2. Enter one or more **search terms** (e.g. `coffee shop`) and a **location** (e.g. `Berlin, Germany`).
3. (Optional) Turn on **deep search**, reviews, or images, and set your limits.
4. Click **Start** and watch results fill in live.
5. **Export** to Excel, CSV, JSON, or HTML — or pull the data via API.

### ⬇️ Input

| Field | Type | Default | Description |
|---|---|---|---|
| 🔍 `searchStringsArray` | array | — | Search terms, one per line (e.g. `barber shop`, `dental clinic`) |
| 📍 `locationQuery` | string | — | Free-text location, e.g. `Washington, DC` or `Berlin, Germany` |
| 🏙️ `city` / 🗺️ `state` / 🌍 `country` | string | — | Optional structured location fields |
| 🧮 `maxItems` | integer | `100` | Hard cap on total results across all terms and locations — you're never charged past it. Empty = no limit |
| 🌐 `deepSearch` | boolean | `false` | Split the area into sub-areas to get past Google's ~120-place limit per search |
| 🏷️ `categoryFilter` | string | — | Keep only places whose category matches (e.g. `Barber shop`) |
| 🗣️ `language` | select | `en` | Google interface language |
| 🚩 `countryCode` | string | `us` | 2-letter country code for geolocation and currency |
| 📧 `scrapeContactsFromWebsite` | boolean | `true` | Extract emails + social links from each place's website |
| 📭 `skipPlacesWithoutEmail` | boolean | `false` | Lead-list mode — output only places with an email |
| 🔁 `skipDuplicateEmails` | boolean | `true` | Keep only the first place per email address — booking platforms put one shared mailbox on dozens of listings |
| 💬 `includeReviews` | boolean | `false` | **Add-on**. Attach reviews per place (text, rating, author, date, photos) |
| 🔢 `maxReviewsPerPlace` | integer | `20` | Cap reviews per place (1–5000) |
| 🖼️ `includeImages` | boolean | `false` | **Add-on**. Attach photo URLs per place |
| 🔢 `maxImagesPerPlace` | integer | `20` | Cap images per place (1–200) |
| ⚡ `concurrency` | integer | `3` | Parallel Google sessions, each on its own IP |

#### 🟢 Quick example — every barbershop in Berlin with emails

```json
{
  "searchStringsArray": ["barber shop"],
  "locationQuery": "Berlin, Germany",
  "maxItems": 500,
  "deepSearch": true,
  "scrapeContactsFromWebsite": true
}
```

#### 🟡 Example — restaurants in NYC with full review history

```json
{
  "searchStringsArray": ["italian restaurant", "ramen", "steakhouse"],
  "locationQuery": "New York, NY",
  "maxItems": 100,
  "includeReviews": true,
  "maxReviewsPerPlace": 200,
  "includeImages": true,
  "maxImagesPerPlace": 30
}
```

### ⬆️ Output

Every place is one row/record. View results in the **table** or **JSON** tab, or export to Excel, CSV, JSON, or HTML.

```jsonc
{
  "place_id": "ChIJZW3FhdK3t4kRLXEtK4yueuE",
  "name": "Scissors & Scotch",
  "category": "Barber shop",
  "categories": ["Barber shop"],
  "address": "331 N St NE, Washington, DC 20002, USA",
  "city": "Washington",
  "state": "DC",
  "zip_code": "20002",
  "country_code": "US",
  "area": "Near Northeast",
  "plus_code": "WX4X+PH",
  "latitude": 38.9068,
  "longitude": -77.001,
  "phone": "(202) 481-2850",
  "website": "https://scissorsscotch.com/",
  "email": "info@scissorsscotch.com",
  "emails": ["info@scissorsscotch.com", "dc@scissorsscotch.com"],
  "facebook": "https://www.facebook.com/scissorsscotch",
  "instagram": "https://www.instagram.com/scissorsscotch/",
  "twitter": "https://twitter.com/scissorsscotch",
  "rating": 4.7,
  "reviews_count": 1422,
  "price_level": "$$",
  "permanently_closed": false,
  "temporarily_closed": false,
  "opening_hours": "Monday: 9 AM–8 PM | Tuesday: 9 AM–8 PM | Wednesday: 9 AM–8 PM | Thursday: 9 AM–8 PM | Friday: 9 AM–7 PM | Saturday: 9 AM–7 PM | Sunday: 10 AM–5 PM",
  "google_maps_url": "https://www.google.com/maps/search/?api=1&query=Scissors+%26+Scotch&query_place_id=ChIJZW3FhdK3t4kRLXEtK4yueuE",
  "reviews": [
    {
      "rating": 5,
      "text": "Best haircut I've had in DC. Stylist took time to understand what I wanted...",
      "publishedAt": "2 months ago",
      "author": "Mike Visalli",
      "authorAvatar": "https://lh3.googleusercontent.com/a/...",
      "authorProfileUrl": "https://www.google.com/maps/contrib/111279794912534073117?hl=en-US",
      "authorId": "111279794912534073117",
      "reviewId": "ChdDSUhNMG9...",
      "photos": ["https://lh3.googleusercontent.com/grass-cs/..."]
    }
  ],
  "images": [
    "https://lh3.googleusercontent.com/grass-cs/...",
    "https://lh3.googleusercontent.com/grass-cs/..."
  ],
  "search_query": "barber shop",
  "search_location": "Washington, DC",
  "scraped_at": "2026-05-12T10:15:30+00:00"
}
```

### 🌍 Languages & countries

Search in English, Spanish, French, German, Italian, Portuguese, Russian, Ukrainian, Polish, Turkish, Dutch, Japanese, Korean, and Chinese (Simplified). Address parsing is tested across 60+ countries — US, EU (DE/FR/IT/ES/NL/PL), UK, CIS (RU/UA/BY/KZ), Turkey, Japan, Brazil, and Mexico — with ISO-2 country codes auto-detected.

### ❓ Frequently asked questions

**How does Google Maps Scraper work?**
You enter one or more search terms and a location. The scraper searches Google Maps just like a person would, collects every matching business, and for each place with a website it also visits that site to pull emails and social profiles. Results stream into your dataset as they're found.

**What are the disadvantages of the Google Maps API?**
The official Google Places API requires an API key and billing, caps results (for example a maximum of 5 reviews per place with no pagination), limits how many places you can pull per query, and doesn't return emails or social profiles at all. This scraper has no key, higher limits, and enriches each place with contact data Google's API never exposes.

**Can I scrape places from multiple locations at once?**
Yes. Add multiple search terms, and combine with `deepSearch` to cover an entire city or region and get past Google's ~120-place limit per area.

**Can I extract Google Maps reviews?**
Yes — enable `includeReviews` to attach reviews per place with text, rating, author, date, and photos, up to your `maxReviewsPerPlace` cap.

**Can I get emails and phone numbers for lead generation?**
Yes. Phone numbers come straight from Google Maps, and emails plus social links are extracted from each place's website — included in the base price. Turn on `skipPlacesWithoutEmail` for a clean lead list.

**Can I integrate Google Maps Scraper with other apps?**
Yes. Connect it to Make, Zapier, Google Sheets, Slack, and more, or trigger runs and pull data with webhooks and the Apify API.

**Can I use Google Maps Scraper as its own API, in Python or Node.js?**
Yes. Every run and dataset is available through the Apify API, with ready-made Python and JavaScript client libraries, a CLI, and an MCP server.

**Is it legal to scrape Google Maps data?**
Scraping publicly available business data is generally legal. This scraper only collects public information (names, addresses, phones, public websites, ratings, and reviews). You are responsible for how you use the data and for complying with applicable laws such as GDPR/CCPA.

### 📞 Support & feedback

Found a bug or need a feature? Email **africanec@gmail.com** — usually fixed and redeployed within 24 hours.

To speed up debugging you can share run data with the developer: [Apify Security Settings](https://console.apify.com/settings/security) → **"Share run data with developers"** → enable for this Actor.

# Actor input Schema

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

What to search on Google Maps — one term per line. Examples: `barber shop`, `coffee`, `dental clinic`.

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

Where to search. Free-text like `Washington, DC` or `Berlin, Germany`. Leave empty if you fill the structured fields below.

## `city` (type: `string`):

Optional — combined with state/country into a single location string.

## `state` (type: `string`):

Optional — US state or other top-level region (e.g. `CA`).

## `country` (type: `string`):

Optional — full country name, e.g. `USA`, `Germany`.

## `maxItems` (type: `integer`):

Hard cap on how many places the run returns in total, across ALL search terms and locations. The actor stops as soon as it has this many — you are never charged for extras. Leave empty to keep going until Google runs out of results.

## `deepSearch` (type: `boolean`):

When a result page saturates (≥20 items), recursively split the area into sub-areas to bypass the 120-place cap. Slower but much wider coverage.

## `categoryFilter` (type: `string`):

Optional. Keep only places whose category contains this string (case-insensitive), e.g. `Barber shop`.

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

Google interface language for the search.

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

Google geolocation hint — 2-letter ISO code. Affects ranking, results, and currency.

## `scrapeContactsFromWebsite` (type: `boolean`):

For every place that has a website, fetch homepage + contact pages and extract emails plus Facebook / Instagram / X / LinkedIn / YouTube / TikTok / Telegram links.

## `skipPlacesWithoutEmail` (type: `boolean`):

Only push places where an email was found (useful for lead lists).

## `skipDuplicateEmails` (type: `boolean`):

Keep only the first place for each email address. Booking platforms and website templates put one shared address (e.g. `support@platform.com`) on dozens of listings — this drops those repeats so you don't pay for the same lead twice. Places with no email are never affected.

## `includeReviews` (type: `boolean`):

Attach user reviews per place — text, rating, author, date, and attached photos. Paginates through Google's review API, so you get the full review history (up to your cap below). Billed per review extracted — see pricing.

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

Hard cap on reviews attached to one place. The actor paginates Google's review API (~10 reviews per page) until it hits this cap or runs out of reviews.

## `includeImages` (type: `boolean`):

Attach photo URLs to each place. Sources: 3-5 thumbnails from the search response + user-submitted photos from reviews (works only together with 💬 includeReviews). Higher review limit → more photos. Billed per image.

## `maxImagesPerPlace` (type: `integer`):

Hard cap on photo URLs attached to one place.

## `maxRetries` (type: `integer`):

Retries on transient network failures before giving up on a request.

## `concurrency` (type: `integer`):

Google sessions running in parallel (each on its own IP). Higher = faster, but heavier load on Google.

## Actor input object example

```json
{
  "searchStringsArray": [
    "barber shop"
  ],
  "locationQuery": "New York, NY",
  "maxItems": 100,
  "deepSearch": false,
  "language": "en",
  "countryCode": "us",
  "scrapeContactsFromWebsite": true,
  "skipPlacesWithoutEmail": false,
  "skipDuplicateEmails": true,
  "includeReviews": false,
  "maxReviewsPerPlace": 20,
  "includeImages": false,
  "maxImagesPerPlace": 20,
  "maxRetries": 5,
  "concurrency": 3
}
```

# Actor output Schema

## `dataset` (type: `string`):

All scraped places pushed to the dataset.

## `overview` (type: `string`):

No description

## `contacts` (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 = {
    "searchStringsArray": [
        "barber shop"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("pro100chok/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": ["barber shop"] }

# Run the Actor and wait for it to finish
run = client.actor("pro100chok/google-maps-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "barber shop"
  ]
}' |
apify call pro100chok/google-maps-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=pro100chok/google-maps-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/w0yugQzf3ETbRbAC2/builds/hFUZOmUOxoA7bKFjD/openapi.json
