Google Maps Scraper
Pricing
from $2.60 / 1,000 results
Google Maps Scraper
Extract data from thousands of Google Maps locations and businesses, including reviews, reviewer details, images, contact info, including full name, email, opening hours, prices & more. Export data, run via API, schedule and monitor runs, or integrate with other tools.
Pricing
from $2.60 / 1,000 results
Rating
4.4
(11)
Developer
Boztek LTD
Maintained by CommunityActor stats
9
Bookmarked
2.7K
Total users
156
Monthly active users
0.034 hours
Issues response
7 hours ago
Last modified
Categories
Share
A fast, reliable Google Maps place data actor built for clean, consistent output. Give it search terms plus country (optionally state and city), or a custom map area — get a structured dataset with the fields you actually need.
What it does
- Finds places by search terms, Google Maps URLs, or Place IDs
- Covers the target area with a geographic grid so results are not limited to a single result page
- Detail Mode (default): full place profile plus website enrichment — published emails, social profiles, and detected technologies
- Fast Mode: core place fields only, without the website enrichment add-on
Related Tool
If you want a hosted version of this scraper, check out: 👉 https://basedonb.com
On basedonb.com, Detail Mode (full place details — phone, website, opening hours, and more) is included for free, with no per-place add-on fee.
Scraping Modes
Detail Mode (detailGeneration: true, default)
Returns the full place profile plus website enrichment.
Fields: everything in Fast Mode, plus openingHours, additionalInfo (amenities, accessibility, service options, …), subTitle, hasWebsite, email, emails[], socials, techStack, enrichmentStatus, emailEnrichmentStatus, enrichedAt, emailEnrichedAt.
Website enrichment is requested only when a business website is available. The actor waits up to enrichmentTimeoutSecs for each result batch, then returns all fields available so far together with enrichmentStatus and emailEnrichmentStatus. A missing website, an email that is not publicly listed, or a site that cannot be reached does not fail the run.
Best for: complete business profiles where opening hours, contact emails, social profiles, and tech stack matter.
Fast Mode (detailGeneration: false)
Returns the core place record without the enrichment add-on — and without its per-place fee.
Fields: title, address, city, state, neighborhood, phone, website, totalScore, reviewsCount, categories, placeId, url, coordinates, scrapedAt, plus temporarilyClosed / permanentlyClosed when applicable.
Best for: large-scale discovery and lead lists where contact basics are enough.
Pricing
| Apify plan | Result fee (per 1,000 places) | Detail add-on (per 1,000 places) | Detail Mode total |
|---|---|---|---|
| Free | $2.90 | $25 | $27.90 |
| Starter | $2.80 | $25 | $27.80 |
| Scale | $2.70 | $22 | $24.70 |
| Business | $2.60 | $15 | $17.60 |
An actor-start fee is also charged per run: $0.008 on Free, $0.007 on Starter, $0.006 on Scale, and $0.005 on Business. Platform usage is included.
Free tier
Free-tier runs are live searches, exactly like paid runs — your own search terms, your own location or custom area. Only the volume is limited:
- Max 20 places per run.
maxCrawledPlacesPerSearchis clamped to 20 on the free tier; higher values are capped with a warning in the log. - Max 10 search terms per run. Extra terms are skipped and named in the log.
- Every feature is unlocked — including Detail Mode.
detailGeneration: trueworks on the free tier and is billed with the samedetail-generationevent as paid plans.
Upgrade to a paid Apify plan for higher per-run volume, or scrape places with a subscription directly on basedonb.com.
Concurrent search limit
Each Apify user can have at most 2 active live searches at a time. Pending, generating, running, active, assigned, and paused searches all count toward this limit. A run that satisfies your target from already-available places does not start a live search and therefore does not consume a slot.
How billing events work
- Fast Mode — Only the
resultfee applies: $2.90, $2.80, $2.70, or $2.60 per 1,000 emitted places, depending on your Apify plan. - Detail Mode — One
detail-generationevent is charged for every emitted place whendetailGeneration: true. Website email, social-profile, and technology enrichment are bundled into this event; there is no separate enrichment event. - Free tier — Same events, same rules as any other plan.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
searchStringsArray | Array | — | One or more search terms (e.g. ["restaurant", "cafe"]). Max 25, must be unique; free tier uses the first 10 |
country | String | United States | Country or region. Required unless you use customGeolocation |
state | String | — | State/region filter. Only a GeoNames admin1 code (e.g. US.TX) is applied; a plain name is ignored and the search stays country-scoped |
city | String | — | City filter |
maxCrawledPlacesPerSearch | Integer | 50 | Global maximum number of places for the run (1–10,000; capped at 20 on the free tier) |
detailGeneration | Boolean | true | Detail Mode; set false for Fast Mode |
enrichmentTimeoutSecs | Integer | 180 | Max Detail Mode wait per result batch for website enrichment; returns partial fields and status fields on timeout (10–900) |
startUrls | Array | — | Google Maps place URLs; the Place ID is read from each URL |
placeIds | Array | — | Google Maps Place IDs, looked up directly |
customGeolocation | Object | — | GeoJSON polygon or multipolygon ([lng, lat], max 1,000 points). Search uses the area centroid plus geoSearchRadiusKm |
geoSearchRadiusKm | Integer | 25 | Search radius around the custom area centroid (1–500) |
waitMode | String | stream | stream: emit places as they arrive. block: wait for the search to finish, then emit everything |
taskPollTimeoutSecs | Integer | 3300 | Max seconds to wait for an extended search to finish (30–86,400) |
pollIntervalMs | Integer | 10000 | Initial delay between status checks; backoff applies (200–60,000) |
verboseLog | Boolean | false | Enable debug-level logging |
Accepted but not used: language, countryCode, maxRequestRetries, maxConcurrency, navigationTimeoutSecs, and sessionPool are kept for backward compatibility and have no effect on results.
Breaking change: The old locationQuery field was removed. Use city and country instead (for example, replace "Istanbul, Turkey" with city: "Istanbul" and country: "Turkey").
How the search works
- Direct lookups first — any
placeIdsandstartUrlsare resolved straight to place records and count toward your target. - Already-available places — the actor matches your search terms against places it already holds for that location (or, with
customGeolocation, withingeoSearchRadiusKmof the area centroid) and returns them immediately. - Extended search — if the target is still not met, a live search is started for the remaining places. With
waitMode: "stream"(default) results are pushed to the dataset as they arrive; withblockthe run waits and emits everything at the end. The run stops atmaxCrawledPlacesPerSearch, attaskPollTimeoutSecs, or when the search reports no further matches.
If you use customGeolocation alone, you can skip country only when the area already yields enough places — once an extended search is needed, country is required and the run fails without it.
See .actor/INPUT_SCHEMA.json for the complete option list.
Example Output
Fast Mode
{"title": "Karadeniz Pide Fırını","address": "Moda Cd. No:12, 34710 Kadıköy/İstanbul","city": "Istanbul","state": "TR.34","neighborhood": "Kadıköy","phone": "+90 216 345 67 89","website": "https://karadenizpide.com","totalScore": 4.6,"reviewsCount": 892,"categories": ["Pide restaurant"],"placeId": "0x14cac6...:0x1f2e3d...","url": "https://maps.google.com/?cid=2245678901234567890","coordinates": { "lat": 40.9897, "lng": 29.0275 },"scrapedAt": "2025-03-06T14:22:10.000Z"}
Detail Mode
{"title": "Karadeniz Pide Fırını","subTitle": "Pide restaurant","address": "Moda Cd. No:12, 34710 Kadıköy/İstanbul","city": "Istanbul","state": "TR.34","neighborhood": "Kadıköy","phone": "+90 216 345 67 89","website": "https://karadenizpide.com","hasWebsite": true,"totalScore": 4.6,"reviewsCount": 892,"categories": ["Pide restaurant"],"placeId": "0x14cac6...:0x1f2e3d...","url": "https://maps.google.com/?cid=2245678901234567890","coordinates": { "lat": 40.9897, "lng": 29.0275 },"openingHours": [{ "day": "Monday", "hours": "08:00 to 22:00" },{ "day": "Tuesday", "hours": "08:00 to 22:00" }],"additionalInfo": {"Service options": [{ "Dine-in": true }, { "Takeaway": true }]},"email": "info@karadenizpide.com","emails": [{"email": "info@karadenizpide.com","kind": "role","sourceUrl": "https://karadenizpide.com/contact","sameDomain": true}],"socials": {"instagram": "https://instagram.com/karadenizpide","facebook": "https://facebook.com/karadenizpide"},"techStack": {"cms": "wordpress","detected": ["google-tag-manager", "cloudflare"]},"enrichmentStatus": "done","emailEnrichmentStatus": "done","enrichedAt": "2025-03-06T14:21:55.000Z","emailEnrichedAt": "2025-03-06T14:22:03.000Z","scrapedAt": "2025-03-06T14:22:10.000Z"}
Tips
- Set a specific
city(e.g.KadıköywithcountryTurkey) for tighter, more targeted matches. maxCrawledPlacesPerSearchis a global ceiling — the run stops as soon as this many places are collected.- Detail Mode (default) returns full business profiles with opening hours, published website emails, social profiles, and detected technologies. Switch to Fast Mode (
detailGeneration: false) for discovery and lead generation at scale when contact basics are enough and you want to avoid the per-place add-on fee. - For direct place lookups, use
placeIdsorstartUrls— these skip the search step entirely. waitMode: "stream"(default) starts filling your dataset immediately; useblockwhen you prefer one complete batch at the end.
When something goes wrong
The run does not abort. If an input is missing (no country, no search terms, a polygon that cannot be read) or the
data service is briefly unreachable, the Actor keeps every place it already collected, prints a warning explaining
what to change, and finishes normally with a status message such as
Collected 12 of 50 requested place(s) — The live data service could not be reached.
So always check two things after a run: the status message next to the run, and the warnings in the log. Whatever made it into the dataset is complete and safe to use.