Google Maps Scraper
Pricing
from $0.70 / 1,000 place scrapeds
Google Maps Scraper
Stop 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
4.8
(18)
Developer
VortexData
Maintained by CommunityActor stats
42
Bookmarked
2.2K
Total users
652
Monthly active users
2.9 hours
Issues response
3 hours ago
Last modified
Categories
Share
Google Maps Scraper extracts local businesses from Google Maps. No API key, no quota. One place per row: name, category, address, coordinates, phone, website, rating and opening hours, plus emails and reviews when you want them.
- π Search: by keyword and place,
dentistinAustin, Texas, United States - πΊ Or by a shape you draw: a polygon, a radius, a Google Maps URL, a Place ID
- π§² Contacts: emails, phones and socials from each business's own website
- β Reviews: text, rating, author, date
- π Any country, any language: local names, local categories
- π― One business, one row: deduplicated across the whole run
- π³ Pricing: per result, never per hour
- π€ Export: JSON, CSV, Excel, XML, HTML, or straight from the API
How to scrape Google Maps
{"searchStringsArray": ["plumber", "electrician"],"locationQueries": ["Austin, Texas, United States", "Dallas, Texas, United States"],"maxCrawledPlacesPerSearch": 300}
Two search terms Γ two locations Γ 300 = up to 1,200 places. Press Start. Rows show up in the Output tab while the run is still going.
Good search terms. Different trades, each finding places the others miss:
["plumber", "electrician", "hvac contractor", "roofing contractor"]
Poor search terms. Variants of one word, costing time without adding places:
["plumber", "plumbers", "plumbing", "plumber near me"]
| Write this | Not this |
|---|---|
dentist | dentist in Austin. The term is searched in every location |
| One location per line | Austin, Dallas. Read as one name |
Paris, Texas, USA | Paris. A shared name resolves to the biggest one |
50 on your first run | 5000 before you have seen the rows |
Output
Google Maps Scraper output example
{"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","postalCode": "10036","countryCode": "US","location": { "lat": 40.7602998, "lng": -73.9907758 },"phone": "+1 917-265-8444","website": "https://www.birdandbranch.com/","totalScore": 4.6,"reviewsCount": 412,"currentStatus": "Closed","openingHoursToday": { "day": "Thursday", "hours": "7 AMβ5 PM" },"placeId": "ChIJTVhsxFNYwokRXgPwYnY0vgI","url": "https://www.google.com/maps/search/?api=1&query=Bird+%26+Branch&query_place_id=ChIJTVhsxFNYwokRXgPwYnY0vgI","searchString": "coffee shop","scrapedAt": "2026-08-27T10:30:00Z"}
If a column is empty, Google didn't have it.
What data does Google Maps Scraper extract?
| Group | Columns |
|---|---|
| Identity | title categoryName categories categoryId description subTitle |
| Address | address street city postalCode state countryCode neighborhood plusCode timezone |
| Position | location entranceLocation |
| Contact | phone phoneUnformatted website websiteDisplay |
| Reputation | totalScore reviewsCount reviewsUrl |
| Open or closed | openingHoursToday currentStatus nextOpensAt permanentlyClosed temporarilyClosed |
| Photos | imageUrl imageUrls imagesCount imageCategories |
| Hotels | hotelStars hotelPrice hotelAmenities hotelDescription hotelCheckInDate hotelCheckOutDate |
| Commerce | menu price reserveTableUrl bookingLinks |
| Listing | ownerName claimThisBusinessUrl placeTags additionalInfo isAdvertisement |
| Identifiers | placeId cid fid kgmid url |
| Run | searchString rank language scrapedAt searchPageUrl |
categoryId reads identically in every language: jewelry_store in Tokyo and in Lisbon.
The Output tab has ready-made views: Overview, Lead generation, Reviews, Hotels, Full details.
Add-ons
Scrape emails and contacts from Google Maps
{ "extractContactsFromWebsite": true }
Opens each place's own website and adds emails additionalPhones whatsapps facebooks instagrams linkedIns twitters youtubes tiktoks pinterests tripadvisors yelps foursquares.
- It keeps addresses that belong to the site. One on a different domain only survives if the page clearly presents it as a contact, so you don't end up with the web agency that built the site.
- The list is ordered most useful first, so the first address is the one to write to.
- You're charged only where it found something.
- Expect fewer emails than places. Plenty of businesses have no website, and plenty of websites never show an address.
- It skips two dozen global chains. A head office isn't the branch you found.
Scrape Google Maps reviews
{ "maxReviewsPerPlace": 20, "reviewsSort": "newest" }
You get the text and the rating, when it was written, and who wrote it: their name, their profile link, how many reviews and photos they've posted, whether they're a Local Guide. Plus the language it was written in, and any photos attached.
Sort by newest, most_relevant, highest or lowest. It asks for up to 8000 per place, and reviewsScrapedCount tells you how many actually arrived.
Each review is charged. 20 reviews Γ 100 places = 2,000 charged reviews, and the run takes considerably longer. Start low.
Search by area, URL or Place ID
Scrape a custom area, polygon or radius
For a delivery zone, a sales territory, or a radius around a point.
{ "customGeolocation": { "type": "Point", "coordinates": [-74.006, 40.7128], "radiusKm": 5 } }
Paste whatever geojson.io, QGIS or Google My Maps gives you: a Point with radiusKm, a Polygon, a MultiPolygon, a Feature or a FeatureCollection. Draw something smaller than a district and it can come back empty.
Scrape Google Maps by URL
A CRM export, a supplier list, competitors you watch.
{ "startUrls": [{ "url": "https://maps.app.goo.gl/xxxx", "userData": { "crmId": "A-1042" } }] }
Accepts: a Google Maps share link Β· a β¦/maps/place/β¦ URL Β· a copied search page with a map view.
Returns: userData back as inputUserData, so results join onto your own records.
Scrape Google Maps by Place ID
{ "placeIds": ["ChIJreV9aqYWdkgROM_boL6YbwA"] }
Full ChIJ⦠identifiers only, from the Places API or Google's Place ID Finder. Short /g/⦠ids aren't Place IDs and neither are URLs. If you've got a URL, paste it as a URL.
Results
How many results will Google Maps Scraper return?
maxCrawledPlacesPerSearch applies per search term, per location, so terms Γ locations Γ the limit is a ceiling rather than a forecast.
You get fewer when:
- The area holds less. Forty coffee shops is forty coffee shops. Past that, Google pads its answer with unrelated places, saved and charged like any other unless you switch Only what you searched for on.
- Search terms overlap. A place two terms both find is one row, not two.
Extra languages add places rather than copies. Each one searches the same ground again, and you only get what the earlier pass missed.
Every run publishes a map of its results, showing the area it searched with its places on it β as many as a browser can open, and the legend counts any that did not fit. You can look at your coverage instead of guessing at it.
Filter Google Maps results
| In the form | Field | Effect |
|---|---|---|
| π Only places inside the area | geoStrictMatch | Drops everything outside the search area. A place Google files under your city counts as inside. |
| π Keep unlocated places | keepUnverifiedLocations | Keeps places Google gives no address: a plumber with a van, a studio run from home. Only acts when the setting above is on, which otherwise drops them. |
| β© Skip closed places | skipClosedPlaces | Drops places Google marks closed, temporarily as well as permanently. |
| β© Only what you searched for | skipPlacesNotMatchingSearch | Drops places it recognises as unrelated. What it cannot judge is kept. |
You're not charged for anything these drop, and it doesn't count against your limit either. The run just keeps looking.
With Only what you searched for on, every place kept carries searchTermMatch:
| Value | Meaning |
|---|---|
match | The search term names this kind of place |
arguable | Only this run's own results vouch for it |
not-a-match | Not what you searched for |
not-judged | Not enough evidence to decide. Kept, and charged |
It gets rid of most of the obviously unrelated ones and rarely throws away something you wanted. It isn't a guarantee of a clean list, though. Anything it can't judge, it keeps, and you pay for that. A search term that names a kind of place (bakery, pest control service) judges well; a vague phrase can leave almost every place undecided.
Pricing
How much does it cost to scrape Google Maps?
Charged per result, never per hour. The Pricing tab shows current rates.
| Event | Charged |
|---|---|
| Place scraped | Per row in your dataset |
| Place with contact details | Only where the add-on found something |
| Review scraped | Per review |
| Actor start | Once per gigabyte of the run's memory |
Both add-ons are off by default. Set maxTotalChargeUsd before you start and the run stops cleanly when it gets there, keeping everything it found.
Limits and speed
- Places limit:
10minimum, no maximum. - Rows are saved as they're found, so a run that stops early keeps everything up to that point.
- Raise the run's timeout for multi-city jobs, or it'll stop before it's done.
- The Setup block in the log prints what each location resolved to, and flags ambiguous ones.
FAQ
Do I need a Google Maps API key?
No. No Google billing account, no quota, nothing to apply for.
Why did I get fewer places than I asked for?
Four reasons, and the run's summary names which one:
- The area holds fewer places than you asked for.
- Several of your search terms found the same place, so you get it once.
- A filter dropped rows. You weren't charged for them.
- The run hit its timeout or your charge ceiling. Everything found by then is saved.
Why are the results not what I searched for?
Once an area runs out of what you asked for, Google keeps answering with whatever else is nearby, and those places get saved like any other. Switch Only what you searched for on and they're dropped before they reach you, at no charge. Whatever stays carries a searchTermMatch verdict.
Why are there places from the next town?
Google returns what it finds relevant, and near a boundary that takes in the neighbours. Leave Only places inside the area off and they arrive marked insideSearchArea: false. Switch it on and they're dropped.
Switch Keep unlocated places on with it, or you also lose every mobile trade. They have no coordinates to check.
My run returned nothing at all. What went wrong?
Usually one of four. The location resolved to a different place of the same name. Your search term is too specific to be a category anyone's filed under. A filter removed everything. Or the Place IDs and URLs weren't valid places. The run writes one row saying which, marked recordType: "run-diagnostic".
Why are some emails missing or wrong?
Emails come off each place's own website. No website, no email, and a website that never publishes an address gives you nothing either.
By default it keeps only addresses on that site's own domain, which is what stops an agency's address landing on its client's row.
How do I make a run faster?
The run tells you what is holding it up. Near the top of the log, Run plan prints a Bounded by line with one of two answers.
this memory's CPU. Raise the run's memory. Apify grants CPU in proportion to it, and the Actor sizes its own worker pools from the CPU it is given, so a larger machine searches more areas at once.the far end. It is waiting on Google, not on itself. More memory buys nothing here.
Can I run this on a schedule or from my own code?
Yes. Schedule it from the Actor page, or start it through the Apify API.
Is it legal to scrape Google Maps?
It collects business listings Google Maps shows to anyone, plus what a business publishes on its own website. It logs into nothing and takes no personal data.
What you may do with that data depends on where you and the businesses are. Apify's guide to ethical web scraping is a good start; your own case is a question for a lawyer.
Support
Read the run first: the Log ends with what was searched, saved and dropped, and the OUTPUT record says the same via the API.
Still wrong? Open the Issues tab and include the run. Release notes are on Changelog.
Includes a place-category taxonomy Β© Overture Maps Foundation, CC BY 4.0.