Google Maps Reviews Scraper - Ratings and Text
Pricing
from $0.26 / 1,000 reviews
Google Maps Reviews Scraper - Ratings and Text
Scrape Google Maps reviews from a place link, place ID, CID or business name. Each row has the star rating, full text, exact date, reviewer, owner reply and photos. It keeps paging until it has what you asked for or Google runs out. $0.27 per 1,000 reviews.
Pricing
from $0.26 / 1,000 reviews
Rating
5.0
(2)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
39
Total users
2
Monthly active users
8 days ago
Last modified
Categories
Share
Paste a Google Maps link, place ID, CID or business name and get its reviews as rows: star rating, the full text, the exact date, who wrote it, whether the owner replied, and any photos attached. It keeps paging rather than stopping at the first screen.
Google itself is the limit, not the actor. A very large place hands out several thousand reviews and then stops issuing pages, so nobody can pull the complete history of a busy restaurant.
| Input | Maps links, short links, place IDs, CIDs or business names, up to 50 per run |
| Output | One row per review: stars, text, exact date, reviewer, owner reply, photos |
| Ceiling | 5,000 reviews per run |
| Account needed | None, and no Google API key |
| Price | $0.27 per 1,000 reviews on the free plan, down to $0.264 on Business. The free plan's $5 a month covers about 18,000 |
🔍 What Google Maps Reviews Scraper does
It takes whatever form of a place you happen to have and resolves it to the same place: a copied
address-bar URL, a maps.app.goo.gl short link, a ChIJ… place ID, a numeric CID, or the plain
name of the business. Then it reads the review list, paging until it has what you asked for or
Google stops handing out pages.
You can point it at up to 50 places in one run and set a total row budget. That budget is split evenly between the places, so a chain audit gives you a comparable sample from every branch rather than all of it from the busiest one.
Reviews only. Opening hours, phone number, address, category and the overall star average are not part of the output. Google Maps Scraper, linked below, covers place details.
📋 What data you get from each Google Maps review
| What you get | Field |
|---|---|
| The place, as you named it and as Google knows it | target, placeName, placeUrl, placeId, cid |
| A stable id for the review, and its link | reviewId, reviewUrl |
| Stars and the text | rating, text |
| The writer's own words when Google translated them | originalText |
| The exact time it went up, and Google's relative wording | publishedAt, relativeDate |
| Who wrote it and how active they are on Maps | reviewerName, reviewerUrl, reviewerReviewsCount, reviewerPhotosCount, isLocalGuide |
| The owner's reply, and roughly when | ownerReply, ownerReplyRelativeDate |
| Photos on the review | reviewPhotosCount, reviewPhotoUrls |
| When the row was read | scrapedAt |
▶️ How to scrape Google Maps reviews
- Open Google Maps Reviews Scraper and click Try for free.
- Paste one or more links into Place links or IDs, or type names into Business names to look up.
- Set Maximum reviews. Start around 20 to see the output shape.
- Pick a Review order and a Language if the defaults do not suit you, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it from the Apify API.
💰 How much does it cost to scrape Google Maps reviews?
$0.27 per 1,000 reviews. That is the free plan's price; paid plans pay a little less: $0.268 on Starter, $0.266 on Scale and $0.264 on Business. On the free plan, the $5 Apify gives you each month covers about 18,000 reviews.
You pay per review row delivered. Reviews dropped by reviewsSince or onlyWithText, duplicates,
the sample row and diagnostic rows are all free, and a place with no reviews costs you nothing.
📥 What you give it
{"placeUrls": ["https://maps.app.goo.gl/abc123"],"maxReviews": 300,"maxReviewsPerPlace": 100,"sort": "newest","language": "en"}
| Field | Default | What it is |
|---|---|---|
placeUrls | none | Maps links, short links, place IDs or numeric CIDs. Up to 50. Paste the link exactly as the address bar gives it. |
searchTerms | none | Business names, if you do not have links. Up to 50, and each resolves to Google's top match. |
maxReviews | 20 | Total across every place in the run, split evenly between them. Up to 5,000. |
maxReviewsPerPlace | none | Optional cap per place, on top of the even split. Useful when one branch has 40,000 reviews and you want the newest hundred from each. |
sort | newest | newest, relevant, highest or lowest. |
reviewsSince | none | Only reviews after this point. See the warning below. |
onlyWithText | off | Skip star-only ratings with no words. |
language | en | Which language Google should translate into. |
country | us | Which country's Google to ask. |
proxyUrls | none | Optional. Your own servers, used exactly as given. |
reviewsSince only understands two formats: a number of days like 30 days or 30d, or a real
date like 2026-01-15. Anything else, including 2 weeks and 1 month, is ignored without
complaint, and the run then pulls and bills the full history up to your caps. Use days or a date.
reviewsSince stops paging early only when sort is newest. On any other order the cutoff
still filters rows, but the run reads further to find them.
📤 What you get back
A real row from a run on 2 October 2026, with the long links trimmed:
{"ok": true,"charged": true,"recordType": "review","placeName": "Starbucks Reserve Roastery","placeUrl": "https://www.google.com/maps?cid=7899526995152106350","placeId": "ChIJsU30zM1qkFQRbnOm1_LBoG0","cid": "7899526995152106350","reviewId": "Ci9DQUlRQUNvZENodHljRjlvT21GRFdtSnpUV2xQYjFvM1kxbFRZMHhWVlRSMFRWRRAB","rating": 5,"text": "It’s gone ):","originalText": null,"language": "en","publishedAt": "2025-09-26T17:40:32.007Z","relativeDate": "a year ago","reviewerName": "Daniel J","reviewerUrl": "https://www.google.com/maps/contrib/.../reviews?hl=en-US","reviewerReviewsCount": 155,"reviewerPhotosCount": 697,"isLocalGuide": true,"ownerReply": "Hi there! We're so glad you had a wonderful experience. Thanks for sharing it with us!","ownerReplyRelativeDate": "a year ago","reviewPhotosCount": 1,"reviewPhotoUrls": ["https://lh3.googleusercontent.com/grass-cs/..."],"scrapedAt": "2026-10-02T23:24:50.863Z"}
| Field | How to read it |
|---|---|
publishedAt | A real timestamp. relativeDate keeps Google's own "a year ago". |
reviewId | Stable. Use it as your dedupe key across runs. |
target | Exactly what you typed for this place, so you can join results back to your own list. |
text, originalText | text is in the language you asked for. originalText holds the writer's own wording when a translation happened, and null when none did. |
ownerReply | The owner's response, or null. |
isLocalGuide | The badge as true or false. Google's numeric level is not published here. |
placeName | null when you gave a bare ID or CID and Google returned no label. Everything else on the row still identifies the place. |
reviewPhotoUrls | Up to 10 per review. |
🧾 Reading the output
Three kinds of row can land in your dataset.
| Row | How to spot it | Charged |
|---|---|---|
| A review | charged: true and a reviewId | yes |
| The sample row | _sample: true | no |
| A diagnostic | _diagnostic: true and an errorCode | no |
Filter on _sample and _diagnostic being absent, not on recordType. The free sample row
also carries recordType: "review", so a filter on that alone keeps it. Read charged: true as
"this is a real row", not as a receipt.
| Code | What it means |
|---|---|
NO_PLACE_FOUND | That business name matched nothing. Use its link or place ID instead. |
NO_REVIEWS | The place resolved but has no reviews, or none survived your filters. |
SHORTLINK_UNRESOLVED | A maps.app.goo.gl link would not expand. Open it once in a browser and paste the full URL. |
PLACE_ID_UNRESOLVED | The ID did not resolve to a place. |
SEARCH_ or REVIEWS_ plus a status, SEARCH_PARSE, REVIEWS_PARSE | A name lookup or a page of reviews came back unreadable. Re-run it. |
TIME_BUDGET | The run ran out of time. Everything already delivered is complete. The run ends as failed only when the time limit stopped it before any review came back. |
PROXY_INPUT_ADJUSTED | A network setting in your input was not usable, so the run used its own. |
NETWORK | Google was unreachable or answered badly. Re-run it. |
One bad target never stops the others, and a diagnostic row never fails the run.
💡 What people use it for
- Watching what changed in a place's reviews since last month, on a schedule, using
reviewsSince. - Auditing every branch of a chain on the same terms, with a per-place cap so one busy site does not eat the budget.
- Pulling the text of everything below three stars to find the complaint that keeps repeating.
- Checking which reviews the owner replied to, and how fast, across a set of locations.
From a city search to a chain's complaints, in three steps:
- Run Google Maps Scraper on a search like
Starbucks in Seattle, WAand copy theplaceUrlcolumn. - Paste those links into
placeUrlshere withsortonnewest,reviewsSinceat30 daysandmaxReviewsPerPlaceat 50. - Keep the rows with a
ratingof 1 or 2 and group them byplaceNameto see which branch is slipping.
🚧 What it does not do
- Reviews only. No opening hours, phone number, address, category, star average or total review count.
- Not the full history. Google stops issuing pages after a few thousand on large places, and the hard ceiling here is 5,000 per run regardless.
- Sorting is Google's, applied before paging. Asking for 20 sorted
highestgives you the 20 highest Google serves first, not a true sort of the whole history. - Star-only ratings have no text, so
textisnullon those unless you switch on Skip star-only ratings. - Translation is Google's, and its quality is not something this actor controls.
- A name matching several places resolves to Google's top match, and a name with no city in it can land on the wrong branch. For a specific place, use its link or place ID.
- The row budget splits evenly between your places. A place with fewer reviews than its share returns fewer rows, and the leftover is not handed to the others.
- Rows are a snapshot. A review can be edited or deleted later, and
scrapedAtrecords when it was read. - It is not an official Google tool. Dami's Studio is independent and is not affiliated with or endorsed by Google, or by any other company named on this page.
🧭 Which Google Maps scraper do you need?
| If you want | Use |
|---|---|
| Places from a search, with reviews optional | Google Maps Scraper |
| Reviews for a place you can link or name, with exact dates | This one |
| The photos and videos on a place | Google Maps Place Photos Scraper |
| Only what changed in your own locations' reviews, on a schedule | Google Reviews Monitor |
| Businesses in Russia and the CIS, from Yandex Maps | Yandex Maps Scraper |
❓ Questions people ask
Do I need a Google API key to scrape Google reviews?
No. Nothing to apply for, no account and no quota to manage.
Why did I get fewer reviews than I asked for?
Either the place does not have that many, or Google stopped issuing pages, or the budget was split across several places. You are charged for what arrived.
Why is my date cutoff being ignored?
Almost always the format. reviewsSince takes 30 days, 30d or a date like 2026-01-15.
Wordings like 2 weeks are dropped silently.
Can I monitor a place over time?
Yes. Schedule it with reviewsSince at something like 7 days and sort on newest, and each run
reads only what is new. reviewId makes deduping across runs straightforward.
Can I call it from code or connect it to an AI assistant?
Yes. The API tab has
ready-made code for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP
client, connect https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/google-maps-reviews-scraper.
Either way the run happens on your Apify account at the same price.
Is scraping Google reviews legal?
These are public reviews on public place pages. They contain personal data all the same, which GDPR and similar laws cover, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the place link and the run ID. The errorCode on
the diagnostic row usually names the problem on its own.