# Google Maps Scraper (`kibaale/gmaps-scraper`) Actor

Extract business data from Google Maps — places, full profiles, popular times and reviews — from anywhere in the world, without an API key or a Google account. Runs fully in the cloud, outputs a clean dataset (or JSON).

- **URL**: https://apify.com/kibaale/gmaps-scraper.md
- **Developed by:** [kibalee](https://apify.com/kibaale) (community)
- **Categories:**
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 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.

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 Scraper

Extract business data from Google Maps — places, full profiles, popular
times, and reviews — **from anywhere in the world**, without an API key or
a Google account. Runs fully in the cloud, outputs a clean dataset (or
JSON).

### What you can scrape

- **Places by keyword, worldwide** — search any query the way you type it
  in Google Maps. Name the area in the query and it is found
  automatically: "coffee shops in Paris" finds cafes in Paris,
  "dentists near Central Park" finds dentists around Central Park — no
  coordinates, no extra setup. For precise spots, set the map center to
  exact coordinates instead.
- **Business profile per place** — name, address (street & full), rating,
  review count, category, tagline, phone, website, opening hours per day,
  current open/closed status, coordinates, Google Maps link.
- **Popular times** — how busy a place gets: score 0–100 for every hour of
  every day of the week, with plain-language labels, plus live "right now"
  popularity.
- **Reviews** — full review text with author name, star rating, date,
  relative date, and photo attachments.

### Quick start

1. Run the actor with one input: the search query.
2. Result: one dataset record per place. Turn on the extra options for
   popular times or reviews.

Example run — `keyword: "coffee shop Paris"`, `maxResults: 10`:

```json
{
  "keyword": "coffee shop Paris",
  "maxResults": 10,
  "scrapeReviews": true,
  "maxReviewsPerPlace": 20
}
```

#### Example result

One real record from a run of `"coffee shop Paris"` (arrays trimmed):

```json
{
  "title": "Shukery coffee & matcha",
  "address": "18 Av. de l'Opéra, 75001 Paris",
  "rating": 4.8,
  "reviewCount": 1420,
  "categoryLabel": "Coffee shop",
  "tagline": "Dogs allowed",
  "phone": "01 53 40 83 64",
  "website": "https://www.instagram.com/shukerycoffee/",
  "openStatus": "Open · Closes 10 pm",
  "schedule": {
    "Monday": ["7:30 am–9 pm"],
    "...": "..."
  },
  "popularTimes": {
    "Monday": [
      { "hour": 9, "score": 42, "label": "Usually not too busy" },
      "..."
    ]
  },
  "popularTimesReal": {
    "day": "Friday",
    "hour": 12,
    "score": 39,
    "label": "Not too busy"
  },
  "reviews": []
}
```

### Input

| Field | What it does |
|---|---|
| **Search query** (required) | Keyword to search, e.g. `coffee shops in Paris`. Areas named in the query are found automatically, anywhere in the world. |
| Map center | Optional coordinates to search around. Only needed for a precise spot — usually the area in the query is enough. |
| Max results | How many places to return. |
| Scrape place details | Fetch the full profile of each place (default on). |
| Scrape popular times | Capture the 7×24 popularity histogram + live popularity (default off). |
| Scrape reviews | Add review text per place. |
| Max reviews per place | Stop after N reviews (0 = unlimited). |
| Reviews delay | Pause between review pages (raise it if reviews stop coming). |
| Concurrency | Places processed in parallel (speed vs. safety). |
| UI language / Region | Language & region Google returns labels in (default `en` / `US`). |

### Record fields

| Field | What it is |
|---|---|
| `title` | Place name |
| `address`, `addressFull` | Street address, then the full address |
| `latitude`, `longitude` | Coordinates |
| `rating`, `reviewCount` | Average rating and how many people reviewed it |
| `categoryLabel`, `tagline` | Category (e.g. "Coffee shop") and short descriptor |
| `phone`, `website` | Contact details |
| `openStatus`, `schedule` | Open/closed now, and opening hours per weekday |
| `popularTimes`, `popularTimesReal` | 7×24 busy score 0–100 + live popularity |
| `reviews` | Review objects when reviews are enabled |
| `url`, `placeId` | Link to the place on Google Maps, plus its stable place id |

### How much does it cost you?

Roughly one Google request per action:

| Action | Requests |
|---|---|
| Search (1 query) | 1 request → up to ~20 places |
| Profile per place | 1 request per place |
| Popular times | included in the profile request |
| Reviews | 1 request per ~20–25 reviews |

No API-key fees, no per-row hidden costs — you only pay Apify's platform
compute for the requests actually made. Plus a few automatic requests per
run (session warm-up, ~4–5 total) — a one-time cost per run, not per
place. When your query names an area, the actor also looks that area up
once via a free geocoder (no Google request, no API key) so it searches
the area you asked for.

**Billing** is pay-per-event: a small fee per place saved, an extra fee
per full business profile you scrape, and a small fee per 25 reviews when
reviews are enabled. Exact prices: the **Pricing** tab on the Store page.

### FAQ

**Does it work outside one region?** Yes — any country. Name the city,
district or area in the query ("sushi in Tokyo", "cafes in Lisbon",
"plumbers in Brooklyn") and it is found automatically; or pin the map
center to exact coordinates.

**What if the query has no area and I leave the center empty?** The run
stops with a clear message telling you to add an area or set the center —
it never silently searches the wrong place.

**Do I need proxies?** Usually not — this scraper talks to Google Maps
directly, no browser. If Google ever throttles your requests ("limited
view"), add a `GMAPS_PROXY` environment variable (any HTTP/SOCKS proxy
URL) and the actor will route around it.

**Does it use the official Google Places API?** No — no API key, no
$17–32 per 1,000 calls, no usage limits beyond what Google itself
enforces on any visitor.

**How fresh is the data?** Live — every run fetches Google Maps data at
that moment.

**Popular times missing for some places?** Normal — Google only shows
popular times for places that get enough foot traffic.

**Does scraping reviews need a Google account?** No. Anonymous is enough
and safer.

# Actor input Schema

## `keyword` (type: `string`):

What to search on Google Maps, e.g. "coffee shops in Paris", "dentists near Central Park", "pizza in Naples". Name the city/area in the query — the actor finds it automatically, anywhere in the world.

## `mapCenter` (type: `object`):

Optional. Coordinates to search around (Google Maps scans roughly 5-10 km around a center). Leave empty when the query names an area — that area is found automatically.

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

Maximum number of places to return (Google returns up to ~20 per search request).

## `scrapeDetails` (type: `boolean`):

Fetch the full place profile: rating, review count, category, phone, website, opening hours, full address, open/closed status, popular times.

## `scrapePopularTimes` (type: `boolean`):

Ensures the weekly popularity histogram (7 days x 24h, score 0-100 with localized label) and live "right now" popularity are captured, retrying until Google returns them. Requires "Scrape place details".

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

Fetch review text per place (author name, rating, date, text, attachments). Requires "Scrape place details".

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

Stop after this many reviews per place (0 = unlimited).

## `reviewsDelaySeconds` (type: `number`):

Pause between review pages to avoid anti-bot gating. Raise it if reviews stop coming.

## `maxConcurrency` (type: `integer`):

How many places to process in parallel (details/reviews).

## `hl` (type: `string`):

Google UI language code, e.g. "en", "en-US", "id", "de".

## `gl` (type: `string`):

Google region code, e.g. "US", "ID", "DE". Used for labeling and local ranking.

## Actor input object example

```json
{
  "keyword": "coffee shops in Paris",
  "maxResults": 10,
  "scrapeDetails": true,
  "scrapePopularTimes": false,
  "scrapeReviews": false,
  "maxReviewsPerPlace": 20,
  "reviewsDelaySeconds": 0.8,
  "maxConcurrency": 8,
  "hl": "en",
  "gl": "US"
}
```

# Actor output Schema

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

One record per place, stored in the run's default dataset

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("kibaale/gmaps-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("kibaale/gmaps-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 '{}' |
apify call kibaale/gmaps-scraper --silent --output-dataset

```

## MCP server setup

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