# Google Maps Reviews Scraper - Text, Ratings & Replies (`scrapesage/google-reviews-scraper`) Actor

Scrape Google Maps reviews for any place: full review text, star rating, reviewer and Local Guide status, exact dates, owner replies, review photos and detailed food/service ratings. Give it a Maps link, a place ID, or a search term. Filter by rating or keyword before you pay.

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

## Pricing

from $0.33 / 1,000 review 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/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 Reviews Scraper - Text, Ratings & Replies

> **Disclaimer:** This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Google LLC or any of its subsidiaries. All trademarks mentioned are the property of their respective owners. "Google Maps" is referenced only to describe the publicly available website this Actor collects data from.

Scrape **Google Maps reviews** for any place and export them to JSON, CSV or Excel: the **full review text**, star rating, reviewer name and profile, Local Guide status, the **exact publish date**, the **owner's reply**, review photos, and Google's own **detailed ratings** (food, service, atmosphere, price range) where the place has them.

Point it at a Maps link, a place ID, or just a search term. **No API key, no login, no browser** - and you filter by star rating, keyword or owner reply **before** anything is charged.

### Why this Google reviews scraper?

It reads Google's own public review feed over plain HTTP, so there is no browser to pay for and no residential proxy to configure - which is why it can be priced per review instead of per page load. And the columns most review scrapers drop are the ones you need for real analysis: exact timestamps, owner replies and the per-aspect ratings.

| Data | Typical scrapers | This Actor |
|---|---|---|
| Review text, star rating, reviewer name | ✅ | ✅ |
| **Untruncated text** - no "More" button left unexpanded | partial | ✅ |
| **Exact ISO publish + update timestamps** | ❌ "3 months ago" | ✅ |
| Original review language | ❌ | ✅ |
| **Owner reply text and reply date** | ❌ | ✅ |
| Local Guide status and level, reviewer review/photo counts | ❌ | ✅ |
| **Detailed ratings** - food, service, atmosphere, price per person | ❌ | ✅ |
| Review photos with dimensions and captions | ❌ | ✅ |
| Direct link back to the review | ❌ | ✅ |
| Place summary row with the 1-5 star histogram | ❌ | ✅ opt-in |
| Filter by rating, keyword or owner reply **before** billing | ❌ | ✅ |
| Monitor mode - only new reviews | ❌ | ✅ |

### What you get

Every review row carries:

| Field | Notes |
|---|---|
| `text` | the full review, untruncated - no "More" button to expand |
| `rating` | 1-5 stars |
| `publishedAtDate` / `updatedAtDate` | **exact ISO timestamps**, not "3 months ago" |
| `publishedAtText` | Google's own relative wording, kept alongside |
| `originalLanguage` | the language the review was written in |
| `reviewerName`, `reviewerUrl`, `reviewerId`, `reviewerPhotoUrl` | the public profile |
| `reviewerNumberOfReviews`, `reviewerNumberOfPhotos`, `isLocalGuide`, `localGuideLevel` | how much weight the reviewer carries |
| `ownerReplyText`, `ownerReplyDate`, `hasOwnerReply` | the business response |
| `photos`, `photoUrls`, `photoCount` | review photos with dimensions and captions |
| `reviewDetailedRating` | e.g. `{"Food": 4, "Service": 5, "Price per person": "$10-20"}` |
| `reviewUrl` | a direct link back to the review on Google |

Switch on **Include a place summary row** and each place also returns one `place` row: overall score, total review count, address, category, phone, website, coordinates, and the 1-5 star histogram in counts and percentages.

### Use cases

- **Reputation monitoring** - a scheduled run with monitor mode emails or Slacks you only the reviews that arrived since last time.
- **Complaint analysis** - filter to 1- and 2-star reviews and feed the text straight into a sentiment or topic model.
- **Multi-location and franchise reporting** - paste a list of place IDs and get one comparable table across every branch, with per-aspect ratings.
- **Competitor benchmarking** - pull rivals' reviews and compare rating trends, response rates and what customers actually complain about.
- **Support-quality auditing** - `hasOwnerReply` and `ownerReplyDate` show how fast, and how often, each location actually replies.
- **LLM and analytics pipelines** - clean review text with real dates attached, ready to load without parsing HTML.

### How to use

1. [Sign up for Apify](https://console.apify.com/sign-up) - the free plan is enough to try this Actor.
2. Put one or more places in **Place URLs or IDs**. All of these work:
   - a Maps link - `https://www.google.com/maps/place/...`
   - a share link - `https://maps.app.goo.gl/...`
   - a place ID - `ChIJ3UFdD2KAhYARYOHf4j7DshM` or `place_id:ChIJ...`
   - a feature ID - `0x808580620f5d41dd:0x13b2c33ee2dfe160`
   - a CID - `1419411507436839264`
3. Or paste a whole list into **Import places from a file**, or link a `.txt`/`.csv`/Google Sheet/Drive file. Or skip links entirely and use **Search terms** (plus an optional **Search location**) to find places by name.
4. Set **Max reviews per place** and **Sort reviews by**, click **Start**, then **export** as JSON, CSV, Excel, XML or RSS - or pull results through the [Apify API](https://docs.apify.com/api/v2).

Leave the input empty and the Actor runs a small sample so you can see the output shape before committing to a big job.

#### Sorting

`newest` (default), `relevance`, `highest` or `lowest`. Sorting is done by Google, so `newest` really is the newest review first - useful for monitoring, and for capping a run at "the last 100 reviews" without pulling a place's whole history.

#### Filters - applied before you are charged

- **Star ratings** - keep only the ratings you care about (e.g. just 1 and 2 for complaint analysis)
- **Review text contains** - keep only reviews mentioning a word or phrase
- **Only reviews with an owner reply**

Filtered-out reviews are never charged.

#### Monitor mode

Switch on **Monitor mode** and the Actor remembers every review ID it has already returned, so a scheduled run emits **only genuinely new reviews** - and charges for nothing else. Ideal for a daily or hourly reputation alert.

### Output

One row per review, plus an optional `place` row per place:

```json
{
    "type": "review",
    "reviewId": "Ci9DQUlRQUNvZENodHljRjlvT2xCS...",
    "placeName": "Blue Bottle Coffee",
    "placeAddress": "115 Sansome St, San Francisco, CA 94104",
    "rating": 2,
    "text": "Quite terrible. Ridiculously overpriced, even by \"stereotypical SF professional cafe\" standards...",
    "originalLanguage": "en",
    "publishedAtDate": "2025-09-11T16:50:42.536Z",
    "publishedAtText": "11 months ago",
    "reviewerName": "Danann Paris",
    "reviewerNumberOfReviews": 147,
    "isLocalGuide": true,
    "localGuideLevel": 6,
    "hasOwnerReply": false,
    "photoCount": 0,
    "reviewUrl": "https://www.google.com/maps/reviews/data=..."
}
```

### Good to know

- **Google serves reviews in pages of 20.** Deep history is fine, it just takes more pages.
- **`reviewsDistribution` is the histogram of the reviews this run collected**, and `reviewsDistributionBasis` tells you whether that is the place's complete set or only what you asked for. Google does not publish its own histogram on any endpoint this Actor can reach, so it is calculated rather than copied - raise **Max reviews per place** high enough to reach the end and the two are the same thing.
- **`reviewsCount` is exact when the run reaches the end of a place's reviews** (`reviewsCountIsExact: true`). If you stop short, the Actor asks Google's public place feed for the headline total - and that feed publishes the number only some of the time, so `reviewsCount` can be `null` on a partial run. `reviewsFetched` is always exact.
- **Reviews with no text still come back** (rating, reviewer, date); that is how Google stores them.
- **A place with no reviews returns a `place` row and no `review` rows**, and says so in the run status.

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

This Actor uses Apify's **pay-per-event** pricing: you are charged only for the results it delivers, with no monthly rental and no start fee. The events it can charge are:

- **Review scraped** - Charged once per Google Maps review written to your dataset - full text, star rating, reviewer name and profile, Local Guide status, date, owner reply and any review photos. Reviews removed by your filters, reviews already seen in monitor mode, and places that could not be opened are never charged.
- **Place summary** - Charged once per place when the summary row is switched on - overall score, total review count, address, category and the 1-5 star histogram in counts and percentages. Turn off 'Include a place summary row' to skip it entirely.

The current price of each event is shown on the **Pricing** tab of this page. Set a maximum total charge on the run if you want a hard cap on spend, and use the input limits to control how much the Actor fetches.

### Automate & schedule

Run this Actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** - start runs, fetch datasets and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** - official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** - run it hourly, daily or weekly and keep your dataset current.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** - trigger downstream actions (CRM import, Slack alert, email sequence) the moment a run finishes.

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/google-reviews-scraper').call({
    "placeUrls": [
        "https://www.google.com/maps/place/?q=place_id:ChIJ3UFdD2KAhYARYOHf4j7DshM"
    ],
    "maxReviewsPerPlace": 60,
    "sortBy": "newest",
    "includePlaceSummary": true
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} records`);
```

### Integrate with any app

Connect the dataset to thousands of apps - no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** - multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** - push new records straight into your CRM or spreadsheet.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** - get notified when a scheduled run finds something new.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** - auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** - pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** - trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. You can call this Actor from Claude, ChatGPT or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** - describe the data you need and let the assistant run this Actor for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Related Actors in the same category:

- **[Google Maps Scraper](https://apify.com/scrapesage/google-maps-scraper)** - Places, Leads & Contacts
- **[Trustpilot Scraper](https://apify.com/scrapesage/trustpilot-scraper)** - Company Profiles, Reviews & Leads
- **[BBB Scraper](https://apify.com/scrapesage/bbb-scraper)** - Business Leads, Ratings & Accreditation
- **[Thumbtack Scraper](https://apify.com/scrapesage/thumbtack-scraper)** - Home Service Pros, Reviews & Leads
- **[Google Play Reviews Scraper](https://apify.com/scrapesage/google-play-reviews-scraper)** - Ratings, Replies & History

### Tips

- **Cap, don't crawl.** For monitoring, `newest` plus a small **Max reviews per place** is far cheaper than pulling a place's whole history every day - and monitor mode makes sure you never pay for the same review twice.
- **One place ID per branch.** Feature IDs and CIDs are stable, so a saved list of them keeps multi-location reports comparable over time.
- **Complaint pipelines.** Combine the 1-2 star filter with *Review text contains* to isolate a single recurring issue.
- **Response-rate reporting.** Keep `hasOwnerReply` and `ownerReplyDate` and you can report reply rate and median reply time per location straight from the export.
- **Pair it with the [Google Maps Scraper](https://apify.com/scrapesage/google-maps-scraper)** to build the place list first, then feed the place IDs in here.

### FAQ

**How is this Actor billed?** Pay-per-event: you pay only for the results it delivers, with no monthly rental and no start fee. The per-event price is shown on the Pricing tab.

**Can I schedule it and get results automatically?** Yes - create a [Schedule](https://docs.apify.com/platform/schedules) and add a [webhook](https://docs.apify.com/platform/integrations/webhooks) or an integration (Google Sheets, Slack, Make, Zapier) to push each run's dataset wherever you need it.

**Which export formats are available?** Every run's dataset can be downloaded as JSON, CSV, Excel (XLSX), XML, HTML or RSS from the Apify Console or the API.

**Can I run it from code or an AI agent?** Yes - through the [Apify API](https://docs.apify.com/api/v2) and client libraries, or from Claude, ChatGPT and other assistants via the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp).

**Is it legal to scrape Google Maps?** This Actor collects publicly available data only. You are responsible for using the output in compliance with applicable laws (including data-protection law where personal data is involved) and the source's terms. See **Data & lawful use** and the **Disclaimer** below.

**Is this an official Google Maps tool?** No. It is an independent, third-party Actor with no affiliation to, endorsement by or sponsorship from Google LLC. See the **Disclaimer** below.

### Data & lawful use

This Actor reads only what Google Maps publishes to logged-out visitors: it does not log in, create accounts, or reach anything behind a sign-in. It keeps the ordinary anonymous cookies Google Maps itself sets, because the public review feed needs them to page consistently; no account, login or session token is ever used. Names, handles, bios and engagement figures are public, but they relate to identifiable people, so treat the output as personal data. If you are in the EU or UK you are the data controller for what you do with it: have a lawful basis (usually legitimate interest for research, marketing analytics or B2B prospecting), honour access and deletion requests, and do not use the output for spam or unsolicited messaging.

Under [Apify's Standard Actor Contract](https://docs.apify.com/legal/standard-actor-contract), which governs your use of this Actor, you are the controller of any personal data in your input and output and scrapesage acts only as your processor: that data is processed solely to run your job, written only to your own Apify storage, never used for any other purpose and never shared onward. If you need help with a data-subject request that involves this Actor's output, open an issue on the Issues tab.

### Disclaimer

**This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Google LLC or any of its subsidiaries. All trademarks mentioned are the property of their respective owners.**

"Google Maps" and any related marks are the property of their respective owners and are used here only in a descriptive, nominative sense - to identify the publicly accessible website from which this Actor collects data. This Actor is not an official Google Maps product, is not authorised or certified by Google LLC, and does not distribute Google Maps software. It collects only publicly available information; you are responsible for ensuring your use of that data complies with applicable laws, regulations and the terms of the source website.

### Need help?

Open an issue on the Actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome - this Actor is actively maintained.

# Actor input Schema

## `placeUrls` (type: `array`):

The places to pull reviews for. Accepts a Google Maps place URL, a share link, a place ID (`ChIJ...`), a `place_id:...` string, a feature ID (`0x...:0x...`) or a CID. One per row.

## `urlsFromFile` (type: `string`):

Bulk import. Paste a block of place URLs or IDs (one per line), **or** paste a single link to a `.txt` / `.csv` / Google Sheet / Google Drive / Apify key-value-store file holding them.

## `searchTerms` (type: `array`):

Find places on Google Maps and pull their reviews - use this when you do not have the URL. Example: `dentist`, `Blue Bottle Coffee`. Discovery uses a keyless data feed, so it costs no extra browser time.

## `searchLocation` (type: `string`):

City or area to centre the search on, e.g. `Austin, TX`. Only used with *Search terms*.

## `maxPlacesPerSearchTerm` (type: `integer`):

How many matching places to take reviews from, for each search term.

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

Upper limit per place. Google loads reviews in batches as the panel scrolls, so a large number takes proportionally longer - the Actor stops cleanly when the run time budget is nearly spent and says so.

## `sortBy` (type: `string`):

Order Google returns reviews in. *Newest* is the default because it is what most monitoring workflows want.

## `ratings` (type: `array`):

Keep only these star ratings. Leave empty for all. Filtered reviews are **never charged**.

## `containsText` (type: `string`):

Keep only reviews whose text contains this phrase (case-insensitive), e.g. `parking`, `rude`, `wait`.

## `onlyWithOwnerReply` (type: `boolean`):

Keep only reviews the business publicly answered - the fastest way to study how a competitor handles complaints.

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

On by default: one row per review.

## `includePlaceSummary` (type: `boolean`):

Adds one `place` row per place: overall score, total review count and the **1-5 star histogram** in counts and percentages. Charged as `place`.

## `outputFields` (type: `array`):

Trim the export to just these columns. Leave empty for every field.

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

Google Maps interface language, e.g. `en`, `es`, `de`. Affects the review dates and which translations Google shows.

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

Two-letter country Google should serve, e.g. `us`, `gb`, `de`.

## `monitorMode` (type: `boolean`):

Remembers review IDs between runs and emits only reviews it has not seen. Pair with an Apify Schedule to watch a location continuously.

## `monitorStoreName` (type: `string`):

Named key-value store holding the remembered review IDs. Use a different name per tracked place set.

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

How many place pages to render in parallel. Each one is a real browser tab, so keep this low.

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

Apify Proxy. The datacenter pool that ships with every plan is enough - this Actor talks to Google over a plain HTTP API, so it does not need residential traffic.

## Actor input object example

```json
{
  "placeUrls": [
    "https://www.google.com/maps/place/?q=place_id:ChIJ3UFdD2KAhYARYOHf4j7DshM"
  ],
  "maxPlacesPerSearchTerm": 3,
  "maxReviewsPerPlace": 100,
  "sortBy": "newest",
  "onlyWithOwnerReply": false,
  "includeReviews": true,
  "includePlaceSummary": true,
  "language": "en",
  "countryCode": "us",
  "monitorMode": false,
  "monitorStoreName": "google-reviews-monitor",
  "maxConcurrency": 2,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Every review and place summary collected in this 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 = {
    "placeUrls": [
        "https://www.google.com/maps/place/?q=place_id:ChIJ3UFdD2KAhYARYOHf4j7DshM"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/google-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 = { "placeUrls": ["https://www.google.com/maps/place/?q=place_id:ChIJ3UFdD2KAhYARYOHf4j7DshM"] }

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/google-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 '{
  "placeUrls": [
    "https://www.google.com/maps/place/?q=place_id:ChIJ3UFdD2KAhYARYOHf4j7DshM"
  ]
}' |
apify call scrapesage/google-reviews-scraper --silent --output-dataset

```

## MCP server setup

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