Google Maps Scraper – Places, Ratings & Contacts avatar

Google Maps Scraper – Places, Ratings & Contacts

Pricing

$0.50 / 1,000 place returneds

Go to Apify Store
Google Maps Scraper – Places, Ratings & Contacts

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

Simple Actor

Maintained by Community

Actor stats

0

Bookmarked

30

Total users

18

Monthly active users

6 days ago

Last modified

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 review count or the opening hours, on every place of a page or only on some. Such a page is read again until a complete one arrives.
  • Any place, any language — the search text decides where; language decides 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"
}
FieldTypeDefaultWhat it does
queriesarray—Maps searches, one per line, with the place in them (plumbers in denver co). Links copied from Maps work too.
maxPlacesinteger20Places per search, up to 200. Twenty arrive per request.
reviewCountsbooleantrueRe-read a page Google answered without review counts on any of its places. Off is faster; reviewCount and openingHours may then be null on some rows.
languagestringenWhat Google answers in: en, de, fr, es, ja, pt-BR…
countrystringUSTwo-letter code. Nudges ranking; the place in the search decides where.

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"
}
FieldWhat it is
placeIdGoogle's Place ID (ChIJ…) — stable, and what every other Google surface keys on.
cidGoogle's internal Maps listing identifier, in its hex form.
rating, reviewCountStar rating and number of reviews. reviewCount is null only if every re-read came back without it.
address, phone, websiteAs Google shows them. phone is null when the listing has none — common outside the US.
categories, categoryEvery category Google files the place under, and the primary one.
openingHoursHours by weekday in the language asked for. Null for listings that publish none (hotels, for instance), and on a row whose reviewCount is null for the reason above.
latitude, longitude, imageUrlCoordinates and the lead photo.
googleMapsUrl, searchUrlA link that opens the place in Maps, and the search it came from.
position, pageGoogle'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, read_failed, timed_out or parse_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.

Runs that reach their time limit

A run stops reading shortly before its own timeout, keeps every place it has already found, and gives each search it never reached a row with error: "timed_out". The run still succeeds, so a long batch returns what it managed instead of being killed with nothing. A search that stopped partway keeps the places it read and says so in the log. If you see those rows, raise the run's timeout or put fewer searches in one run — a search of 20 places takes a few seconds, and one paged to Google's full depth can take a couple of minutes.

When a run does fail, this Actor reports the failure to its author so it can be fixed: the error and where in the code it happened, how long the run had been going and what it had delivered, and the shape of the input — how many searches, how deep, which language and country. Your search terms and your results are never part of that report.

The one thing that fails a run is the Actor itself being broken. An error it did not expect on a search is a row too, with error: "parse_failed", and the other searches carry on. Only when every search in a run ends that way does the run fail, with the reason in its status message and in each row.

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

  1. Open the Actor and click Try for free / Start.
  2. Put one search per line into Searches, with the place in it.
  3. Set Places per search — 20 is one request; Google has 120–140 for most searches.
  4. 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.

EventPrice
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 googleMapsUrl opens 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.