# Google Maps Reviews Scraper & Sentiment Analyzer (`datascraperes/google-maps-review-analyzer`) Actor

Scrape and analyze public Google Maps reviews from up to 10 business URLs. Get multilingual positive, neutral, and negative sentiment, confidence scores, rating breakdowns, and structured JSON. Pay only for reviews analyzed.

- **URL**: https://apify.com/datascraperes/google-maps-review-analyzer.md
- **Developed by:** [DataScraperES](https://apify.com/datascraperes) (community)
- **Categories:** AI, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 review analyzeds

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

Scrape and analyze public Google Maps reviews with multilingual sentiment classification. **Submit up to 10 business URLs and receive one structured Dataset item per business** with positive, neutral, and negative distributions plus review-level confidence values.

### What this Actor does

Analyze public Google Maps reviews from one or more business listing URLs and receive one compact sentiment report per business. The Actor resolves each business over HTTPS, collects a bounded set of unique reviews, classifies each review as `positive`, `neutral`, or `negative`, and returns counts, percentages, confidence values, and per-review labels.

The default analysis uses the open-source [clapAI/mmBERT-small-multilingual-sentiment](https://huggingface.co/clapAI/mmBERT-small-multilingual-sentiment) checkpoint. It is designed for multilingual sentiment classification and supports the languages documented by its model card. The Actor does not use a generative LLM, does not create business-specific categories, and does not write narrative summaries.

The model runs as reviews are collected. If a review has no text, its rating is used as a clearly marked fallback. The output identifies whether each result came from the model or that fallback.

### Use cases

- Measure the positive, neutral, and negative share of a local business's reviews.
- Compare text sentiment with the star ratings shown on Google Maps.
- Feed review sentiment into SEO reports, CRMs, dashboards, or monitoring workflows.
- Process businesses in different countries without maintaining a category list for each industry.
- Retain only review identifiers, ratings, sentiment, and confidence instead of reviewer profiles or raw text.

### How to use

1. Open the Actor in Apify Console.
2. Add one business URL on one line, or add several lines for a batch.
3. Set the maximum number of reviews per business.
4. Click **Start** and open the default Dataset when the run finishes.

### Input

The Actor has one URL field: `urls`. It supports both ways users normally run the Actor without making them choose between overlapping inputs:

- **One business:** add one Google Maps business URL on one line. The Actor returns one Dataset item.
- **Several businesses:** add one URL per line, up to 10 different businesses. The Actor processes them in the same order and returns one Dataset item per business.

Do not add a separate `url` property. The only accepted URL property is the `urls` array, even when it contains just one entry.

Every entry must be a complete HTTPS Google Maps business listing URL. The following are the two most common supported formats. They are alternatives: choose the format you have and always place it inside the same `urls` array.

#### Example 1: Google Maps URL with a Place ID

Use this format when you already have a Google Place ID:

```json
{
  "urls": [
    "https://www.google.com/maps/place/?q=place_id:ChIJ--511_65pBIR4Tl2-D4grUw"
  ],
  "maxReviews": 5,
  "sort": "recent",
  "language": "es",
  "country": "ES",
  "includeRawReviews": false
}
```

#### Example 2: Full Google Maps business listing URL

Use the complete URL copied from an open Google Maps business listing. Long parameters such as coordinates and `/data=...` are supported:

```json
{
  "urls": [
    "https://www.google.com/maps/place/Walmart+Supercenter/@40.6607799,-73.726629,17z/data=!3m1!4b1!4m6!3m5!1s0x89c264150e65d803:0x17efe5921b20790f!8m2!3d40.6607799!4d-73.726629!16s%2Fg%2F1tdkhkzl?authuser=0&hl=en&entry=ttu&g_ep=EgoyMDI2MDgxOS4wIKXMDSoASAFQAw%3D%3D"
  ],
  "maxReviews": 5,
  "sort": "recent",
  "language": "en",
  "country": "US",
  "includeRawReviews": false
}
```

Standard `/maps/place/` URLs, `maps.app.goo.gl` shared links, `goo.gl/maps` links, and supported Maps URLs containing `place_id`, `cid`, or `ludocid` identifiers are also accepted. Normal Google Search URLs, Maps searches that do not identify one business, directions, user contribution/profile URLs, non-Google domains, HTTP links, empty values, and duplicate URLs are rejected before collection starts.

For a batch, add up to 10 different business URLs to the same `urls` array. You may mix supported URL formats in one run. Do not paste the two complete JSON examples one after another; submit one JSON object containing all the URLs you want to analyze.

`maxReviews` defaults to `100` and accepts `1` to `500` unique reviews per business. `sort` defaults to `recent` and accepts `relevance`, `recent`, `highest`, or `lowest`. `language` and `country` localize the Google Maps request and default to `es` and `ES`; they do not restrict the language of the review text.

Sentiment is always analyzed with the bundled multilingual model. The Actor processes review text as it is collected; rows without text use the star rating as an explicitly marked fallback. `includeRawReviews` defaults to `false`; when enabled, the result also includes normalized review IDs, dates, timestamps, ratings, and text. Author names, profiles, avatars, and profile URLs are not included.

The complete output example below was produced from the full business listing URL shown in Example 2.

### Output

The default Dataset contains one aggregate item per unique submitted business URL. `place.inputUrl` identifies the business that produced the row. `place` contains the resolved Place ID, business name, rating, total review count, and one-to-five-star distribution when Google exposes them. `collection` reports the customer-facing collection status and review coverage, `sentiment` contains the aggregate values, and `reviewSentiments` contains one compact classification per collected review without raw text. Internal transport diagnostics are not included in Dataset items. Businesses are processed in input order and each completed row is pushed independently.

The sentiment summary contains `distribution`, `percentages`, `averageConfidence`, `reviewsAnalyzed`, `textReviewsAnalyzed`, `reviewsWithoutText`, `modelUsed`, `fallbackUsed`, and `warnings`. Each item in `reviewSentiments` contains `reviewId`, `rating`, `sentiment`, `confidence`, `source`, and `textAvailable`.

This is a complete Dataset item from a successful analysis:

```json
{
  "place": {
    "inputUrl": "https://www.google.com/maps/place/Walmart+Supercenter/@40.6607799,-73.726629,17z/data=!3m1!4b1!4m6!3m5!1s0x89c264150e65d803:0x17efe5921b20790f!8m2!3d40.6607799!4d-73.726629!16s%2Fg%2F1tdkhkzl?authuser=0&hl=en&entry=ttu&g_ep=EgoyMDI2MDgxOS4wIKXMDSoASAFQAw%3D%3D",
    "resolvedUrl": "https://www.google.com/maps/place/Walmart+Supercenter/@40.6607799,-73.726629,17z/data=!3m1!4b1!4m6!3m5!1s0x89c264150e65d803:0x17efe5921b20790f!8m2!3d40.6607799!4d-73.726629!16s%2Fg%2F1tdkhkzl?authuser=0&hl=en&entry=ttu&g_ep=EgoyMDI2MDgxOS4wIKXMDSoASAFQAw%3D%3D",
    "placeId": "ChIJA9hlDhVkwokRD3kgG5Ll7xc",
    "name": "Walmart Supercenter",
    "rating": 3.9,
    "totalReviews": 24133,
    "ratingDistribution": {
      "1": 2575,
      "2": 1378,
      "3": 2952,
      "4": 5162,
      "5": 12066
    }
  },
  "collection": {
    "status": "ok",
    "requested": 5,
    "collected": 5,
    "uniqueCollected": 5,
    "sort": "recent"
  },
  "sentiment": {
    "mode": "multilingual_model",
    "modelUsed": true,
    "model": "clapAI/mmBERT-small-multilingual-sentiment",
    "reviewsAnalyzed": 5,
    "textReviewsAnalyzed": 5,
    "reviewsWithoutText": 0,
    "fallbackUsed": false,
    "distribution": {
      "positive": 3,
      "neutral": 2,
      "negative": 0
    },
    "percentages": {
      "positive": 60,
      "neutral": 40,
      "negative": 0
    },
    "averageConfidence": 0.778575,
    "warnings": []
  },
  "reviewSentiments": [
    {
      "reviewId": "Ci9DQUlRQUNvZENodHljRjlvT25oUE9YWkdlVkJzVm13eVoyNTVYM014WlhScGMxRRAB",
      "rating": 5,
      "sentiment": "neutral",
      "confidence": 0.473044,
      "source": "multilingual_model",
      "textAvailable": true
    },
    {
      "reviewId": "Ci9DQUlRQUNvZENodHljRjlvT2tnd1oyMUdiMmQxU3pBek1rYzNjMlZXVFhkdVNGRRAB",
      "rating": 4,
      "sentiment": "neutral",
      "confidence": 0.695602,
      "source": "multilingual_model",
      "textAvailable": true
    },
    {
      "reviewId": "Ci9DQUlRQUNvZENodHljRjlvT21ab1owRnRhWFoxZDFCb2VuSjFiVkpzUzBoQ2JVRRAB",
      "rating": 5,
      "sentiment": "positive",
      "confidence": 0.794851,
      "source": "multilingual_model",
      "textAvailable": true
    },
    {
      "reviewId": "Ci9DQUlRQUNvZENodHljRjlvT2t0aGRHSjVSRE15UVVkd1QxRlJUalJJZUhkRFNXYxAB",
      "rating": 5,
      "sentiment": "positive",
      "confidence": 0.959329,
      "source": "multilingual_model",
      "textAvailable": true
    },
    {
      "reviewId": "Ci9DQUlRQUNvZENodHljRjlvT25wUVJVTmhURTl2UkRnNE1IcGxRWFYzZWtoZlExRRAB",
      "rating": 5,
      "sentiment": "positive",
      "confidence": 0.970048,
      "source": "multilingual_model",
      "textAvailable": true
    }
  ],
  "quality": {
    "textCoverage": 1,
    "ratingCoverage": 1,
    "absoluteTimestampCoverage": 0,
    "deduplicated": true
  },
  "analysis": {
    "mode": "multilingual_model",
    "llmUsed": false,
    "method": "basic_multilingual_sentiment",
    "reviewsObserved": 5,
    "warnings": [],
    "modelUsed": true,
    "limitations": [
      "Sentiment is limited to positive, neutral, and negative labels.",
      "Rows without text use the star rating as a fallback.",
      "The model confidence is not a calibrated probability."
    ]
  }
}
```

Results can be inspected in the Dataset or exported in the formats supported by Apify. Review text is not returned unless `includeRawReviews` is enabled.

### Pricing

This Actor uses pay-per-event pricing. Apify automatically applies the rate for your account tier:

| Apify tier | Price per analyzed review | Price per 1,000 reviews |
|---|---:|---:|
| FREE | $0.001 | $1.00 |
| BRONZE | $0.0009 | $0.90 |
| SILVER | $0.0008 | $0.80 |
| GOLD | $0.00075 | $0.75 |
| PLATINUM | $0.00075 | $0.75 |
| DIAMOND | $0.00075 | $0.75 |

There is no additional charge per business, Actor start, or Dataset item, and platform usage is included in the event price.

A `review-analyzed` event is charged only for a review included in a delivered Dataset result. Zero-review, blocked, unresolved, and error results are not charged. If a business yields fewer reviews than requested, only the reviews actually analyzed and delivered are charged.

You can set a maximum total charge for the run in Apify. The Actor checks the remaining paid capacity before collecting each business and may return fewer reviews when that limit is reached, so the run does not intentionally analyze more paid reviews than the configured budget allows.

### API and integrations

Run the Actor from Apify Console, the REST API, Apify clients, CLI, Tasks, Schedules, or webhooks. Use `place.placeId` when it is available as a stable key for comparing repeated runs. Use `sentiment.distribution` and `sentiment.percentages` for aggregate reporting, or `reviewSentiments` for row-level integrations.

### Related Actors

| Actor | Best for |
|---|---|
| [Google Maps Business Scraper | $1 per 1,000](https://apify.com/datascraperes/actor-google-maps) | Discovering Google Maps business listings by location and category before selecting individual businesses for review analysis. |
| [Google SERP Scraper API – Search Results Scraper](https://apify.com/datascraperes/google-serp-scraper) | Comparing review sentiment with the business's organic Google visibility for selected searches. |
| [Similarweb Website Traffic & SEO Analytics Scraper](https://apify.com/datascraperes/similarweb-website-scraper) | Adding estimated traffic and SEO context to a business website found from its Google Maps listing. |

### Limits and data quality

- One run requires `urls` with 1 to 10 different Google Maps business URLs and accepts up to 500 requested reviews per business.
- The Actor processes businesses sequentially and reuses one sentiment-model instance; it does not multiply model memory by the number of URLs.
- Google Maps URLs and response structures can change. The result reports statuses such as `partial`, `blocked`, `not_found`, or `ambiguous` when collection cannot be verified.
- `collected` is the number of unique reviews returned by the source, not a guarantee that it equals the business's total review count.
- The bundled multilingual model classifies available review text. Rows without text are counted with their rating and marked with `source: "rating_fallback"`.
- The model returns three sentiment classes. `confidence` is the model's top-class score and is not a calibrated probability or a guarantee of correctness.
- A review can contain mixed opinions, sarcasm, multiple languages, or culturally specific wording. Validate results before using them for high-impact decisions.
- The rating fallback is deterministic and uses only star ratings for reviews where no text is available; it does not replace the model analysis.
- Raw reviews are disabled by default. When enabled, review text may contain personal information written by third parties.
- Source availability, localization, rate limits, and network conditions can affect review coverage.

### Frequently asked questions

#### Do I need to provide a Google `place_id`?

No. Provide the normal public business listing URL. The Actor attempts to resolve the available business identifier over HTTPS. A URL that does not identify one unique listing can return an `ambiguous` or `not_found` status.

#### Does this Actor use a browser or generative LLM?

No. Review extraction uses direct HTTPS requests and the single analysis flow uses a local open-source text-classification model. The output explicitly reports `llmUsed: false`.

#### How is sentiment analyzed?

The Actor uses one bundled multilingual text-classification model and returns positive, neutral, or negative with a confidence score. Reviews without text use their star rating as a clearly marked fallback.

#### Can I analyze multiple businesses in one run?

Yes. Add one URL per line in `urls`, up to 10 different businesses. The Dataset receives one independent result per URL, in input order. If one business cannot be resolved or collected, its status is reported in that row and the remaining URLs continue processing.

#### Why did I receive fewer reviews than requested?

Google Maps may expose fewer reviews in the selected order, stop returning additional reviews, or temporarily restrict a request. The Actor can also cap collection at the run's maximum total charge. Inspect `collection.status`, `collection.requested`, and `collection.collected` instead of treating a short result as proof that the business has no more reviews.

#### How do I limit the maximum cost?

Set the maximum total charge when starting the run in Apify. The number of reviews covered depends on your account tier; for example, a `$0.10` limit covers up to 100 reviews on FREE or more on a discounted tier. When the remaining budget cannot cover another review at the safest applicable rate, the Actor stops before performing additional paid collection.

#### Are individual reviews included by default?

The default output includes compact review IDs, ratings, sentiment, and confidence. Raw review text and timestamps are included only when `includeRawReviews` is enabled.

### Responsible use

Use this Actor only for lawful purposes and in accordance with applicable laws, privacy obligations, database rights, and the terms governing Google Maps data. You are responsible for determining whether collecting, storing, analyzing, and redistributing review content is permitted for your use case.

Minimize retained personal data, protect exported Datasets, avoid excessive collection, and honor applicable deletion or opt-out requests. Review text can contain personal information written by third parties even when author fields are omitted.

### Support

If a run returns an unexpected status or output, open an issue in the Actor's **Issues** tab with the run ID, a sanitized input URL, `collection.status`, and the observed behavior. Do not post API tokens, cookies, credentials, or private review content.

# Actor input Schema

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

Each line must contain one complete HTTPS Google Maps business listing URL. Standard /maps/place/ links, maps.app.goo.gl short links, and goo.gl/maps links are accepted. Add one line for a single business or up to 10 different lines for batch processing. Duplicate URLs are rejected.

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

Maximum number of unique reviews to collect and analyze incrementally.

## `sort` (type: `string`):

Order requested from the Google Maps review endpoint.

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

Two-letter language code used in Google Maps requests.

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

Two-letter country code used to localize Google Maps requests.

## `includeRawReviews` (type: `boolean`):

Include normalized review IDs, dates, ratings, and text in the Dataset item. Disabled by default to minimize personal data.

## Actor input object example

```json
{
  "urls": [
    "https://www.google.com/maps/place/?q=place_id:ChIJ--511_65pBIR4Tl2-D4grUw"
  ],
  "maxReviews": 5,
  "sort": "recent",
  "language": "es",
  "country": "ES",
  "includeRawReviews": false
}
```

# Actor output Schema

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

One analysis result with place metadata, collection status, basic multilingual sentiment values, and optional normalized reviews.

# 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": [
        "https://www.google.com/maps/place/?q=place_id:ChIJ--511_65pBIR4Tl2-D4grUw"
    ],
    "maxReviews": 5,
    "sort": "recent",
    "language": "es",
    "country": "ES",
    "includeRawReviews": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("datascraperes/google-maps-review-analyzer").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": ["https://www.google.com/maps/place/?q=place_id:ChIJ--511_65pBIR4Tl2-D4grUw"],
    "maxReviews": 5,
    "sort": "recent",
    "language": "es",
    "country": "ES",
    "includeRawReviews": False,
}

# Run the Actor and wait for it to finish
run = client.actor("datascraperes/google-maps-review-analyzer").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": [
    "https://www.google.com/maps/place/?q=place_id:ChIJ--511_65pBIR4Tl2-D4grUw"
  ],
  "maxReviews": 5,
  "sort": "recent",
  "language": "es",
  "country": "ES",
  "includeRawReviews": false
}' |
apify call datascraperes/google-maps-review-analyzer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datascraperes/google-maps-review-analyzer"
        }
    }
}

```

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/coycebMM2Z6OT6FKG/builds/b6D4F9e4SRY9pnYwx/openapi.json
