Google Maps Reviews Scraper - Ratings and Text, No API Key avatar

Google Maps Reviews Scraper - Ratings and Text, No API Key

Pricing

from $0.27 / 1,000 review scrapeds

Go to Apify Store
Google Maps Reviews Scraper - Ratings and Text, No API Key

Google Maps Reviews Scraper - Ratings and Text, No API Key

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. No API key. $0.27 per 1,000 reviews, flat.

Pricing

from $0.27 / 1,000 review scrapeds

Rating

5.0

(2)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

34

Total users

22

Monthly active users

20 hours ago

Last modified

Share

Google Maps Reviews Scraper: every review for a place, no API key

Paste a Maps link, a place ID, a CID or just the business name, and get the reviews back 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.

InputMaps links, place IDs, CIDs or business names, up to 50 per run
OutputOne row per review
Ceiling5,000 reviews per run
Account neededNone, and no Google API key
Price$0.27 per 1,000 reviews, flat on every plan

🔍 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 this actor's output. The Google Maps Scraper linked below covers place details.

📥 What you give it

{
"placeUrls": ["https://maps.app.goo.gl/abc123"],
"maxReviews": 300,
"maxReviewsPerPlace": 100,
"sort": "newest",
"language": "en"
}
FieldDefaultWhat it is
placeUrlsnoneMaps links, short links, place IDs or numeric CIDs. Up to 50. Paste the link exactly as the address bar gives it.
searchTermsnoneBusiness names, if you do not have links. Up to 50, and each resolves to Google's top match.
maxReviewsbox starts at 20Total across every place in the run, split evenly between them. Up to 5,000.
maxReviewsPerPlacenoneOptional 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.
sortnewestnewest, relevant, highest or lowest.
reviewsSincenoneOnly reviews after this point. See the warning below.
onlyWithTextoffSkip star-only ratings with no words.
languageenWhich language Google should translate into.
countryusWhich country's Google to ask.
proxyUrlsnoneOptional. 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 recent run, trimmed where the URLs run long:

{
"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": "11 months ago",
"reviewerName": "Daniel J",
"reviewerUrl": "https://www.google.com/maps/contrib/103952951038275342964/reviews?hl=en-US",
"reviewerReviewsCount": 142,
"reviewerPhotosCount": 625,
"isLocalGuide": true,
"ownerReply": "Hi there! We're so glad you had a wonderful experience. Thanks for sharing it with us!",
"ownerReplyRelativeDate": "11 months ago",
"reviewPhotosCount": 1,
"reviewPhotoUrls": ["https://lh3.googleusercontent.com/grass-cs/..."],
"scrapedAt": "2026-09-21T01:45:28.154Z"
}
FieldWhat it is
publishedAtA real timestamp, worked back from Google's relative wording. relativeDate keeps the original "11 months ago".
reviewIdStable. Use it as your dedupe key across runs.
targetExactly what you typed for this place, so you can join results back to your own list.
text, originalTexttext is in the language you asked for. originalText holds the writer's own wording when a translation happened, and null when none did.
ownerReplyThe owner's response, or null.
isLocalGuideThe badge as true or false. Google's numeric level is not published here.
placeNamenull when you gave a bare ID or CID and Google returned no label. Everything else on the row still identifies the place.
reviewPhotoUrlsUp to 10 per review.

🧾 Reading the output

Three kinds of row can land in your dataset.

RowHow to spot itCharged
A reviewcharged: true and a reviewIdyes
The sample row_sample: trueno
A diagnostic_diagnostic: true and an errorCodeno

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.

The errorCode on a diagnostic row tells you which target had the problem:

CodeWhat it means
NO_PLACE_FOUNDThat business name matched nothing. Use its link or place ID instead.
NO_REVIEWSThe place resolved but has no reviews, or none survived your filters.
SHORTLINK_UNRESOLVEDA maps.app.goo.gl link would not expand. Open it once in a browser and paste the full URL.
PLACE_ID_UNRESOLVEDThe ID did not resolve to a place.
TIME_BUDGETThe run ran out of time. Everything already delivered is complete.
PROXY_INPUT_ADJUSTEDA network setting in your input was not usable, so the run used its own.
NETWORKGoogle was unreachable or answered badly. Re-run it.

One bad target never stops the others, and a diagnostic row never fails the run.

▶️ How to run it

  1. Open Google Maps Reviews Scraper and click Try for free.
  2. Paste one or more links into Place links or IDs, or type names into Business names.
  3. Set Maximum reviews. Start around 20 to see the output shape.
  4. Pick a Review order and a Language if the defaults do not suit you, then click Start.
  5. Download the dataset as JSON, CSV or Excel, or read it from the Apify API.

💰 How much does it cost?

$0.27 per 1,000 reviews. Flat on every Apify plan, no volume tiers.

You pay per review row delivered. Reviews dropped by reviewsSince or onlyWithText, duplicates, sample rows and diagnostic rows are all free, and a place with no reviews costs you nothing.

💡 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 competitors' locations.

🚧 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 "highest" gives you the 20 highest Google serves first, not a true sort of the whole history.
  • Star-only ratings have no text, so text is null on those unless you switch on Skip star-only ratings.
  • Translation is Google's, and its quality is not something this actor controls.
  • Photo links are Google CDN URLs. Stable for a long time, but not archival.
  • 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.
  • Rows are a snapshot. A review can be edited or deleted later, and scrapedAt records when it was read.
  • 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.

🧭 Which Google scraper do you need?

If you wantUse
Reviews for places you can name or linkThis one
Place details, and reviews alongside themGoogle Maps Scraper
Reviews plus AI-drafted replies, on a scheduleGoogle Reviews Monitor
App store reviews insteadGoogle Play Reviews Scraper
Search resultsGoogle Search Results Scraper

❓ Questions people ask

Do I need a Google API key? No. Nothing to apply for, no quota to manage.

Can I monitor a place over time? Yes. Schedule it with reviewsSince set to something like 7 days and sort on newest, and each run picks up only what is new. reviewId makes deduping across runs straightforward.

Why did I get fewer reviews than I asked for? Either the place does not have that many, or Google stopped issuing pages. 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 audit every branch of a chain? Feed the list of place IDs, set maxReviewsPerPlace, and you get a comparable sample from each branch in one run.

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 scraping and the law 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.