Google Maps Scraper – Places, Ratings & Contacts
Pricing
$0.50 / 1,000 place returneds
Google Maps Scraper – Places, Ratings & Contacts
Scrape Google Maps places for any search: name, rating, review count, address, phone, website, categories, opening hours, coordinates, photo and place ID. Twenty places a request, paged to everything Google lists. No API key, no browser. Unofficial.
Pricing
$0.50 / 1,000 place returneds
Rating
0.0
(0)
Developer
Simple Actor
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Scrape Google Maps places as structured data. Type what you would type into Maps — "coffee shops in austin tx", "dentists in miami fl", "boulangerie paris 11e" — and every place Google lists comes back as a row: name, star rating, review count, full address, phone, website, categories, opening hours, coordinates, lead photo and Google's own Place ID — in Google's order.
Built for lead generation, local SEO, market research and location data: every business of a kind in an area, with the contact details to reach it and the Place ID to look it up anywhere else.
No API key, no login, no browser, no account of yours involved. Twenty places arrive per request, so a typical search finishes in seconds.
$0.50 per 1,000 places — $0.01 for a typical 20-place search. Apify platform usage included, nothing else to pay. A search that cannot be read is never charged.
Unofficial. Not affiliated with, endorsed by, or sponsored by Google.
Features
- The whole listing, per place — name, rating, review count, address, phone, website, every category, opening hours by weekday, coordinates and a photo.
- Google's Place ID on every row — the same
ChIJ…identifier the Places API uses, stable across runs: deduplicate on it, or look the place up elsewhere. Plus a ready-made Google Maps link. - Everything Google lists — paged automatically to the end of Google's own results, typically 120–140 places for a search, with no place twice.
- Review counts you can rely on — Google sometimes answers with a lighter record that has the rating but not the count; those pages are re-read until the counts arrive.
- Any place, any language — the search text decides where;
languagedecides what Google answers in, opening hours included. - Many searches in one run — one per line, each with its own rows.
- Paste a Maps link — a search copied from Maps' address bar is read as its terms.
- Runs stay green. A search that cannot be read becomes an error row, so one bad line never costs the rest of the job.
Input
{"queries": ["coffee shops in austin tx", "dentists in miami fl"], // one per line"maxPlaces": 20, // per search; Google runs out at ~120–140"reviewCounts": true, // re-read a page that came without review counts"language": "en","country": "US"}
| Field | Type | Default | What it does |
|---|---|---|---|
queries | array | — | Maps searches, one per line, with the place in them (plumbers in denver co). Links copied from Maps work too. |
maxPlaces | integer | 20 | Places per search, up to 200. Twenty arrive per request. |
reviewCounts | boolean | true | Re-read a page Google answered without review counts. Off is faster; reviewCount may then be null on some rows. |
language | string | en | What Google answers in: en, de, fr, es, ja, pt-BR… |
country | string | US | Two-letter code. Nudges ranking; the place in the search decides where. |
Put the place in the search
Google answers a search with no place in it — just "plumbers" — for wherever it thinks the request came from, which is a data centre, not you. Write the search the way you would in Maps: "plumbers in denver co", "coffee near shibuya station", "hotels in lisbon". Any language works.
How many places
Google lists 20 places a request and stops at roughly 120–140 for most
searches — the same point where Maps itself stops scrolling. maxPlaces
decides how far to read; asking for more than Google has returns everything
it lists. To get different places rather than more of them, narrow the
search: a neighbourhood instead of a city, or a more specific category.
Output
One item per place, in the run's dataset:
{"type": "place","position": 1,"name": "Relax and Smile Dental Care","placeId": "ChIJ8WVD9Z622YgRTsE_RcBq1Qk","cid": "0x88d9b69ef54365f1:0x9d56ac0453fc14e","address": "1490 Biscayne Blvd Suite 101, Miami, FL 33132","phone": "(305) 555-0134","website": "https://www.example-dental.com/","rating": 4.9,"reviewCount": 928,"categories": ["Dentist", "Cosmetic dentist", "Dental clinic"],"category": "Dentist","latitude": 25.7891,"longitude": -80.1886,"openingHours": { "Monday": "12–7 PM", "Tuesday": "9 AM–5 PM", "Sunday": "Closed" },"imageUrl": "https://lh3.googleusercontent.com/gps-cs-s/…","googleMapsUrl": "https://www.google.com/maps/place/?q=place_id:ChIJ8WVD9Z622YgRTsE_RcBq1Qk","query": "dentists in miami fl","searchUrl": "https://www.google.com/maps/search/dentists+in+miami+fl","page": 1,"retrievedAt": "2026-09-11T14:02:11.000Z"}
| Field | What it is |
|---|---|
placeId | Google's Place ID (ChIJ…) — stable, and what every other Google surface keys on. |
cid | Google's internal Maps listing identifier, in its hex form. |
rating, reviewCount | Star rating and number of reviews. reviewCount is null only if every re-read came back without it. |
address, phone, website | As Google shows them. phone is null when the listing has none — common outside the US. |
categories, category | Every category Google files the place under, and the primary one. |
openingHours | Hours by weekday in the language asked for. Null for listings that publish none (hotels, for instance). |
latitude, longitude, imageUrl | Coordinates and the lead photo. |
googleMapsUrl, searchUrl | A link that opens the place in Maps, and the search it came from. |
position, page | Google's rank for the search, 1 first, and which request it arrived on. |
A search that could not be read is its own row with type: "error", an
error code (bad_input or read_failed) and an errorDescription. The
run itself stays green either way, and its status message says how many
searches could not be read — so if you run on a schedule, check for
type: "error" rows rather than trusting the run status.
An empty dataset means every search was read and Google Maps lists no places for it. It never means a search could not be made; that arrives as an error row instead.
How to use
From Apify Console
- Open the Actor and click Try for free / Start.
- Put one search per line into Searches, with the place in it.
- Set Places per search — 20 is one request; Google has 120–140 for most searches.
- Click Start, then open the Dataset tab — the Places view shows a photo of each — and export as JSON, CSV or Excel. The Contacts view is the website, phone and Maps link per place.
From the API
curl -s "https://api.apify.com/v2/acts/simple.actor~google-maps/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"queries": ["coffee shops in austin tx"], "maxPlaces": 60}'
Lead generation with the JavaScript client:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('simple.actor/google-maps').call({queries: ['dentists in miami fl', 'dentists in fort lauderdale fl'],maxPlaces: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();const leads = items.filter((p) => p.website && p.phone);// Deduplicate across searches and runs on `placeId`, which is stable.
Use cases
- Lead generation — every business of a kind in an area, with website and phone, ready for outreach or a contact-details crawler.
- Local SEO and rank tracking — where a business sits in Maps for its
keywords, by
position, over time. - Market research — how many competitors a category has in a city, how they rate, where they cluster.
- Location datasets — coordinates, categories and hours for mapping, routing or analysis.
- Data enrichment — attach a Place ID, rating and hours to a list of businesses you already have.
Pricing
Simple pay-per-result pricing — no subscription and no start fee.
| Event | Price |
|---|---|
| Place returned | $0.0005 |
What that comes to:
- A search at the default depth, 20 places: $0.01.
- Everything Google lists for a search, around 140 places: about $0.07.
- 1,000 places, however many searches they come from: $0.50.
Error rows are never charged, and a search Google has no places for costs nothing.
Limits worth knowing
- Google stops at roughly 120–140 places a search. That is where Maps itself stops scrolling too. Narrow the search for different places.
- The place goes in the search. A search without one is answered for the data centre's location, not yours.
- Reviews themselves are not included — the count and rating are. The
googleMapsUrlopens the place where reviews can be read. - Some listings have no phone, website or hours. Those fields are null rather than guessed.
FAQ
Is scraping Google Maps legal? Results come from Google Maps and are subject to Google's terms — check them, and your own use, before relying on the data. This Actor reads the same listing data Maps shows anyone, without logging in.
Do I need a Google Maps API key? No. There is no key, no login, no browser and no quota of your own to manage.
Why is reviewCount null on some rows?
Google sometimes answers with a lighter record that carries the rating but not
the count. With reviewCounts on (the default) such pages are re-read until
the counts arrive, which nearly always works. Null means every re-read came
back light, or you switched the option off.
How do I know a search failed if the run stays green?
Check for rows with type: "error" — that is the failure channel by design, so
one bad search never costs the rest of the job. The run's status message also
counts how many searches could not be read.
Results come from Google Maps and are subject to Google's terms. Unofficial, and not affiliated with Google.