Google Maps Scraper
Pricing
from $0.70 / 1,000 place scrapeds
Google Maps Scraper
Rising starStop wasting your budget on slow, resource-heavy browser-based scrapers. This is the fastest, most cost-effective, and data-rich Google Maps scraper on Apify, designed for high-scale lead generation and market research.
Pricing
from $0.70 / 1,000 place scrapeds
Rating
5.0
(10)
Developer
VortexData
Maintained by CommunityActor stats
18
Bookmarked
711
Total users
192
Monthly active users
2.4 hours
Issues response
23 minutes ago
Last modified
Categories
Share
πΊοΈ Google Maps Scraper: Places, Reviews, Emails & Local Leads
Scrape Google Maps places by keyword, location, Google Maps URL, Place ID, or custom GeoJSON area. Extract business names, categories, addresses, phone numbers, websites, ratings, coordinates, reviews, and Google identifiers.
For lead generation, the Actor can also enrich saved places with public website emails, extra phone numbers, WhatsApp links, social profiles, and business-profile links such as Tripadvisor, Yelp, and Foursquare.
- β No Google Maps API key required.
- β‘ HTTP-first Google Maps scraping, without browser automation for normal search.
- π¦ Export results from Apify datasets as JSON, CSV, Excel, XML, RSS, or HTML.
π― Best Use Cases
| Use case | What you get |
|---|---|
| π§² Local lead generation | Business names, categories, addresses, phones, websites, emails, social profiles, and lead-qualification links. |
| ποΈ Market research | Business density, categories, ratings, websites, and coordinates across cities, regions, or custom areas. |
| β Review monitoring | Google Maps reviews attached to each scraped place. |
| π Area-based scraping | City, suburb, ZIP/postal code, radius, polygon, or multipolygon searches. |
| π Exact place scraping | Known places from Google Maps URLs, query_place_id URLs, or raw Google Place IDs. |
| π Automation | Scheduled runs, Apify API, webhooks, integrations, CLI, and SDK workflows. |
π¦ Extracted Data
| Group | Fields |
|---|---|
| π·οΈ Place identity | title, categoryName, categories, description, subTitle |
| π Address and location | address, street, city, state, postalCode, countryCode, location, insideSearchArea |
| βοΈ Google Maps contacts | phone, phoneUnformatted, website, websiteDisplay |
| βοΈ Website contacts | emails, additionalPhones, whatsapps |
| π Social profiles | facebooks, instagrams, linkedIns, twitters, youtubes, tiktoks, pinterests |
| π§ Business-profile links | tripadvisors, yelps, foursquares |
| β Ratings and status | totalScore, reviewsCount, currentStatus, openingHoursToday, permanentlyClosed, temporarilyClosed |
| π¬ Reviews | reviews, reviewsScrapedCount, review text, author data, dates, photos when available |
| π Google identifiers | placeId, fid, cid, kgmid, canonical Google Maps url |
| π¨ Hotel fields | hotelStars, hotelPrice, hotelAmenities, hotelCheckInDate, hotelCheckOutDate |
The Output tab has focused views:
- Overview - common place fields.
- Lead generation - business identity plus contact and lead fields.
- Reviews - review payload and review counters.
- Hotels - hotel-specific fields.
- Full details - complete record grouped by meaning.
Apify also provides its built-in All fields view.
π Quick Start
For a normal keyword + location search, fill in:
- π
searchStringsArray- one search term per line. - π
locationQueries- one complete location per line. - π―
maxCrawledPlacesPerSearch- maximum saved places per search term and location.
{"searchStringsArray": ["coffee shop"],"locationQueries": ["Brooklyn, New York, United States"],"maxCrawledPlacesPerSearch": 200}
This saves up to 200 coffee shop places for that search/location, with fields such as name, category, address, phone, website, rating, coordinates, Place ID, and Maps URL.
π§ͺ Input Recipes
βοΈ Lead Generation With Website Contacts
Enable extractContactsFromWebsite when you need public contacts from business websites.
{"searchStringsArray": ["dental clinic"],"locationQueries": ["Austin, Texas, United States"],"maxCrawledPlacesPerSearch": 500,"extractContactsFromWebsite": true}
How enrichment works:
- Places without websites are still saved.
- For places with websites, the Actor checks the homepage first.
- If the homepage has no email, it tries lightweight contact-style pages such as
/contact,/contact-us,/about,/booking,/impressum, and local-language equivalents. - Rows are pushed to the dataset as soon as each website is processed.
- Website enrichment can find emails, extra phones, WhatsApp links, social profiles, Tripadvisor, Yelp, and Foursquare links.
If you need only rows with emails, filter the finished dataset by emails.length > 0.
β Reviews
Set maxReviewsPerPlace above 0.
{"searchStringsArray": ["pizza"],"locationQueries": ["Brooklyn, New York, United States"],"maxCrawledPlacesPerSearch": 100,"maxReviewsPerPlace": 100,"reviewsSort": "newest"}
The Actor can fetch up to 1000 reviews per place. Higher limits take longer and use more requests.
π Multiple Search Terms
{"searchStringsArray": ["restaurant", "coffee shop", "bakery"],"locationQueries": ["Helsinki, Finland"],"maxCrawledPlacesPerSearch": 300,"language": "fi","additionalLanguages": ["en"]}
Each search term has its own result limit. Extra languages run additional full passes and can improve coverage in multilingual regions.
π Multiple Locations
Use multiple locationQueries entries to run the same search terms across several independent areas.
{"searchStringsArray": ["plumber", "electrician"],"locationQueries": ["Seddon, Victoria, Australia","Footscray, Victoria, Australia"],"maxCrawledPlacesPerSearch": 100}
Use one complete location per line. Do not combine two cities in one location string.
maxCrawledPlacesPerSearch applies per search term per location. The example above can save up to about 400 rows before deduplication: 2 search terms Γ 2 locations Γ 100.
π Google Maps URLs And Place IDs
Use startUrls when you already know exact places or copied a Google Maps search page with a visible map viewport.
{"startUrls": [{"url": "https://www.google.com/maps/search/?api=1&query=Example+Business&query_place_id=ChIJreV9aqYWdkgROM_boL6YbwA","userData": { "externalId": "crm-123" }}],"maxReviewsPerPlace": 50}
Accepted direct inputs:
- β
Full Google Maps place URLs in
startUrls. - β
Google Maps share links in
startUrls. - β
Search URLs with
@lat,lng,zoomor@lat,lng,metersinstartUrls. - β
Raw Google Place IDs in
placeIdsonly when they come from Google Places API, Google's Place ID Finder, or aquery_place_idURL parameter.
Do not paste /g/... values, short IDs, fids, numeric CIDs, or full URLs into placeIds. Paste the full Google Maps URL into startUrls instead.
Search URLs without @lat,lng,zoom or @lat,lng,meters are ignored because no search area is available.
π°οΈ Custom Search Area
Use customGeolocation when automatic location boundaries are too small, too large, or not accurate enough.
{"searchStringsArray": ["plumber"],"maxCrawledPlacesPerSearch": 1000,"customGeolocation": {"type": "Point","coordinates": [-74.006, 40.7128],"radiusKm": 20}}
Supported custom areas:
- GeoJSON
PointwithradiusKm - GeoJSON
Polygon - GeoJSON
MultiPolygon
For exact suburbs, service areas, or multiple separate areas, use a real Polygon or MultiPolygon.
Very small polygons are risky for discovery searches: Google Maps may return no places inside a tiny cell. For grid-cell workflows, scrape a larger real search area first, then assign saved places to small cells by coordinates after the run.
π Strict Area Matching
geoStrictMatch=true keeps only places whose coordinates are inside the resolved location or custom GeoJSON area.
Normal strict behavior:
- in-area places are saved;
- out-of-area places are dropped;
- GeoJSON
PolygonandMultiPolygoninputs use exact point-in-polygon checks; - small geocoded areas such as suburbs and neighborhoods use exact OpenStreetMap boundaries when available;
- broader geocoded areas and
Point+radiusKmuse the resolved bounding box.
When the area itself is empty
A city's official boundary is often far smaller than the city people mean. Mendoza's is 54 kmΒ², and its industrial suppliers all sit in Godoy Cruz, GuaymallΓ©n and MaipΓΊ β so a strict search of "Mendoza" can find nothing at all while Google is returning a full page of exactly the businesses you wanted, one street past the line.
When that happens, the Actor:
- saves nothing from outside the area β you asked for the area, not for its neighbours, and you are not charged for rows you told it to drop;
- stops searching early instead of opening viewport after viewport over ground that keeps answering with the next town;
- returns a single diagnostic row (
recordType="run-diagnostic",isPlace=false), as every run does when it has no places to show; - tells you which towns your results were in, by name and count, in the run log and in
OUTPUT.searchStats.nearbyCitiesWithResults.
That list is usually the answer: search those towns as Location(s) of their own, or turn geoStrictMatch off to keep nearby results marked insideSearchArea=false.
π³ Pricing And Cost Control
Check the Actor's Pricing tab on Apify for the current billing events and prices.
Typical billing events:
- one base event for each saved Google Maps place;
- optional contact-details event when website enrichment finds contacts or social profiles;
- optional review event for each review attached to a place.
Cost control tips:
- Start with
maxCrawledPlacesPerSearch=50for a test run. - Keep
maxReviewsPerPlace=0unless you need reviews. - Enable
extractContactsFromWebsiteonly when you need website contacts. - Extra languages and extra zoom passes increase request volume.
- Use Apify's
maxTotalChargeUsdrun limit for large automated batches. - If the charge limit is reached, the Actor stops gracefully and saves a partial run summary when possible.
βοΈ Configuration Reference
| Input field | What it does | Recommended use |
|---|---|---|
searchStringsArray | Google Maps search terms. | Add one business category or keyword per line. |
locationQueries | One or more independent search locations. | Add one complete city, suburb, region, or country per line. |
maxCrawledPlacesPerSearch | Maximum saved places per search term per location or direct target. | Use 50 for tests, 500+ for city-scale lists. |
language | Primary Google Maps language. | Use the local language for local categories when needed. |
additionalLanguages | Extra language passes. | Useful in multilingual regions; increases requests. |
extractContactsFromWebsite | Visits business websites and extracts public contacts and profiles. | Enable for lead generation. |
contactsFetchContactPage | Checks lightweight contact/about/location pages when the homepage has no email. | Keep enabled for better email yield without deep crawling. |
contactsProxyFallback | Retries failed website/contact-page fetches through residential proxy after a direct attempt. | Keep enabled for better contact coverage; disable only to minimize proxy bandwidth. |
contactsFilterEmailsByWebsiteDomain | Keeps emails related to the business website. | Enabled by default for cleaner leads; turn off to keep every valid-looking public email found. |
maxReviewsPerPlace | Number of reviews to attach to each place. | Use 0 for fastest runs; increase for review analysis. |
reviewsSort | Requested review order. | newest is best-effort; Google can ignore it for some places. |
skipClosedPlaces | Removes temporarily or permanently closed places. | Enable for active-business lead lists. |
geoStrictMatch | Uses stricter area matching. | Enable for strict exports; read the strict-mode section above. |
keepUnverifiedLocations | Keeps service-area businesses, which have no address at all, in a strict run. | Enable for lead generation: they are real businesses with phone, website and category, and a strict run would otherwise drop them. |
There is nothing to tune. The Actor works out how to cover an area, how deep
to split it, at what zoom, and how many workers to run from the job you give it:
a grid is laid over the search area at the closest zoom that still covers it, a
map view is split wherever Google truncates its answer, and the workers scale
with the queue. The settings that used to control this by hand
(maxPlacesPerViewport, enableSubdivision, maxSubdivisionDepth,
multiZoomDelta, zoom, concurrency, requestTimeoutSecs,
minRequestIntervalMs) are gone β a wrong guess at any of them quietly cost
coverage or money. Runs saved with those fields keep working.
reverseGeocodeMissingAddress is gone for good: it invented a street address for
businesses that do not have one, by reverse-geocoding the placeholder coordinate
Google gives them. Use keepUnverifiedLocations instead β it keeps those
businesses with an honestly empty address.
Legacy post-fetch filters such as categoryFilterWords, placeMinimumStars, and searchMatching are no longer applied. They could remove valid rows only after Google Maps data had already been fetched. Filter the finished dataset by categories, totalScore, title, or searchString instead.
π€ Output Example
The default dataset contains one row per unique Google Maps place.
{"searchString": "coffee shop","title": "Bird & Branch Coffee Roasters","categoryName": "Coffee shop","categories": ["Coffee shop", "Cafe"],"address": "359 W 45th St, New York, NY 10036, United States","city": "New York","state": "New York","countryCode": "US","location": { "lat": 40.7602998, "lng": -73.9907758 },"insideSearchArea": true,"phone": "+1 917-265-8444","website": "https://www.birdandbranch.com/","emails": ["hello@example.com"],"instagrams": ["https://www.instagram.com/example"],"totalScore": 4.6,"currentStatus": "Closed","placeId": "ChIJTVhsxFNYwokRXgPwYnY0vgI","url": "https://www.google.com/maps/search/?api=1&query=Bird+%26+Branch+Coffee+Roasters&query_place_id=ChIJTVhsxFNYwokRXgPwYnY0vgI","reviewsScrapedCount": 5,"reviews": [{"author": "Alex Smith","text": "Great coffee and friendly service.","publishedAt": "3 months ago","publishedAtTimestamp": "2026-02-04T14:22:09Z"}],"scrapedAt": "2026-05-29T10:30:00Z"}
Website enrichment fields appear only when extractContactsFromWebsite=true. Review fields appear only when maxReviewsPerPlace is greater than 0.
π©Ί Run Diagnostics
At the end of each run, the Actor writes an OUTPUT record to the default key-value store and prints the same important information in the log as Run diagnosis.
Useful fields:
status-SUCCEEDED,PARTIAL, orINPUT_NEEDS_ATTENTION.inputWarning- explanation when input changes are needed.diagnosticHints- concrete reasons for low or zero output.totalPlaces- number of real Google Maps place rows.diagnosticRows- number of non-place diagnostic rows.datasetItems- total default dataset items.searchStats- returned, filtered, out-of-area, and dropped place counters.stoppedByChargeLimit- true when Apify's max total charge limit stopped the run.datasetUrl- direct API link to the dataset.
If a run saves zero Google Maps places, the Actor may write one diagnostic dataset row with recordType="run-diagnostic", isDiagnostic=true, and isPlace=false. This row is not a place. It explains why the run produced no places and may be charged as one dataset result under pay-per-event pricing.
π οΈ Troubleshooting
π The Run Succeeded But Returned 0 Places
Open the OUTPUT record or the Apify log and look for Run diagnosis.
Common causes:
- the location was misspelled or resolved to the wrong area;
- the search term is too narrow for the selected location;
skipClosedPlaces=trueremoved closed places;geoStrictMatch=trueremoved places outside the selected area;- direct URLs or Place IDs were not valid Google Maps place targets.
Try a broader search term, a clearer location such as City, Country, or a larger custom area.
π Results Look Outside My Location
Google Maps can return nearby or ranked results outside the requested area. When the Actor can check the boundary, it marks those rows with insideSearchArea=false.
Options:
- leave
geoStrictMatch=falseand filter byinsideSearchArea; - enable
geoStrictMatch=truefor stricter exports; - use a clearer location such as
Brooklyn, New York, United States; - use
customGeolocationwith a realPolygonorMultiPolygon.
π¬ Support
If a run does not return what you expected, check OUTPUT.inputWarning, OUTPUT.diagnosticHints, and the Apify log first. They usually explain whether the issue is location resolution, strict filtering, out-of-area results, unsupported direct URLs, or an empty Google response.
For bugs, feature requests, or confusing results, use the Actor's Issues tab on Apify and share the affected run when possible.
Version history is available in the Actor's Changelog on the Apify page.