# Google Maps Reviews Scraper (`bgfc97/google-maps-reviews-scraper`) Actor

🔥 Up to 30% OFF! Scrape Google Maps reviews — no login. Rating, text, date, reviewer, owner responses, likes, photos + place details — 30+ fields per review. Fast & reliable, pay per review.

- **URL**: https://apify.com/bgfc97/google-maps-reviews-scraper.md
- **Developed by:** [Bruno](https://apify.com/bgfc97) (community)
- **Categories:** Lead generation, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.80 / 1,000 review scrapeds

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

## Google Maps Reviews Scraper

Scrape **Google Maps reviews** for any place using a real headless browser (Playwright) through
Apify residential proxy. Give it a place URL, a Google `place_id`, or just a name + city, and it
returns the place's info **and its reviews** — with sort and language options.

Reviews are read from **two complementary sources and merged** (de-duplicated by review id):

1. the review **cards rendered in the page** (reliable backbone), and
2. Google Maps' **own internal review payload embedded in the page** (`APP_INITIALIZATION_STATE` —
   the place-details response Maps itself loads). This second source provides the **full, untruncated
   review text** plus fields the visible cards don't expose: the **absolute publish date**, the
   **review language**, the author's **id / photo / review count / Local-Guide** status, the
   **review photos**, the **owner's response text + date**, and the place's **1–5 star distribution**.

### Input

Provide at least one target (you can mix them):

| Field | Type | Description |
|-------|------|-------------|
| `startUrls` | array | Google Maps place URLs (`https://www.google.com/maps/place/...` or `https://maps.app.goo.gl/...`). Most reliable input. |
| `searchStrings` | array | `name + city`, e.g. `Katz's Delicatessen New York`. First matching place is scraped. |
| `placeIds` | array | Google place IDs (`ChIJ...`). |
| `maxReviews` | integer | Max reviews per place (default 100, up to 50000). |
| `reviewsSort` | select | `mostRelevant`, `newest`, `highestRating`, `lowestRating` (default `newest`). |
| `language` | string | UI/results language, e.g. `en`, `pt-BR`, `es` (default `en`). |
| `proxyConfiguration` | proxy | RESIDENTIAL strongly recommended (default). |
| `timeoutSecs` | integer | Per-place render timeout (default 60). |

### Output

One dataset item **per review**, each carrying the place context:

```json
{
  "placeName": "Katz's Delicatessen",
  "placeId": "0x89c2598f7ff4aa09:0x313547e757cb8cea",
  "placeIdChIJ": "ChIJCar0f49ZwokR6ozLV-dHNTE",
  "placeUrl": "https://www.google.com/maps?cid=...",
  "placeRating": 4.5,
  "placeTotalReviews": 55724,
  "placeCategory": "Deli",
  "placeAddress": "205 E Houston St, New York, NY 10002",
  "placeStarDistribution": { "1": 1821, "2": 1422, "3": 3369, "4": 8863, "5": 40249 },
  "reviewId": "Ci9DQUlR...",
  "author": "Patric Nouaille",
  "authorUrl": "https://www.google.com/maps/contrib/117377362771329070868",
  "authorId": "117377362771329070868",
  "authorPhoto": "https://lh3.googleusercontent.com/a/...",
  "authorMeta": "3 reviews",
  "authorReviewsCount": 3,
  "authorIsLocalGuide": false,
  "rating": 5,
  "date": "2 months ago",
  "dateAbsolute": "2026-07-24T10:18:14.113Z",
  "publishedAtTimestamp": 1784888294113,
  "reviewLanguage": "en",
  "likes": 0,
  "text": "Full, untruncated review text...",
  "ownerResponse": "Thanks for visiting!",
  "ownerResponseDate": "2 months ago",
  "ownerResponseDateAbsolute": "2026-07-28T...",
  "reviewUrl": "https://www.google.com/maps/reviews/data=...",
  "photos": ["https://lh3.googleusercontent.com/...", "..."],
  "source": "embedded+dom"
}
```

`source` tells you where each review came from: `embedded` (Google's internal payload), `dom`
(rendered card), or `embedded+dom` (both, merged).

### Honesty

No fabricated data. Fields that are not on the real page come back as `null` (or `[]` for photos,
`0` for likes). If Google blocks the request or serves a reduced layout, the item reports the exact
reason instead of inventing results — always use a RESIDENTIAL proxy.

#### Note on review depth

Google does not paginate its public reviews list for automated (non-logged-in) browser sessions —
its internal `listugcposts` pagination endpoint returns HTTP 403 to unauthenticated requests. This
actor therefore returns the full set of reviews Google exposes to a logged-out visitor: the place's
complete info + star distribution, and the exposed review set (the most recent/relevant reviews,
with full text, photos, dates, language and owner replies). It does **not** download the entire
multi-thousand review history. Sort order and language apply to the returned set.

# Actor input Schema

## `startUrls` (type: `array`):

One or more Google Maps place URLs to scrape reviews from, e.g. "https://www.google.com/maps/place/..." or a shortened "https://maps.app.goo.gl/..." link. This is the most reliable input. You can also use "searchStrings" or "placeIds" instead of (or together with) this.

## `searchStrings` (type: `array`):

Alternative to URLs: place name plus city/location, e.g. "Katz's Delicatessen New York" or "Padaria Bella Paulista Sao Paulo". Each string is searched on Google Maps and the first matching place is scraped. Use a specific name+city to avoid ambiguity.

## `placeIds` (type: `array`):

Alternative to URLs: Google place IDs (they start with "ChIJ..."), e.g. "ChIJ8Q2WSpJZwokRQwxJvR2tkbc". Each is resolved to its Maps place page and its reviews are scraped.

## `maxReviews` (type: `integer`):

Maximum number of reviews to extract per place. The actor reads the on-page reviews and then paginates Google Maps' internal reviews endpoint until this many are collected or no more reviews remain. Use a smaller number for faster/cheaper runs.

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

Order in which Google returns the reviews before scrolling: Most relevant (Google default), Newest first, Highest rating first, or Lowest rating first.

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

Google Maps UI/results language code, e.g. "en", "pt-BR", "es". Affects the relative dates ("2 months ago") and any translated content, and is also sent as the Accept-Language header.

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

Google Maps blocks datacenter IPs quickly and serves a reduced layout to suspicious clients — RESIDENTIAL proxy is strongly recommended (default) for complete, paginated reviews.

## `timeoutSecs` (type: `integer`):

How long to wait for the place page and the reviews list to render before giving up on a given place.

## `debugEndpoint` (type: `boolean`):

Advanced/diagnostic only. When enabled, the raw Google Maps reviews-endpoint payload is saved to the run's key-value store (for troubleshooting). Leave off for normal runs.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.google.com/maps/place/Katz's+Delicatessen/@40.722233,-73.987429,17z/data=!4m6!3m5!1s0x89c2598f7ff4aa09:0x313547e757cb8cea"
  ],
  "searchStrings": [],
  "placeIds": [],
  "maxReviews": 100,
  "reviewsSort": "newest",
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "timeoutSecs": 60,
  "debugEndpoint": false
}
```

# Actor output Schema

# 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 = {
    "startUrls": [
        "https://www.google.com/maps/place/Katz's+Delicatessen/@40.722233,-73.987429,17z/data=!4m6!3m5!1s0x89c2598f7ff4aa09:0x313547e757cb8cea"
    ],
    "searchStrings": [],
    "placeIds": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("bgfc97/google-maps-reviews-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 = {
    "startUrls": ["https://www.google.com/maps/place/Katz's+Delicatessen/@40.722233,-73.987429,17z/data=!4m6!3m5!1s0x89c2598f7ff4aa09:0x313547e757cb8cea"],
    "searchStrings": [],
    "placeIds": [],
}

# Run the Actor and wait for it to finish
run = client.actor("bgfc97/google-maps-reviews-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 '{
  "startUrls": [
    "https://www.google.com/maps/place/Katz'\''s+Delicatessen/@40.722233,-73.987429,17z/data=!4m6!3m5!1s0x89c2598f7ff4aa09:0x313547e757cb8cea"
  ],
  "searchStrings": [],
  "placeIds": []
}' |
apify call bgfc97/google-maps-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bgfc97/google-maps-reviews-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/nEIY9M9aIGjxNgxkq/builds/LyL2ZM81iJLfaIHdr/openapi.json
