Google Maps Reviews Scraper with Sentiment & Replies avatar

Google Maps Reviews Scraper with Sentiment & Replies

Pricing

from $0.18 / 1,000 results

Go to Apify Store
Google Maps Reviews Scraper with Sentiment & Replies

Google Maps Reviews Scraper with Sentiment & Replies

Scrape Google Maps reviews with star rating, text, date, reviewer name, owner-reply detection, reply latency in days and star-anchored sentiment. Filter unanswered or by star rating. Export to JSON, CSV or Excel. From $0.18 per 1,000 results.

Pricing

from $0.18 / 1,000 results

Rating

0.0

(0)

Developer

Alexandre Manguis

Alexandre Manguis

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

15 days ago

Last modified

Share

Google Maps Reviews Scraper with Sentiment & Owner-Reply Tracking

Scrape Google Maps reviews for any public place and get them back reputation-ready: star rating, text, date, reviewer info, owner-reply detection, reply latency in days, star-anchored sentiment, and a needsResponse flag — no post-processing code required. Export to JSON, CSV or Excel.

What it does

This Actor collects the publicly visible reviews shown on a Google Maps place page (one or many places per run) and, for each review, computes the fields a reputation-management workflow actually needs:

  • Whether the owner replied, and how long it took (ownerReplied, ownerReplyText, replyLatencyDays). Google exposes no exact timestamp for replies, only a coarse relative label (e.g. "a week ago"); replyLatencyDays is therefore an approximation whose error grows with the reply's age, and null when it can't be placed reliably.
  • A sentiment label and score derived from the star rating (plus a lexicon fallback for common English words), so you don't need to call an LLM or a sentiment API per review.
  • A needsResponse flag: true when a review is negative/neutral and unanswered — the exact triage filter an agency needs.
  • Server-side filters (onlyUnanswered, minStars/maxStars, reviewsNewerThan) so you pay only for the reviews that matter to you.

Most low-cost Google Maps review scrapers return the raw star/text/date dump and leave sentiment, reply-matching and latency to you. This Actor does that work locally, for free, as part of the same run.

Each run returns up to 60 of the newest reviews per place (Google's own review-list response is capped at 60 regardless of what you request — see FAQ). This is designed for recurring reputation monitoring (schedule a run + reviewsNewerThan), not a one-off full historical export.

Who is it for / use cases

  • Reputation-management & local-SEO agencies tracking several client locations who need a weekly report: rating trend, sentiment mix, unanswered count, median reply latency.
  • Multi-location businesses (restaurant, retail, clinic chains) that want to list every negative review with ownerReplied=false older than N days, per location — an SLA tracking view.
  • AI reply-drafting / RAG pipeline builders who need clean, sentiment-tagged, reply-aware review data to feed an agent that drafts owner responses.
  • Competitive benchmarking: compare sentiment mix and reply responsiveness of a business against nearby competitors' public reviews.

Features

  • Collects reviews from one or many Google Maps place URLs in a single run.
  • Sort by newest, most relevant, highest or lowest rating.
  • Filter by star range, text-only reviews, unanswered reviews, or a minimum publish date (reviewsNewerThan) — filtering happens before billing, so filtered-out rows are never charged.
  • Owner-reply detection with reply latency in days (approximate — see note above, Google gives no exact timestamp for replies).
  • Local, rule-based sentiment (positive/neutral/negative) anchored on the star rating, with a documented lexicon fallback — no external API cost, no per-review charge.
  • Data-minimisation default: reviewer profile URL and contribution count are null unless you explicitly opt in (includeReviewerProfile).
  • Structured skip rows (skipped: true, skipReason, no billing event) for invalid URLs or places with zero reviews — the run still succeeds.

Input

FieldTypeDefaultDescription
placeUrlsarray of string (required)—Google Maps place URLs to collect reviews from. Accepts both the ?q=place_id:... form and the @lat,lng/data=...!1s0x... form.
maxReviewsPerPlaceinteger50Max reviews collected per place, capped at 60: Google's review-list endpoint returns at most 60 reviews per response regardless of this value, and its pagination token does not work over plain HTTP (see FAQ).
maxResultsinteger200Hard cap on total reviews pushed to the dataset across all places.
reviewsSortenum: newest, relevant, highestRanking, lowestRankingnewestSort order requested from Google.
reviewsNewerThanstring—Skip reviews older than this date (ISO date like 2026-09-01, or relative like 30 days). Pagination stops early when reviewsSort=newest.
minStars / maxStarsinteger 1–5—Keep only reviews within this star range.
onlyUnansweredbooleanfalseKeep only reviews with no public owner response.
onlyWithTextbooleanfalseSkip star-only reviews with no text.
languagestring (ISO 639-1)enInterface/response language requested from Google.
computeSentimentbooleantrueCompute sentiment locally. Disable for a pure raw dump.
includeReviewerProfilebooleanfalseInclude the reviewer's public profile URL and contribution count. Off by default for GDPR data minimisation.
proxyConfigurationobject{"useApifyProxy": true}Apify Proxy settings. Datacenter proxy is sufficient for this target; escalate to residential only if you see repeated blocks.

Output (real sample)

{
"placeUrl": "https://www.google.com/maps/place/?q=place_id:ChIJrTLr-GyuEmsRBfy61i59si0",
"placeId": "ChIJrTLr-GyuEmsRBfy61i59si0",
"skipped": false,
"skipReason": null,
"reviewId": "Ci9DQUlRQUNvZENodHljRjlvT2xWdVUzTXlTbUY0U1hwSFF6SkNNbWx2YW1sdFZrRRAB",
"reviewUrl": "https://www.google.com/maps/reviews/data=!4m8!14m7!1m6!2m5!1sCi9DQUlRQUNvZENodHljRjlvT2xWdVUzTXlTbUY0U1hwSFF6SkNNbWx2YW1sdFZrRRAB...",
"stars": 4,
"text": "Great service and experience. I wish the menu was less focused on sea food and a bit more variety. Recommended.",
"textLanguage": "en",
"publishedAtDate": "2026-07-06T09:19:28.897Z",
"publishedAtText": "2 months ago",
"daysSincePublished": 88,
"likesCount": 0,
"reviewerName": "Raph",
"reviewerIsLocalGuide": false,
"reviewerReviewsCount": null,
"reviewerProfileUrl": null,
"ownerReplied": true,
"ownerReplyText": "Thanks so much for your kind words! We're delighted you had a great experience with us. We also appreciate your feedback about the menu; we'll certainly pass on to our team for consideration.",
"ownerReplyPublishedAtDate": "2026-08-03T09:58:34.381Z",
"replyLatencyDays": 28,
"sentiment": "positive",
"sentimentScore": 0.45,
"sentimentMethod": "stars+lexicon",
"needsResponse": false,
"scrapedAt": "2026-10-02T09:58:34.381Z"
}

ownerReplyPublishedAtDate and replyLatencyDays are derived from Google's relative label for the reply ("2 weeks ago" etc.) — Google exposes no exact timestamp for owner replies. The error grows with the reply's age, and both fields are null when the label can't be resolved to a date at or after the review itself.

(This row is the first row of test/production-sample.json, a real recorded run committed in the repo, and is shown verbatim — reviewerName is the public display name exactly as Google Maps shows it, here a single-word handle. The same file proves ownerReplied/ownerReplyText/ownerReplyPublishedAtDate/replyLatencyDays end-to-end: 46 of its 61 rows have ownerReplied: true, and on a 60-review sample from the same place replyLatencyDays resolved for 22/22 answered reviews — see owner_reply_detection in TEST_REPORT.json.)

A skip row for an invalid URL or a place with zero public reviews looks like this instead (never billed, taken verbatim from test/production-sample.json):

{
"placeUrl": "https://example.com/not-a-google-maps-url",
"placeId": null,
"skipped": true,
"skipReason": "not a Google Maps place URL",
"scrapedAt": "2026-10-02T09:58:31.146Z"
}

How to use via API

curl

curl "https://api.apify.com/v2/acts/YOUR_USERNAME~google-maps-reviews-reputation-tracker/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"placeUrls": ["https://www.google.com/maps/place/?q=place_id:ChIJN1t_tDeuEmsRUsoyG83frY4"],
"maxReviewsPerPlace": 50,
"maxResults": 200,
"onlyUnanswered": true,
"maxStars": 3
}'

JavaScript (apify-client)

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('YOUR_USERNAME/google-maps-reviews-reputation-tracker').call({
placeUrls: ['https://www.google.com/maps/place/?q=place_id:ChIJN1t_tDeuEmsRUsoyG83frY4'],
maxReviewsPerPlace: 50,
maxResults: 200,
onlyUnanswered: true,
maxStars: 3,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python (apify-client)

from apify_client import ApifyClient
client = ApifyClient("YOUR_API_TOKEN")
run_input = {
"placeUrls": ["https://www.google.com/maps/place/?q=place_id:ChIJN1t_tDeuEmsRUsoyG83frY4"],
"maxReviewsPerPlace": 50,
"maxResults": 200,
"onlyUnanswered": True,
"maxStars": 3,
}
run = client.actor("YOUR_USERNAME/google-maps-reviews-reputation-tracker").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

Pricing

Pay-per-result (PAY_PER_EVENT), billed as one Result event per review actually pushed to the dataset. Reviews removed by your own filters (onlyUnanswered, minStars/maxStars, reviewsNewerThan, invalid/empty places) are never charged.

TierPrice per 1,000 reviews
Free$0.27
Bronze$0.23
Silver$0.21
Gold$0.18
Platinum$0.18
Diamond$0.18

This undercuts the niche leader (compass/Google-Maps-Reviews-Scraper, $0.30/1000 Gold) while adding sentiment, reply latency and the needsResponse triage flag at no extra cost.

This Actor only reads what Google Maps already shows to any anonymous visitor on a public place page — no login, no paywall, no access-control bypass, no CAPTCHA-solving. Reviewer names are personal data under GDPR even when publicly displayed; by default the Actor does not fetch the reviewer's profile URL or contribution count (includeReviewerProfile=false), performs no enrichment, and does no cross-source identity resolution. You, the Apify user running this Actor, are the data controller for any dataset you export — please handle it under your own GDPR obligations. Google's Maps terms discourage bulk download/caching of Maps content; this is a contractual risk for the party scraping, not a technical access-control violation (no account is used or at risk here), and the practice is widely operated on Apify. Decide knowingly.

Troubleshooting

  • Empty or very few results for a place: the place may have fewer reviews than maxReviewsPerPlace, or your filters (minStars/maxStars/onlyUnanswered/reviewsNewerThan) excluded the rest. Check the dataset for a skipped: true row with a skipReason, or the run log.
  • A place/URL never appears in the output: look for its skipped: true row — skipReason explains why (invalid URL, zero public reviews, a fetch error, or all reviews removed by your own filters); skip rows are never billed.
  • Repeated HTTP 429 / "unusual traffic": switch proxyConfiguration from datacenter to residential proxy groups; Google is rate-limiting the datacenter IP range for that place.
  • replyLatencyDays is null even though ownerReplied is true: either the owner reply's relative label (Google gives no exact timestamp for replies, see below) couldn't be parsed, or it resolved to a date before the review itself — too coarse to place reliably, so the Actor drops it to null instead of publishing an impossible date pair.
  • Non-English reviews show sentimentMethod: "stars" instead of "stars+lexicon": the sentiment lexicon only covers common English words; other languages fall back to the star-anchored method, which is still returned, just less text-aware.
  • Log line reviewsSort="newest" came back empty; fell back to sort="relevant": for a small number of places Google's own newest-sorted endpoint returns nothing even though the place has reviews; the Actor retries once with relevant so you still get results instead of an empty place. Results for that place are not ordered the way you requested, but reviewsNewerThan is still applied correctly per review (no reviews are silently dropped by the pagination cutoff).

FAQ

Does this use the official Google Places API? No. The Places API caps review results at roughly 5 per place, which isn't enough for reputation monitoring. This Actor reads the same public review data Google serves to the Maps website.

Is the sentiment analysis AI-based? No — it's a transparent, rule-based method anchored on the star rating with an English lexicon fallback (sentimentMethod tells you which rule produced the label). This keeps the Actor fast and free of per-review API cost. Disable it with computeSentiment=false for a pure raw dump.

Can I monitor the same places on a schedule? Yes — combine reviewsSort=newest with reviewsNewerThan (e.g. "7 days") on an Apify Schedule to pull only new reviews each run and keep cost low.

Will I be charged for reviews filtered out by onlyUnanswered or star filters? No — filtering happens before the row is pushed to the dataset, and billing only happens on pushed rows.

How many reviews per place can I get? Up to 60 newest reviews per place per run — Google's review-list response caps out at 60 regardless of the requested page size, and the pagination token it returns consistently comes back empty over plain HTTP. This Actor is built for recurring monitoring (schedule + reviewsNewerThan) rather than a one-time full historical backfill of a place with thousands of reviews.

What happens to an invalid place URL or a place with zero reviews? It gets a structured skip row (skipped: true, skipReason explaining why) instead of failing the run or being silently dropped, and it is never billed.

Keywords

google maps reviews scraper, google reviews sentiment analysis, google maps reputation tracker, review response tracker, unanswered google reviews, owner reply latency, google reviews api alternative, local seo review monitoring, multi location review export, google business profile reviews export, review sentiment csv export, scrape google reviews without api key

Hashtags

#GoogleMaps #GoogleReviews #ReviewScraper #ReputationManagement #LocalSEO #SentimentAnalysis #LeadGeneration #WebScraping #Apify #CustomerFeedback #MultiLocation