How to scrape Google Maps

Build a browser scraper, or make one API call. Real code for both.

Free to try, no card Working code below ~1 second responses
THE DIY REALITY

Why scraping Google Maps yourself is hard

Google Maps looks easy to scrape. The names, phones, and websites are right there on a public page. Then you try it, and you hit four walls in roughly this order:

The wallWhat actually happens
The data is not in the HTMLGoogle Maps is a JavaScript app. A plain HTTP GET returns a shell full of scripts, and the listings render later in the browser. So you need Puppeteer, Playwright, or Selenium, plus a machine with enough RAM to keep Chrome instances alive.
One search caps outThe results list stops loading after a few scrolls. In our own test, one "dentists in Miami" search returned about 100 businesses. The metro has over 1,000. Covering a full city means a full-area sweep that returns every business, deduplicated.
Google blocks bot IPsRun a headless browser from a datacenter IP and you get CAPTCHAs and empty pages fast. Clean IPs cost real money, and a burned IP stays burned for a while.
The markup shifts under youClass names in the page are machine-generated strings, and they rotate. Your selectors break without warning, and the scraper fails quietly until someone notices the empty spreadsheet.

None of this is impossible; it is an engineering project with ongoing upkeep, proxy bills, and 3 a.m. selector fixes. What matters is what you are after: the craft, or the data.

PICK YOUR ROUTE

Your three options, compared

There are three real ways to get Google Maps business data: build the scraper, pay Google's official Places API, or use a scraper API that does the collection for you.

Build it yourselfOfficial Places APICrustAPI
SetupDays of code, then upkeep foreverAn afternoonOne HTTP request
CostProxies + servers + your hours$35 per 1,000 requests at the tier that includes phone, website, and hours$1.96 per 1,000 businesses at standard prices
Results per search~100 before the list stops loading60 max across 3 billed pagesUp to 100 in one request
Keeping the dataYou store what you scrapeStoring prohibited beyond place IDsNo storage limits
When it breaksYour problem, at 3 a.m.Google's problemOur problem, and failed queries cost nothing

Official Places figures from Google Maps Platform pricing and the Text Search docs, checked July 12, 2026. Full worked math on our Places API alternative page.

THE API WAY

How do you get started?

No browser, no proxies, no selectors. You make one HTTPS request and get JSON back. Here is the whole tutorial:

1

Get a free API key

Sign up and your key is on the dashboard. Every account gets a free plan, no card. Maps bills per business returned, and searches that return nothing are free.

2

Make one request

Any search you would type into the Google Maps box works as the q parameter. Set limit up to 100.

curl "https://crustapi.com/v1/search?type=maps&q=plumbers%20in%20Boise,%20ID&limit=5" \ -H "x-api-key: YOUR_KEY"
3

Read the results

This is the actual response from that request, pulled August 4, 2026, in about a second. One record shown, trimmed, phone masked for this page. Here it is as CSV, the way it lands in a spreadsheet:

# CSV view title,address,phone,website,categoryName,totalScore,reviewsCount,lat,lng Express Plumbing Heating & Air,"7863 W Mossy Cup St Ste C, Boise, ID 83709",(208) 3••-••09,https://expressplumbingidaho.com/,Plumber,4.8,1928,43.577280699999996,-116.27977489999999 ... 4 more

And the same record as raw JSON:

# JSON view { "query": "plumbers in Boise, ID", "count": 5, "tookMs": 708, "places": [ { "title": "Express Plumbing Heating & Air", "placeId": "ChIJH94r9eT4rlQRpv0QckvrUYc", "address": "7863 W Mossy Cup St Ste C, Boise, ID 83709", "phone": "(208) 3••-••09", "website": "https://expressplumbingidaho.com/", "categoryName": "Plumber", "categories": ["Plumber", "Air conditioning contractor", "Heating contractor"], "totalScore": 4.8, "reviewsCount": 1928, "openingHours": { "Monday": "Open 24 hours", ... }, "location": { "lat": 43.577280699999996, "lng": -116.27977489999999 } }, ... 4 more ] }

The same call in Python, if curl is not your thing:

import requests r = requests.get( "https://crustapi.com/v1/search", params={"type": "maps", "q": "plumbers in Boise, ID", "limit": 100}, headers={"x-api-key": "YOUR_KEY"}, ) for place in r.json()["places"]: print(place["title"], place["phone"], place["website"])

Every record carries the full field set: name, address, phone, website, rating, review count, price level, categories, hours, lat/lng, rank position, photo thumbnail, and booking links. The breakdown lives on the Google Maps scraper API page, and the playground runs the same searches in the browser.

PULLED LIVE FROM THE API, AUGUST 4, 2026

What data do you get?

The first three businesses from that Boise search, as they land in a spreadsheet. Phones are masked here on the page; the API returns them in full, formatted and E.164.

BusinessCategoryRatingReviewsPhoneWebsite
Express Plumbing Heating & AirPlumber4.81,928(208) 3••-••09expressplumbingidaho.com
Perfect Plumbing Heating & AirPlumber4.85,604(208) 2••-••31perfectplumbingheatingair.com
Beacon Plumbing, Heating, Air-Conditioning, and Electrical, IncPlumber51,822(208) 5••-••61beaconplumbing.com
GO WIDER AND DEEPER

Cover a whole city, then pull the reviews

One search caps at 100 businesses. CrustAPI sweeps the whole metro for you and returns every business past that cap, deduplicated, from a single call, no stitching searches together on your end.

# CrustAPI sweeps the whole metro and returns every # business, deduplicated for you. One call, no slicing. r = requests.get( "https://crustapi.com/v1/search", params={"type": "maps", "q": "plumbers in Boise, ID"}, headers={"x-api-key": "YOUR_KEY"}, ) businesses = r.json()["places"] print(len(businesses), "businesses, already deduplicated")

Want the actual review text for any of those places? Swap to type=reviews with the placeId you already have. Reviews respond in about 0.3 seconds, with rating, text, author, date, sorting, and pagination. More on the Google Reviews API page.

curl "https://crustapi.com/v1/search?type=reviews&placeId=ChIJH94r9eT4rlQRpv0QckvrUYc&sortBy=newest" \ -H "x-api-key: YOUR_KEY"
STRAIGHT ANSWER

Google Maps data does not include email addresses. Not from us, and not from anyone scraping Maps, because the listings themselves do not show one. You get name, address, phone, website, rating, reviews, categories, and hours. Verified emails come from a different source: our LinkedIn people search (beta) returns public profiles with verified emails attached.

Run your first search free
Try it free. No card, no contract.
Try for free
PRICING

How much does scraping Google Maps cost?

You pay the Maps rate for each business a search returns. Forty businesses cost $0.0784 at standard Maps prices. Empty searches are free, so you can try a query without paying for a zero-result response.

DepositGoogle Search / 1,000 requestsMaps / 1,000 businessesLinkedIn reads / 1,000 requestsPeople, Jobs, Refresh / 1,000 units
$10+$1.00$1.96$6.00$1.96
$149+$0.76$1.49$4.50$1.49
$549+$0.56$1.10$3.30$1.10
$1,999+$0.41$0.80$2.45$0.80
$6,500+$0.33$0.65$1.95$0.65
$27,500+$0.28$0.55$1.65$0.55
$50,000+$0.26$0.50$1.50$0.50
$100,000+$0.20$0.40$1.50$0.40

Every eligible account gets $6 of free usage monthly. Each deposit keeps its prices until spent; paid funds never expire. People and Jobs bill per successful search, Refresh per accessible profile. Full profiles in People use the read rate per full profile. See all billing details.

Larger deposits unlock lower endpoint prices. Each deposit keeps its prices until spent. See the full deposit table on the pricing page. Prices in USD, ex-tax.

Funds are prepaid and never expire, so an unused pack is still yours next year.

WHO IT'S FOR

Who scrapes Google Maps?

FAIR PLAY

When you should not use us: for live location features inside an app (map views, place lookups, autocomplete), Google's official Places API is the right tool, with an SLA behind it. If you want to learn browser automation, building your own Playwright scraper is a good project. This API is for when you need the data without the upkeep.

BEFORE YOU ASK

Common questions

Logged-out, public-only collection has repeatedly defeated computer-fraud and contract claims. We handle the collection on our side; what you receive is business data that is public on the map for anyone to see.

No, and be wary of anyone who says otherwise. Google Maps listings do not show email addresses, so no Maps scraper can return them. Records include name, address, phone, website, rating, reviews, categories, and hours. For verified emails, our LinkedIn people search (beta) returns public profiles with a verified email attached.

Not with the API. You make one HTTPS request with your key and get JSON back in about a second. The collection is our side of the deal. If you build a DIY scraper instead, yes, you will need both.

Up to 100 with the limit parameter, billed at the Maps rate per business actually returned. To cover a whole city, CrustAPI sweeps the whole metro for you and returns every business, deduplicated, so you make one call instead of stitching searches together. Empty searches cost nothing.

Yes. The playground at /app runs the same searches in the browser, and the API plugs into Clay, n8n, LangChain, CrewAI, and MCP if you work in those tools.

Maps costs $1.96 per 1,000 businesses at standard prices, down to $0.40 for the largest deposit. Empty and failed searches are free. Every eligible account gets $6 of free usage monthly. Paid funds never expire.

Related: Google Maps Scraper API · Google Reviews API · Google Search API

WORKS WITH YOUR STACK

Try it on your own city

The free plan covers a real lead list. Run one search and look at the JSON that comes back.

Try for free
No credit card required