Google Maps Reviews Scraper – Ratings, Text, Owner Replies avatar

Google Maps Reviews Scraper – Ratings, Text, Owner Replies

Pricing

from $0.50 / 1,000 review scrapeds

Go to Apify Store
Google Maps Reviews Scraper – Ratings, Text, Owner Replies

Google Maps Reviews Scraper – Ratings, Text, Owner Replies

Extract Google Maps reviews by place ID, cid, or Maps URL, or by search query: rating, review text (original + translated), author, owner replies and photos.

Pricing

from $0.50 / 1,000 review scrapeds

Rating

0.0

(0)

Developer

SERP King

SERP King

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Google Maps Reviews Scraper – Ratings, Review Text, Owner Replies

Extract Google Maps reviews for any business: rating, review text (original and translated), author, whether they're a Local Guide, owner replies, and review photos. Give it a place ID, a cid, or a Google Maps URL — or just a search query — and it calls a licensed data provider directly. No proxies, no headless browser, no IP bans, no CAPTCHAs.

What data you get

One dataset row per review:

  • placeId, cid — Google's identifiers for the place the review belongs to
  • placeName, placeAddress, placeRating, placeReviewsCount — the place's own current stats, attached to every one of its reviews
  • reviewId, reviewUrl
  • author, authorUrl, isLocalGuide, authorReviewsCount
  • rating — the reviewer's star rating (0-5) for this review
  • text, originalText, originalLanguage — review text in the requested language, the untranslated original, and its detected language
  • publishedAt (ISO 8601 UTC)
  • ownerAnswer, ownerAnswerAt — the business's reply, if any
  • imagesCount, imageUrls — photos attached to the review
  • query — the search query that surfaced this place, null for a place passed directly via placeIds

Why this scraper

  • Fast — reviews come from a real-time, expedited data pipeline, typically under a minute per batch of places, not minutes of browser automation per place.
  • Cheap — pay only for reviews actually returned, a flat $0.0005 per review regardless of your Apify plan (see Pricing).
  • Up to 4,000 reviews per place — far past what Google's own UI shows without heavy scrolling.
  • Three ways in — a place_id, a numeric cid, or a Google Maps URL (both the ?cid= and the !1s0x...:0x... link formats work); or skip IDs entirely and search by queries like the Maps actor does.
  • Original + translated text — both text (in your requested language) and originalText/originalLanguage are returned, so you can tell a translation from a native-language review.

Pricing

This actor uses Apify's pay-per-event pricing, flat across all plans:

EventWhat it meansPrice
apify-actor-startApify's platform-billed "run started" event, charged once per run automatically — no code call needed, so a run that finds zero reviews costs almost nothing$0.00005
apify-default-dataset-item ("Review scraped" in Console)Charged once per review written to the output dataset$0.0005

Worked example: scraping 1,000 reviews costs 1,000 × $0.0005 + $0.00005 ≈ $0.50.

Input

Two ways to tell the actor which places to fetch reviews for — fill one, or both:

By ID:

{
"placeIds": ["ChIJrTLr-GyuEmsRBfy61i59si0"],
"maxReviewsPerPlace": 100
}

By search query (used as the prefill; searches Google Maps, takes the top maxPlacesPerQuery results):

{
"queries": ["coffee shops in Austin, TX"],
"country": "US",
"maxPlacesPerQuery": 2,
"maxReviewsPerPlace": 20
}
FieldTypeDefaultDescription
placeIdsarray of stringsPlaces to fetch reviews for. Accepts a place_id (e.g. "ChIJrTLr-GyuEmsRBfy61i59si0"), a numeric cid (e.g. "9542840243817508540"), or a Google Maps URL containing a ?cid= query parameter or a !1s0x...:0x... feature id. Optional if queries is set.
queriesarray of strings["coffee shops in Austin, TX"]Google Maps search queries; each takes its first maxPlacesPerQuery results. Optional if placeIds is set.
countrystring (ISO-2)"US"Used to resolve the location for every review request, and (unless coordinates is set) to anchor queries.
coordinatesstringQuery mode only: anchor queries to a map viewport instead of country, "lat,lng,zoom" (e.g. "30.2672,-97.7431,14").
maxPlacesPerQueryinteger10 (1-100)How many places to take from each query's search results.
languagestring"en"Language code for review text and query results.
maxReviewsPerPlaceinteger100 (10-4,000)Reviews to fetch per place. Must be a multiple of 10 — Google's reviews API pages in tens.
reviewsSortstring"newest"One of newest, relevant, highest_rating, lowest_rating.
reviewsNewerThanstring (ISO-8601)Keep only reviews published on or after this date/datetime (inclusive), e.g. "2026-09-01" or "2026-09-01T00:00:00Z". Applied after fetching, before writing to the dataset — see below.
reviewsOlderThanstring (ISO-8601)Keep only reviews published on or before this date/datetime (inclusive), e.g. "2026-09-08". Must be on or after reviewsNewerThan.

DataForSEO's reviews API has no date filter of its own, so reviewsNewerThan/reviewsOlderThan are applied by this actor after fetching up to maxReviewsPerPlace reviews and before writing rows to the dataset — only rows inside the window get pushed, and only pushed rows are charged, so an out-of-window review costs nothing. The run's STATS record (reviewsFilteredByDate) reports how many were dropped this way.

A run is capped at 100 places total (placeIds count + maxPlacesPerQuery x queries) and 4,000 reviews per place — so the input fails validation up front, with a message telling you exactly how far over you are, rather than letting a typo turn into a runaway bill. Need more than 100 locations? See Monitoring at scale below.

Output

One real dataset row, from an actual run against a public Google Maps place on September 8, 2026:

{
"placeId": null,
"cid": "9920705898319708454",
"placeName": "Cacao Much - Chocolate Café",
"placeAddress": "Av. Providencia 2400, 7510034 Providencia, Región Metropolitana, Chile",
"placeRating": 4.5,
"placeReviewsCount": 3261,
"reviewId": "Ci9DQUlRQUNvZENodHljRjlvT25WemVXa3pNblpoY1ZOblFsY3llV1ZwTTBZeFVVRRAB",
"author": "Nahime Mostafá",
"authorUrl": "https://www.google.com/maps/contrib/102272400702552550088/reviews?hl=es-419",
"isLocalGuide": true,
"authorReviewsCount": 54,
"rating": 5,
"text": "Personalmente me encantó que ofrezcan el chocolate caliente en su versión espesa y ligera. Opté por el ligero y es ideal para acompañar con los churros.",
"originalText": null,
"originalLanguage": "es",
"publishedAt": "2026-09-08T00:57:25Z",
"ownerAnswer": "Gracias por tu increíble reseña! Te esperamos nuevamente para más cositas ricas ",
"ownerAnswerAt": "2026-09-08T02:06:20Z",
"imagesCount": 3,
"imageUrls": [
"https://lh3.googleusercontent.com/grass-cs/ACvplmPyV1Y2boQQd_IiPxCNzcRRj_H4xKqiC5FsyY228kXEfOEz-E9eopWRITHuzN7ZD-t7bTdxXZdq3YBuF2PWFTxZwZ3_xlGOTCZZhaqdCmpWJl9two6UgsXy71WDz0DsIUnk5WuTarNqA_ed=k-no",
"https://lh3.googleusercontent.com/grass-cs/ACvplmNGHnWahaniFQAoBtOvACPQj15OYxrIRgspNJlecjwXl-ijWm-XxdImmQlX8zlRNEPJ8CCak9Hwzs5VGoHHKayLicxBUMRcf2xWsfCt9D-COS0QGBBl6u3HF8ExN_ui7eQOfMrzKKBqSv1y=k-no",
"https://lh3.googleusercontent.com/grass-cs/ACvplmN3ATMOr1PfjQM6qaoZuObWplPfurFHqdz7Un2CU3r-7Zg9iQ05YBL10h6-eoDNaHLMiNSTfgMfgN2j1I5tYfWRansMGS9mqcG8ofAPYD-4EMmmwW2zKaYoMybvrGADU0mMReUHk_9RXNAn=k-no"
],
"reviewUrl": "https://www.google.com/maps/reviews/data=!4m8!14m7!1m6!2m5!1sCi9DQUlRQUNvZENodHljRjlvT25WemVXa3pNblpoY1ZOblFsY3llV1ZwTTBZeFVVRRAB!2m1!1s0x0:0x89ad6d73ce780126!3m1!1s2@1:CAIQACodChtycF9oOnVzeWkzMnZhcVNnQlcyeWVpM0YxUUE%7C%7C?hl=es-419",
"query": "cafeterías en Providencia, Santiago"
}
FieldTypeDescription
placeIdstring | nullGoogle's place identifier
cidstring | nullGoogle's numeric identifier for the place
placeNamestring | nullBusiness name
placeAddressstring | nullThe place's address, as shown alongside its reviews
placeRatingfloat | nullThe place's current overall rating (0–5)
placeReviewsCountinteger | nullThe place's current total review count
reviewIdstring | nullGoogle's identifier for this specific review
authorstring | nullReviewer's display name
authorUrlstring | nullLink to the reviewer's Google Maps profile
isLocalGuideboolean | nullWhether the reviewer has Local Guide status
authorReviewsCountinteger | nullTotal reviews the author has written (not just for this place)
ratingfloat | nullThis review's star rating (0–5)
textstring | nullReview text, translated to language if needed
originalTextstring | nullUntranslated review text
originalLanguagestring | nullDetected language of originalText
publishedAtstring | nullISO 8601 UTC
ownerAnswerstring | nullThe business's reply text, if any
ownerAnswerAtstring | nullISO 8601 UTC
imagesCountinteger | nullNumber of photos attached to the review
imageUrlsarray of stringsDirect URLs of attached photos (empty if none)
reviewUrlstring | nullDirect link to the review
querystring | nullThe queries entry that surfaced this place, null for a placeIds entry

Limits

  • Maximum 4,000 reviews per place, and 100 places per run (see Input) — this actor's own cap, to keep a typo from turning into a runaway bill.
  • maps.app.goo.gl short links (the ones "Share" in the Google Maps app produces) aren't supported: resolving them needs an HTTP redirect, and this actor never makes requests to Google directly. Expand the link in a browser first and pass the resulting maps.google.com/google.com/maps URL instead.
  • authorReviewsCount counts the author's total reviews across Google Maps, not reviews of this specific place.
  • Auto-generated vs. manually-written reviews aren't distinguished — Google itself doesn't expose that flag through this data source.
  • A place found via queries but not yet indexed with any reviews returns zero rows for it (not an error) — check the run's STATS key-value record (placesWithoutReviews) to see how many.
  • Results reflect Google Maps at the moment the run executes; ratings, reply text, and review counts can change between runs.

Monitoring at scale

Tracking more than 100 locations on a recurring schedule (e.g. a reputation-management agency watching 300 client locations weekly)? Chunk your place list across multiple runs rather than trying to fit it into one:

  1. Chunk placeIds into batches of ≤100 — e.g. 300 locations become 3 chunks of 100, each its own scheduled run (3 Apify Schedules, or 3 calls from your own orchestrator to the Apify API's run-actor endpoint).
  2. Prefer placeIds over queries for monitoring — a placeIds list targets the same locations every run, while a queries search can surface a different set of places as Google Maps' own ranking shifts.
  3. Set reviewsNewerThan to your last successful run's date, with reviewsSort: "newest" — this keeps a run from re-charging for reviews it already pulled last time (see Input above for how the filter works). An Apify Schedule sends the same fixed input on every trigger, so it can't compute "since last run" by itself: drive reviewsNewerThan from your own cron/orchestrator, updating the run's input to the previous run's date (via the Apify API) before each trigger.
  4. Dedupe by reviewId on your side across runs — if you pad reviewsNewerThan a day earlier than strictly necessary as a safety margin (clock drift, a review that lands mid-run), you'll see a handful of the same reviews again rather than relying on the filter alone for a perfectly disjoint set.
  5. Watch reviewsFilteredByDate and placeReviewsCount in STATS/each row — if a place picked up more new reviews than maxReviewsPerPlace since your last run, the oldest ones in that window are lost (with reviewsSort: "newest", only the newest maxReviewsPerPlace are fetched at all); raise maxReviewsPerPlace for that place if this happens.

Worked weekly example: 300 locations, chunked into 3 runs of 100 places each, averaging ~20 new reviews per location per week: 300 × 20 × $0.0005 = $3.00 in review charges, plus 3 × $0.00005 = $0.00015 for the 3 run starts — about $3.00/week total.

FAQ

Is this legal? The actor retrieves publicly available review data through a licensed data provider, the same category of source used by reputation-management and local-SEO tools. You're responsible for how you use the extracted data under your local regulations.

Which languages are supported? Any language Google Maps itself supports for reviews. Set language to get text translated into that language; originalText/originalLanguage always carry the review as the author wrote it, regardless of language.

Can I pass a place_id I got from the Google Maps Places API or another Apify actor? Yes — placeIds accepts a place_id directly, no conversion needed. It also accepts a cid or a full Google Maps URL if that's what you have instead.

Why did I get fewer reviews than maxReviewsPerPlace? The place may simply not have that many. placeReviewsCount on each returned row tells you the place's actual total; if it's lower than maxReviewsPerPlace, that's the ceiling regardless of what you requested.

Can I run this via API, on a schedule, or trigger it from a webhook? Yes. Any Apify actor can be started, monitored and read back through the Apify API, run on a recurring schedule, and wired to webhooks on run events from the Apify Console.