# Google Map Scraper (`insights_data/google-map-scraper`) Actor

Scrape Google Maps places by keyword, link or place ID. Get name, category, address, phone, website, rating, reviews, hours, coordinates and lead flags like no website or low rating as clean JSON. Bulk input, live results, no API key or login needed.

- **URL**: https://apify.com/insights_data/google-map-scraper.md
- **Developed by:** [Insights Data](https://apify.com/insights_data) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

### 🗺️ What is Google Map Scraper?

**Google Map Scraper** turns a Google Maps search into a ready list of local business leads, with the phone, website, address, rating and opening hours that Google Maps shows for each place. Sales teams, marketing agencies and market researchers use it for Google Maps lead generation and competitor checks instead of copying listings by hand.

Just type a keyword such as `dentist`, add a city, and click **Start**. You can try it with the $5 monthly credit of the Apify Free plan. This Google Maps scraper also accepts Google Maps links and place ids, works without a Google account or API key, and saves each place to your results the moment it is ready. It turns Google Maps business listings into clean rows you can sort, filter and export.

- 🎯 **Build local lead lists:** get the name, phone, website and full address of dentists, gyms or restaurants in a city, ready for B2B lead generation and outreach by phone or through the business website (no email addresses are included).
- 🚩 **Find sales prospecting targets:** every place comes with lead signals such as `no_website`, `few_reviews` or `unclaimed`, so you can spot businesses without websites or with weak listings in seconds.
- 📊 **Run Google Maps competitor analysis:** compare ratings, review counts, categories and opening hours of competitors in an area. Turn on place details for the star-by-star rating breakdown and review topics.
- 🧭 **Do market research:** map the places of a category in a city or region, with coordinates, neighborhoods and postal codes.
- 📌 **Check local SEO:** see which listings are unclaimed, which categories they use, and how their rating compares with the area.
- 🤖 **Feed your tools:** send the structured rows to Google Sheets, a CRM, a dashboard or an AI agent.

#### What can Google Map Scraper do?

- 🔍 **Search by keyword and location**, by Google Maps search link, place link, place id or short map link, with many entries in one run
- 🎚️ **Filter places** by category words, minimum star rating, with or without a website, and open or closed
- 🚩 **Add lead signals** to every place: no website, no phone, low rating (below 4.0), few reviews (below 10), closed, unclaimed
- 🧬 **Add place details** on request: rating breakdown, review topics, amenities and attributes, photos and owner posts
- 🗂️ **Get extra tables** for opening hours, rating breakdown, review topics, amenities, photos, owner posts, searches and failed inputs, at no extra charge
- 📦 **Export** to JSON, CSV, Excel, XML or HTML, run it via API, schedule it, and connect it to Make, Zapier, n8n or Google Sheets

***

### 📋 Google Map Scraper data: what you can extract

Every run returns the same Google Maps data structure: one row per place in the main **Places** table. As a Google Maps places scraper, it collects these fields (names as in the dataset):

| Field group | Fields |
|---|---|
| 🏷️ Name and category | `title`, `categoryName`, `categories`, `description` |
| 📍 Address and location | `address`, `street`, `city`, `state`, `postalCode`, `countryCode`, `neighborhood`, `location` (lat, lng), `timezone` |
| ☎️ Phone | `phone`, `phoneUnformatted` (international format) |
| 🌐 Website | `website`, `domain` |
| ⭐ Rating | `totalScore`, `reviewsCount`, `reviewsLink` |
| 🕒 Hours and status | `openStatus`, `openingHours`, `permanentlyClosed`, `temporarilyClosed`, `claimThisBusiness` |
| 🚩 Lead signals | `opportunity` (`no_website`, `no_phone`, `low_rating`, `few_reviews`, `closed`, `unclaimed`) |
| 📸 Photos | `imageUrl` (main photo); `imageUrls` with place details |
| 🆔 IDs and links | `placeId`, `cid`, `fid`, `kgmid`, `url`, `searchPageUrl`, `rank`, `scrapedAt` |
| 🧬 Place details (optional) | `ratingBreakdown`, `reviewTopics`, `additionalInfo` (amenities), `imageUrls`, `ownerPosts` |

Phone numbers come in two formats, the one shown on Google Maps and the international one, which is what most people want from a Google Maps phone number scraper.

> **Note:** a field is `null` (or an empty list) when Google Maps doesn't show it for a place, for example a description or a website. The place-details fields only appear in the rows when **Place details** is on. `claimThisBusiness` is `true` when the listing still shows a claim link, which is how you find unclaimed Google business listings.

#### What data can't Google Map Scraper extract?

- Email addresses and social media profiles
- Review texts, reviewer names and review dates (you get review counts, the rating breakdown and review topics)
- Questions and answers, popular times, menus and booking links

For the reviews themselves, use [Google Map Review Scraper](https://apify.com/insights_data/google-map-review-scraper). It returns rating, text, author, date and owner replies for any place.

***

### 🚀 How to scrape Google Maps

This Google Maps scraper tool is designed for an easy start, even if you've never tried to scrape Google Maps data before.

1. [Create a free Apify account](https://console.apify.com/sign-up) using your email.
2. Open [Google Map Scraper](https://apify.com/insights_data/google-map-scraper).
3. Add a keyword, a Google Maps link or a place id in **Search terms and Maps links** (one per line), and type a city in **Location**.
4. Click **Start** and watch the places appear in the **Output** tab while the run is going.
5. Download your data from **Storage → Datasets → Export** in JSON, CSV, Excel, XML or HTML.

#### First run checklist

> 💡 **Before you click Start**
>
> - Type one keyword per line in **Search terms and Maps links**, for example `dentist`.
> - Type one city in **Location**, for example `New York, USA`. For a city outside the USA, also set **Country**.
> - Leave **Places per search** at 10. Each keyword then saves up to 10 places, which is at most $0.02 per keyword in result charges on the Free plan, plus the start fee and platform usage.
> - Optional: set a maximum charge limit in **Run options** below the input form.
> - Click **Start**. Places appear in the **Output** tab while the run is going.
> - Download them from **Storage → Datasets → Export**.

Raise **Places per search** once the output looks right.

***

### 💲 How much does it cost to scrape Google Maps?

Google Map Scraper uses **pay-per-event** pricing. Your bill has three parts:

1. **Results:** you pay for each place saved to the main Places table. The price depends on your Apify plan (table below).
2. **Start fee:** $0.00005 per run at the default 1 GB memory (start fee is $0.00005 per GB).
3. **Platform usage:** the compute the run uses, billed at your Apify plan's own rates.

| 💲 Apify plan | Price per place | Price per 1,000 places |
|---|---|---|
| 💲 Free | $0.002 | $2.00 |
| 💲 Starter | $0.0018 | $1.80 |
| 💲 Scale | $0.0016 | $1.60 |
| 💲 Business and higher | $0.0014 | $1.40 |

The plan discount applies to the result price only. The start fee is the same on every plan, and platform usage is billed at your Apify plan's own rates.

**Example:** 1,000 places cost $2.00 in result charges on the Free plan ($1.40 on Business), plus the $0.00005 start fee and platform usage. The default input (one search, 10 places) costs $0.02 in result charges plus the start fee and platform usage. The best way to know your full cost is a small test run: the run page shows the exact cost when it finishes.

**What is not billed:** the extra tables (opening hours, rating breakdown, review topics, amenities, photos, owner posts), the searches table and the failed inputs table. Entries that return nothing cost no result charges.

**When a run fails or stops early:** each place is charged when it is saved. If a run stops early (your maximum charge limit is reached, you abort it, or Google Maps keeps refusing requests), you pay for the places already saved, plus the start fee and the platform usage so far. If a run fails before any place is saved, there are no result charges; the start fee and platform usage still apply.

See the [pricing tab](https://apify.com/insights_data/google-map-scraper/pricing) for the current prices.

#### Is scraping Google Maps free?

You can start for free. The [Apify Free plan](https://apify.com/pricing) gives you $5 in monthly credit, which pays for result charges and platform usage. Free-plan runs work the same as paid runs: there is no extra cap on places per run.

#### How do I cap the cost of a run?

Set a **maximum charge limit** in **Run options** below the input form before you click **Start** (via the API, use the `maxTotalChargeUsd` parameter). It caps the result charges of that run; platform usage comes on top. When the limit is reached, the Actor stops cleanly and keeps every place it already saved.

***

### ⬇️ Google Map Scraper input

The only required field is **Search terms and Maps links**. Everything else is optional.

#### Settings most people change

- **Search terms and Maps links** (`urls`): one entry per line. A keyword or category (`dentist`, `coffee shop`), a Google Maps search or place link, or a place id. Duplicate entries are removed.
- **Location** (`locationQuery`): the city, region, address or country to search in, for example `New York, USA`. It is added to every keyword entry, and to search links without a map position, so use one location per run. Place ids, place links with an id, and links with a map position (`@lat,lng`) ignore it. For several cities, save one task per city (see [Run it on a schedule](#run-it-on-a-schedule)), or leave **Location** empty and write the city into each keyword.
- **Places per search** (`maxCrawledPlacesPerSearch`): the maximum places for **each** entry, not for the whole run. The default is 10. `0` means as many places as Google Maps lists.
- **Place details** (`scrapePlaceDetailPage`): adds the rating breakdown, review topics, amenities, photos and owner posts. Slower, because each place needs one extra step. Off by default.
- **Website filter** (`website`): all places, only places with a website, or only places without one.

Here's an example that finds up to 10 dentists in New York:

```json
{
    "urls": ["dentist"],
    "locationQuery": "New York, USA",
    "maxCrawledPlacesPerSearch": 10
}
```

See the [input tab](https://apify.com/insights_data/google-map-scraper/input-schema) for the full form.

#### All input fields

| ⬇️ Field (Console title) | API name | Default | What it does |
|---|---|---|---|
| 🔍 Search terms and Maps links | `urls` | (required) | Keywords, Google Maps search or place links, place ids or short map links, one per line |
| 🏙️ Location | `locationQuery` | empty | Area added to keyword entries and to search links without a map position |
| 💯 Places per search | `maxCrawledPlacesPerSearch` | 10 | Maximum places per entry; `0` = all |
| 🧬 Place details | `scrapePlaceDetailPage` | off | Adds the place-details fields and fills their tables |
| 🏷️ Place categories | `categoryFilterWords` | empty | Keep only places whose categories contain one of these words |
| ⭐ Minimum star rating | `placeMinimumStars` | any | `two`, `twoAndHalf`, `three`, `threeAndHalf`, `four`, `fourAndHalf` |
| 🌐 Website filter | `website` | `allPlaces` | `allPlaces`, `withWebsite`, `withoutWebsite` |
| 🚫 Skip closed places | `skipClosedPlaces` | off | Leaves out permanently and temporarily closed places |
| 🈯 Language | `language` | `en` | Language of categories, hours text and descriptions (70 languages) |
| 🌍 Country | `countryCode` | not set | Country the results lean towards; added to the location when **Location** is empty |
| 📮 City, State, County, Postal code | `city`, `state`, `county`, `postalCode` | empty | Joined into a location only when **Location** is empty |
| 🛡️ Proxy | `proxyConfiguration` | no proxy | Optional. A proxy sends the requests through another connection. Choose Apify Proxy or your own proxy |

#### Places per search

The limit counts per entry. Three keywords with the default of 10 can return up to 30 places, and each saved place is a billed result.

- ✅ Good: `10` for a first test, then raise it
- ❌ Bad: `0` with many broad keywords on a first run

> ⚠️ With `0`, the number of places depends on how many Google Maps lists. Set a maximum charge limit to keep the cost under control.

#### Location

Keyword searches run as "keyword in location", so `dentist` with `New York, USA` searches dentists in New York. When a search returns many places, the Actor also searches the rest of the area for more. That only works when a location is set or the link points at a map area.

- ✅ Good: `Austin, TX, USA`
- ❌ Bad: `Austin; Dallas` (two locations in one run)

For several cities in one run, leave **Location** empty and type entries like `dentist in Austin` and `dentist in Dallas`. Don't combine both: with **Location** set, it is added to every keyword entry too. Keep in mind that without any location (from **Location**, or from the City, State, County, Postal code or Country fields), the extra search of the rest of the area does not run, so busy keywords may return fewer places.

> ⚠️ When **Country** is not set, results lean towards the USA, even with a non-US **Location**. For other countries, set **Country** too.

#### Search terms and Maps links

You can mix keywords and links. A Google Maps place id starts with `ChIJ`; you find it in the `placeId` column of an earlier run. A place link that contains an id returns that exact place. A place link with only a name returns the first match for that name.

- ✅ Good: `coffee shop`, `https://www.google.com/maps/search/coffee+shop/@40.75,-73.98,14z`, `ChIJb-HkRuRYwokRF5qsEyxejyc`
- ❌ Bad: a normal website address (it is treated as a keyword)

#### Minimum star rating

Values are words that the Console shows as 4.0+, 4.5+ and so on. When a minimum is set, places without any rating are left out too.

***

### ⬆️ Google Map Scraper output

Results are stored in a **dataset** (Apify's name for a results table) and appear in the **Output** tab while the run is going, so you can watch the Google Maps data scraper fill the table live. The main **Places** table has six views: Places, Contact and location, Ratings and reviews, Status and hours, Place details, and IDs and links. To download, go to **Storage → Datasets**, open the dataset and click **Export**.

#### JSON example

Here is an example place row for the input above. The values are examples and shortened (**Place details** off):

```json
[
    {
        "rank": 1,
        "searchPageUrl": "https://www.google.com/maps/search/dentist%20in%20New%20York%2C%20USA",
        "title": "209 NYC Dental",
        "categoryName": "Dentist",
        "categories": ["Dentist", "Cosmetic dentist"],
        "address": "209 E 56th St 1st floor, New York, NY 10022",
        "neighborhood": "Manhattan",
        "street": "209 E 56th St 1st floor",
        "city": "New York",
        "postalCode": "10022",
        "state": "NY",
        "countryCode": "US",
        "website": "https://www.209nycdental.com/",
        "domain": "209nycdental.com",
        "phone": "(212) 355-2290",
        "phoneUnformatted": "+12123552290",
        "claimThisBusiness": false,
        "location": { "lat": 40.7594146, "lng": -73.9671025 },
        "totalScore": 4.9,
        "reviewsCount": 1930,
        "permanentlyClosed": false,
        "temporarilyClosed": false,
        "openStatus": "Open · Closes 6:30 PM",
        "openingHours": [
            { "day": "Monday", "hours": "7:30 AM-6:30 PM" }
        ],
        "timezone": "America/New_York",
        "description": "Family dental practice.",
        "imageUrl": "https://lh3.googleusercontent.com/p/example-photo",
        "placeId": "ChIJb-HkRuRYwokRF5qsEyxejyc",
        "cid": "2850600632550464023",
        "fid": "0x89c258e446e4e16f:0x278f5e2c13ac9a17",
        "kgmid": "/g/1thqbs3j",
        "reviewsLink": "https://search.google.com/local/reviews?placeid=ChIJb-HkRuRYwokRF5qsEyxejyc",
        "url": "https://www.google.com/maps/place/?q=place_id:ChIJb-HkRuRYwokRF5qsEyxejyc",
        "opportunity": [],
        "scrapedAt": "2026-10-28T10:00:00.000Z"
    }
]
```

This place has a website, a phone, a rating above 4.0 and many reviews, so `opportunity` is empty. A place without a website would show `["no_website"]`.

> **Note:** `cid`, `fid` and `kgmid` are technical Google ids of the same place. Most users can ignore them; they help match places across tools. `placeId` is the id you can paste back into **Search terms and Maps links**.

#### Place details example

With **Place details** on, each row also gets these fields (example values):

```json
{
    "ratingBreakdown": { "oneStar": 44, "twoStar": 8, "threeStar": 12, "fourStar": 64, "fiveStar": 1802 },
    "reviewTopics": [{ "topic": "friendly staff", "mentions": 311 }],
    "additionalInfo": { "Accessibility": [{ "Wheelchair accessible entrance": true }] },
    "imageUrls": ["https://lh3.googleusercontent.com/p/example-photo"],
    "ownerPosts": [{ "text": "Same-day appointments available.", "link": "https://example.com" }]
}
```

#### Extra tables and run totals

You find the extra tables in the **Output** tab and under **Storage → Datasets**. They are not billed.

| 🗂️ Table | One row per | Filled when |
|---|---|---|
| 🕒 Opening hours | weekday of a place | the place lists opening hours |
| ⭐ Rating breakdown | place | **Place details** is on |
| 🗣️ Review topics | review topic | **Place details** is on |
| ♿ Amenities and attributes | attribute | **Place details** is on |
| 📸 Photos | photo | **Place details** is on |
| 📣 Owner posts | owner post | **Place details** is on |
| 🔍 Searches | entry you gave | every run |
| 🛑 Failed inputs | entry that failed or returned nothing | when an entry fails or finds nothing |

The **Searches** table shows how many places each entry found and kept, with a status:

- `ok`: places were kept
- `filtered`: places were found, but none were kept, because your filters removed them or an earlier entry had already saved them
- `no places`: Google Maps returned nothing for this entry
- `failed`: the entry could not be searched; the Failed inputs table says why

The **Run summary** (Output tab, or **Storage → Key-value stores**) holds the run totals: places saved, places charged, entries with problems, entries skipped and the duration.

#### How to export Google Maps to Excel or CSV

Open **Storage → Datasets**, pick the dataset, click **Export** and choose Excel. Google Maps to CSV works the same way: pick CSV instead. You can also choose a view first, so the file only holds the columns you need.

***

### 💡 Tips and advanced usage

#### How many results can you scrape with Google Map Scraper?

There is no fixed cap per run. Each entry returns up to **Places per search** places, and `0` returns as many as Google Maps lists for that search. When a search returns many places and a location is set (or the link points at a map area), the Actor also searches the rest of that area. Very large regions may still not return every place, so split a country or state into cities. The best way to know for your use case is a quick test run.

#### How to get faster or cheaper results

- Keep **Place details** off unless you need the extra fields. It adds one step per place.
- Use filters (**Place categories**, **Minimum star rating**, **Website filter**): places removed by a filter are not billed.
- The same place found by two keywords is saved and billed once per run.
- Use precise keywords (`pediatric dentist`) instead of broad ones (`doctor`).

#### Run it on a schedule

A weekly lead feed for an agency that sells websites:

1. Set **Search terms and Maps links** to `plumber`, **Location** to `Austin, TX, USA`, **Website filter** to "Only without a website" and **Places per search** to `50`.
2. Save the input as a **task** (a saved copy of your input that you can rerun) from the Actor page. Add a maximum charge limit in the task's run options.
3. Create an Apify **schedule** for the task that runs it every Monday.
4. Compare runs by `placeId`: a `placeId` that is new this week is a new prospect, and a changed `totalScore` or `reviewsCount` shows movement. The Actor doesn't compare runs itself, so do it in Google Sheets or your CRM.

> ⚠️ Every run saves and bills its places again, including the ones you got last week. With 50 places, that is at most $0.10 per week in result charges on the Free plan, plus the start fee and platform usage. For more cities, create one task per city.

#### Troubleshooting

- **The run failed and no places were saved:** Google Maps refused the requests. Wait a while and run again. You can also open **Proxy** at the bottom of the input form and choose Apify Proxy. A proxy sends the requests through another connection. You pay no result charges for this run; the start fee and platform usage still apply.
- **The run stopped early with "Maximum charge limit reached":** raise the maximum charge limit in **Run options** and run again. The places already saved stay in your dataset.
- **An entry returned 0 places:** open the **Searches** table. `no places` means Google Maps listed nothing, so check the spelling and the location. `filtered` means your filters removed every place, so loosen them. `failed` means the entry could not be searched; the **Failed inputs** table says why.
- **The run failed with "Input problem":** check **Search terms and Maps links**, **Places per search** and **Minimum star rating** for an unusual value, then run again.
- **Fewer places than expected:** see [Why am I getting fewer results than expected?](#why-am-i-getting-fewer-results-than-expected)
- **Something else:** check the log for the entry that caused the problem, then [create an issue](https://apify.com/insights_data/google-map-scraper/issues/open) with your input.

#### Known issues

- `temporarilyClosed` is matched by exact text and may miss some temporarily closed places.
- If Google Maps keeps refusing requests, the Actor stops sending new ones and keeps everything already saved. If nothing was saved, the run ends as failed. See [Troubleshooting](#troubleshooting).
- Without a location, broad keywords return fewer places, and the log suggests adding one.

***

### 🔌 Google Map Scraper integrations and API

#### Can I use Google Map Scraper as a Google Maps scraper API?

Yes. The [Apify API](https://docs.apify.com/api/v2) lets you start runs, schedule them and fetch results. Use the `apify-client` [NPM package](https://apify.com/insights_data/google-map-scraper/api/javascript) for Node.js or the [PyPI package](https://apify.com/insights_data/google-map-scraper/api/python) for Python. The [API tab](https://apify.com/insights_data/google-map-scraper/api) has ready-to-use code.

#### Google Maps scraper Python example

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("insights_data/google-map-scraper").call(run_input={
    "urls": ["dentist"],
    "locationQuery": "New York, USA",
    "maxCrawledPlacesPerSearch": 10,
})

for place in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(place["title"], place["phone"], place["website"], place["opportunity"])
```

Calling this Google Maps data extractor from code is the easiest way to feed your own lead-scoring or mapping pipeline.

#### Can I integrate Google Map Scraper with other apps?

Yes. Connect it to almost any cloud service through [Apify integrations](https://apify.com/integrations), and use [webhooks](https://docs.apify.com/integrations/webhooks) (a link Apify calls when a run finishes) to start the next step automatically. Two workflows that fit this Actor:

- 📗 **Google Sheets lead list:** add the Google Sheets integration to your scheduled task, so every run appends its places (name, phone, website, `opportunity`) to a sheet your sales team works from.
- 🔁 **Google Maps scraper n8n or Make flow:** a webhook on "run succeeded" starts an n8n or Make scenario that keeps only rows with `no_website` or `unclaimed`, creates leads in your CRM and posts a summary to Slack. Zapier works the same way.

#### Can I use it as a Google Maps scraper MCP tool for AI agents?

Yes. Connect Google Map Scraper to Claude and other AI assistants through the Apify MCP server, then ask the agent for places in plain words ("find 20 cafes in Lisbon without a website"). Open the [MCP tab](https://apify.com/insights_data/google-map-scraper/api/mcp) for setup steps.

***

### 🧩 Other Google scrapers

These Actors from the same account cover the other half of a local or Google research workflow:

| | |
|---|---|
| 💬 [Google Map Review Scraper](https://apify.com/insights_data/google-map-review-scraper): reviews for any place with rating, text, author, date and owner replies | 🏨 [Google Hotels Scraper](https://apify.com/insights_data/google-hotels-scraper): hotel prices, ratings, star class, amenities and booking links |
| 📢 [Google Ads Transparency Center Scraper & API](https://apify.com/insights_data/google-ads-transparency-center-scraper-api): ads across Search, YouTube, Shopping, Maps and Play by brand or domain | 📰 [Google News Scraper](https://apify.com/insights_data/google-news-scraper): headlines, publishers and article links by search term or topic |
| 📈 [Keyword Search Volume — Bulk Google Metrics (CPC & Trend)](https://apify.com/insights_data/keyword-search-volume): Google search volume, CPC and 12-month trend for your keywords | 💼 [LinkedIn Company Employees Scraper](https://apify.com/insights_data/linkedin-company-employees-scraper): public employees of a company with title, seniority and location |

***

### ❓ FAQ

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

Scraping publicly visible business listings is generally legal, but you should respect personal data rules (such as GDPR), intellectual property and Google's [Terms of Service](https://policies.google.com/terms). Business data like names, phones and addresses is usually public; data about private people needs a legitimate reason. Read Apify's guide on [whether web scraping is legal](https://blog.apify.com/is-web-scraping-legal/). This is not legal advice.

#### How does Google Map Scraper work?

It works like a Google Maps crawler that you steer with a keyword and a location. For each entry it loads the public Google Maps results, reads the list of places, removes duplicates, applies your filters and limit, and saves each place as soon as it's ready. With **Place details** on, it also opens each place for the extra fields. The lead signals are calculated from the place data.

#### How to scrape Google Maps for leads?

Use it as a Google Maps lead scraper: enter the business type and city, set **Website filter** or **Minimum star rating** to match the leads you sell to, and sort the results by the `opportunity` field. The `opportunity` signals (`no_website`, `few_reviews`, `low_rating`, `unclaimed`) make the run a Google Maps leads extractor with a built-in reason to call each business. For agency prospecting, "Only without a website" is a good starting point. You get phones and websites, not emails.

#### How is Google Map Scraper different from Google Map Review Scraper?

Google Map Scraper is the Google Maps business data scraper: it finds places and returns their contact details, ratings, review counts and review topics. [Google Map Review Scraper](https://apify.com/insights_data/google-map-review-scraper) collects the reviews of a place.

| | Google Map Scraper | Google Map Review Scraper |
|---|---|---|
| Finds places by keyword and location | ✅ | ❌ |
| Phone, website, address, hours | ✅ | ❌ |
| Rating and review count | ✅ | ✅ (rating per review) |
| Rating breakdown and review topics | ✅ (Place details on) | ❌ |
| Review text, author, date, owner replies | ❌ | ✅ |

#### Is Google Map Scraper a Google Places API alternative?

It can be, if the fields listed above are what you need. You get place data without an API key, a Google Cloud project or billing setup. It is not the official API: a Google places scraper like this one reads what Google Maps shows publicly, and we have not compared the two field by field. Check the field list above against your needs before you switch.

#### What is the difference between a Google Maps extractor and a scraper?

Nothing in practice. "Google Maps extractor", "scraper" and "crawler" all describe a tool that collects data from Google Maps listings. Google Map Scraper adds filters, lead signals and per-section tables on top.

#### Can I use it as a Google business scraper for one company?

Yes. Paste the company's Google Maps place link or place id into **Search terms and Maps links**. You get one row for that place, and with **Place details** on you also get the rating breakdown, amenities, photos and owner posts.

#### Can I scrape a Google Maps URL instead of a keyword?

Yes. The same field takes links, so you don't need a separate Google Maps URL scraper. A search link that contains a map position keeps that area, and a place link with an id returns that place.

#### Why am I getting fewer results than expected?

- **Places per search** is 10 by default; raise it or set `0`.
- Your filters removed places. The **Searches** table shows found and kept counts per entry.
- No location was set, so the Actor could not search the rest of the area. Add one in **Location**.
- Google Maps simply lists fewer places for that keyword and area. Try a broader keyword or a bigger city.
- Check the **Failed inputs** table and the log for entries that returned nothing.

#### Does Google Map Scraper return email addresses?

No. This Google Maps business scraper returns phone numbers, websites and addresses. It doesn't visit business websites and doesn't collect emails or social profiles.

***

### 📧 Support and feedback

Found a bug or missing a field? Create an issue on the [Issues tab](https://apify.com/insights_data/google-map-scraper/issues/open) and include the input you used.

Need a **custom solution**, such as a different data source or more fields? Contact us at hello.insights.data@gmail.com.

Built and maintained by [Insights Data](https://apify.com/insights_data).

# Actor input Schema

## `urls` (type: `array`):

One per line: a keyword or category (dentist, coffee shop), a Google Maps search or place link, or a place id starting with ChIJ. Duplicates are removed. Add as many as you like.

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

City, region, address or country to search in, for example New York, USA. Used with keywords; links that already point at an area keep their own area. Use one location per run.

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

Maximum places to return for each keyword or link. Use 0 for everything Google shows; big areas are scanned in parts to go past the usual limit.

## `scrapePlaceDetailPage` (type: `boolean`):

Adds the star-by-star rating breakdown, review topics, amenities and attributes, more photos and owner posts for every place. Slower, because each place needs one extra step.

## `categoryFilterWords` (type: `array`):

Keep only places whose category contains one of these words, for example dentist or pizza. Leave empty to keep every category.

## `placeMinimumStars` (type: `string`):

Skip places rated below this value.

## `website` (type: `string`):

Keep all places, only places that list a website, or only places without one.

## `skipClosedPlaces` (type: `boolean`):

Leave out places that are permanently or temporarily closed.

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

Language of the results: category names, opening hours text and descriptions.

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

Country to search in. Also biases the results towards this country. Used as the location when no location is typed above.

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

City to search in. Used when no location is typed above.

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

State or region. Used when no location is typed above.

## `county` (type: `string`):

County or district. Used when no location is typed above.

## `postalCode` (type: `string`):

Postal or ZIP code. Used when no location is typed above.

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

Runs without a proxy by default. If Google refuses the requests, the Actor switches to a datacenter proxy, then a residential proxy, and stays on it.

## Actor input object example

```json
{
  "urls": [
    "restaurant"
  ],
  "locationQuery": "New York, USA",
  "maxCrawledPlacesPerSearch": 10,
  "scrapePlaceDetailPage": false,
  "placeMinimumStars": "",
  "website": "allPlaces",
  "skipClosedPlaces": false,
  "language": "en",
  "countryCode": "",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One row per place.

## `contactLocation` (type: `string`):

Phone, website, address and coordinates.

## `ratings` (type: `string`):

Rating, review count, breakdown and topics.

## `statusHours` (type: `string`):

Open or closed, opening hours and lead signals.

## `details` (type: `string`):

Description, categories, amenities, photos and owner posts.

## `ids` (type: `string`):

Place ids and Google links.

## `openingHours` (type: `string`):

One row per weekday of each place.

## `ratingBreakdown` (type: `string`):

Reviews per star for each place (place details on).

## `reviewTopics` (type: `string`):

One row per review topic of each place (place details on).

## `amenities` (type: `string`):

One row per attribute of each place (place details on).

## `photos` (type: `string`):

One row per photo of each place (place details on).

## `ownerPosts` (type: `string`):

One row per owner post of each place (place details on).

## `searches` (type: `string`):

One row per keyword, link or place id you gave, with how many places it returned.

## `failedInputs` (type: `string`):

Entries that could not be searched or returned nothing.

## `summary` (type: `string`):

Counts and timing of the run.

# 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 = {
    "urls": [
        "restaurant"
    ],
    "locationQuery": "New York, USA",
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("insights_data/google-map-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 = {
    "urls": ["restaurant"],
    "locationQuery": "New York, USA",
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("insights_data/google-map-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 '{
  "urls": [
    "restaurant"
  ],
  "locationQuery": "New York, USA",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call insights_data/google-map-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,insights_data/google-map-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/a0V8YhddP3UgHDXgn/builds/50gSFQ9i4PpwFFTvb/openapi.json
