How to scrape Google Maps

Two ways to scrape Google Maps: build a headless browser scraper yourself, or call one API that returns the same business data as clean JSON in about a second. Real code and a real response below.

3,000 free searches / month, 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 a real engineering project with ongoing upkeep, proxy bills, and 3 a.m. selector fixes. Whether that is worth it depends on what you are actually 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 entry
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

Scrape Google Maps in three steps

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 3,000 free credits a month, no card. One credit = one 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 July 17, 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,1923,43.5772807,-116.2797749 ... 4 more

And the same record as raw JSON:

# JSON view { "query": "plumbers in Boise, ID", "count": 5, "tookMs": 813, "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": 1923, "openingHours": { "Monday": "Open 24 hours", ... }, "location": { "lat": 43.5772807, "lng": -116.2797749 } }, ... 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, categories, hours, and lat/lng. The field-by-field breakdown lives on the Google Maps scraper API page. Prefer clicking to coding? The playground runs the same searches in the browser.

PULLED LIVE FROM THE API, JULY 17, 2026

What the rows look like

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,923(208) 3••-••09expressplumbingidaho.com
Beacon Plumbing, Heating, Air-Conditioning, and ElectricalPlumber5.01,780(208) 5••-••61beaconplumbing.com
Perfect Plumbing Heating & AirPlumber4.85,587(208) 2••-••87perfectplumbingheatingair.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. If you need verified emails for the people behind those businesses, that comes from a different source: our LinkedIn people search returns public profiles with verified emails attached.

Run your first search free
3,000 credits a month. No card, no contract.
Get started →
PRICING

One credit per business returned

Prepaid packs, and credits never expire: 25k for $49 · 100k for $149 · 500k for $549 · 2.5M for $1,999. A search that returns 40 businesses costs 40 credits. A search that returns none costs nothing, so you can experiment with queries without burning money.

FAIR PLAY

When you should not use us: if you are building live location features inside an app (map views, place lookups, autocomplete), Google's official Places API is the right tool, with an SLA and support contracts behind it. And if you want to learn browser automation, or you need screenshots and photos off the page, building your own Playwright scraper is a genuinely good project. This API is for when you need the data, at volume, without the upkeep.

BEFORE YOU ASK

Common questions

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

WORKS WITH YOUR STACK

Try it on your own city

3,000 free credits covers a real lead list. Run one search and look at the JSON that comes back.

Get 3,000 free credits
No credit card required