How to Scrape Google Maps Data in 2026 (Python + API, Without Getting Blocked)
Google Maps is the biggest local business database on the planet. Names, star ratings, review counts, categories, addresses — it is a goldmine for lead lists, local SEO, and market research.
So everyone wants to scrape it. And almost everyone hits the same three walls: Google blocks bots, the page is rendered by JavaScript, and there is a hard ceiling on how many results you can pull from one search.
This guide walks through the three honest ways to get Google Maps data in 2026 — the official Places API, do-it-yourself Python scraping, and a SERP API — with the real trade-offs of each. We will be clear about what you can actually get and what you cannot.
TL;DR: The Google Places API gives you clean place details (rating, up to 5 reviews) but no ranking position and costs climb fast. DIY Python scraping with Selenium or Playwright works for a weekend project but breaks under the ~120-result ceiling and IP blocks. A SERP API returns the Google local pack as structured JSON — business name, rating, review count, address, and position — with no proxy pool or headless browser to maintain. Pick the tool that matches the data you actually need.
What data lives on Google Maps
Google Maps holds two different layers of data, and confusing them is the number one mistake beginners make.
The first layer is place details: a specific business's name, rating, review count, category, phone, website, opening hours, and a handful of recent reviews. This is "the profile."
The second layer is local ranking: for a search like "plumber near me" in a specific city, which businesses appear in the local pack (the map box with three listings) and in what order. This is "the visibility."
These are not the same thing, and no single tool gives you both perfectly. The Places API is great at layer one and gives you nothing on layer two. Scraping the search results page is the only way to capture layer two reliably. Keep that split in mind — the rest of this guide hangs on it.
The three ways to get it (comparison table)
There are three practical paths in 2026, and each is best for a different job.
| Approach | Best for | Gives ranking position? | Maintenance | Cost shape |
|---|---|---|---|---|
| Places API (official) | Verified place profiles, contact details | No | Low | Per request; reviews/ratings hit the highest tier |
| DIY scraping (Selenium/Playwright) | One-off scrapes, learning | Partial & fragile | Very high (breaks weekly) | Proxies + servers + your time |
| SERP API (local pack) | Lead lists, local rank tracking at scale | Yes (local-pack order) | None — access is handled for you | Flat per call, page depth doesn't multiply |
If you only need clean profiles, use the Places API. If you need to know who ranks where, you need SERP data. If you are scraping fewer than a hundred listings once, DIY is fine. Let's go deeper on each.
Approach 1: The official Places API
The Google Places API is the legitimate, Terms-of-Service-friendly way to get business profiles — but it has real limits you should know before you build on it.
It returns structured place details: name, formatted address, coordinates, rating, total review count, price level, opening hours, and website. That is genuinely useful and 100% allowed.
But three things bite people. First, reviews are capped at five per place in the Place Details response, and that cap has been a documented limitation for years with no pagination (Google's own Place Details docs spell out the reviews field behavior).
Second, ratings and reviews are "atmosphere data," which sits in the most expensive SKU tier. A $200 monthly credit covers casual use, but at scale the bill grows quickly — see Google's official pricing list. You also need an active billing project to use it at all.
Third, and most important for SEO work: the Places API does not return ranking position. You can ask it about a business, but you cannot ask "who shows up in the local pack for 'dentist in Austin' and in what order." That answer only lives in the search results.
Approach 2: DIY scraping with Python
Writing your own Selenium or Playwright scraper feels like the cheap option, and for a one-time job it can work — but it is the most fragile of the three by a wide margin.
Google Maps is heavily JavaScript-rendered, so plain requests + BeautifulSoup gets you almost nothing. You need a real headless browser that scrolls the results panel and waits for listings to load.
Then the problems start. The CSS selectors that identify a business name or rating are obfuscated class names that Google changes — often the markup shifts within weeks and your parser silently returns empty fields. We wrote about why these scrapers tend to break at 3am, and Maps is one of the worst offenders.
Next, the blocks. Repeated automated requests from one IP get throttled, CAPTCHA'd, or banned. People reach for proxy pools, which is its own cost and headache — here's why proxies get banned by Google and how fast it happens.
For the bigger picture of build-vs-buy, our guide on Google search API vs scraping and the true cost of a Google scraper in 2026 both apply directly here. The headline finding: the maintenance time almost always costs more than the data.
The 120-result ceiling and the geo-grid pattern
No matter how good your scraper is, Google Maps returns roughly 120 results per search — this is a hard, intentional ceiling, not a bug you can code around.
Google caps the visible listings at about 120 per query (its infinite scroll simply stops). That's fine for "coffee shops in one neighborhood," but useless if you want every plumber in a metro area of millions of people.
The standard fix is the geo-grid (or geo-tiling) pattern. Instead of one big search over a whole city, you divide the area into a grid of smaller, overlapping coordinate cells — say a 5×5 grid of points spaced a kilometer apart — and run the same query "from" each cell's location.
Each cell returns its own local results as if a searcher were standing there. You merge all the cells and de-duplicate by business name plus address. Overlapping the cells slightly makes sure no business near a boundary slips through the cracks.
This pattern does double duty. It breaks past the result ceiling and it reveals how a business's ranking changes across a city — a shop can be #1 from its own block and invisible three kilometers away. That hyperlocal visibility map is exactly what local SEO agencies sell. If you want to build one end to end, our sibling tutorial on the geo-grid local rank tracker (a Local Falcon alternative) walks through the grid math and visualization.
One important honesty note: a SERP API returns the Google local pack — the local/Maps box on the web search page — as structured JSON. That gives you business name, rating, review count, category, address, hours, and position. It is not a full places database and does not scrape complete review text. Match the tool to the layer of data you need.
Approach 3: A SERP API for the local pack
If your goal is local-pack data — who ranks and what their rating/review count is — a SERP API is the cleanest path, because it returns that box as structured JSON and there is nothing to maintain.
Here is the key idea: when you search a local-intent query like "best dentist austin tx" on Google, the results page shows a local pack — a small map with three to a handful of business listings. Serpent's Google SERP API parses that pack for you and hands back the fields directly.
For each local-pack business you get: name, rating, reviews (the count), category, address, hours, and the result's position. That is the local visibility layer the Places API can't give you.
The operational win is that there is no proxy pool or headless browser to maintain — access is handled for you. You make one HTTPS request with your API key and parse JSON. No CAPTCHAs, no selector babysitting, no fleet of servers.
Combine that with the geo-grid pattern above — one API call per grid cell, each with a localized country and query — and you can map an entire city's local rankings without ever touching Selenium.
Working Python example (local pack to CSV)
Here is a complete, runnable example: call Serpent's /api/search endpoint with a local-intent query, parse results.localPack, and export to CSV.
You only need the requests library and a free API key (sign up for 10 free Google searches).
import csv
import requests
API_KEY = "sk_live_your_key" # keep this server-side
BASE_URL = "https://api.apiserpent.com/api/search"
def fetch_local_pack(query, country="us"):
"""Return the Google local pack for a local-intent query."""
resp = requests.get(
BASE_URL,
headers={"X-API-Key": API_KEY},
params={
"q": query,
"engine": "google",
"country": country,
"num": 10,
},
timeout=60,
)
resp.raise_for_status()
data = resp.json()
return data.get("results", {}).get("localPack", [])
def export_csv(businesses, filename="local_pack.csv"):
fields = ["position", "name", "rating", "reviews",
"category", "address", "hours"]
with open(filename, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=fields, extrasaction="ignore")
writer.writeheader()
for i, biz in enumerate(businesses, start=1):
row = {k: biz.get(k, "") for k in fields}
row["position"] = biz.get("position", i)
writer.writerow(row)
if __name__ == "__main__":
results = fetch_local_pack("best dentist austin tx", country="us")
print(f"Found {len(results)} businesses in the local pack")
for biz in results:
print(f" {biz.get('name')} — {biz.get('rating')} "
f"({biz.get('reviews')} reviews)")
export_csv(results)
print("Saved local_pack.csv")
The relevant slice of the JSON you are parsing looks like this:
{
"success": true,
"query": "best dentist austin tx",
"engine": "google",
"country": "us",
"results": {
"localPack": [
{
"name": "Bright Smile Dental",
"rating": "4.9",
"reviews": "612",
"category": "Dentist",
"address": "Congress Ave, Austin, TX",
"hours": "Open ยท Closes 6 PM"
}
]
}
}
To scale this into a city-wide scan, wrap fetch_local_pack() in a loop over your grid of localized queries (for example "dentist austin downtown", "dentist austin north", and so on), then de-duplicate by name + address before writing the CSV. For multi-country lead lists, swap the country param — see our guide on international rank tracking across 40 countries.
Note one limit so you build on solid ground: this returns the local-pack listing fields above — it does not pull full review text or a private place-details database. For deep profiles, pair it with the official Places API.
Use cases: leads, rank visibility, monitoring
Local-pack data powers three high-value workflows for agencies and growth teams.
Lead lists. Pull the local pack for "[service] in [city]" across many cities and you have a clean, ranked list of real businesses with ratings and review counts — perfect for prospecting. Our deeper playbook on SERP API lead generation shows how to qualify and enrich these.
Local rank visibility. Track where your own (or a client's) business sits in the local pack over time and across neighborhoods. Start with tracking local SEO rankings, then the hands-on local SEO rank tracking API tutorial for the code.
Competitor monitoring. Each local-pack scan captures every competitor in the box, so you get a free competitor map on every call. Schedule it weekly and you can see exactly when a rival climbs or drops. Our overview of local SEO rank tracking ties these together.
All three run on the same simple loop you saw above. The data quality is the same whether you pull one city or five hundred — and because page depth does not multiply the price, scaling up is mostly a question of how many cities you queue.
Get Google local-pack data as clean JSON
Serpent returns the Google local pack — business name, rating, review count, category, address, hours, and position — with no proxy pool or headless browser to maintain. Start with 10 free Google searches, flat pricing from $0.60 down to $0.03 per 10,000 searches, and no subscription.
Get Your Free API KeyExplore: Google SERP API · Live Playground · Pricing
FAQ
Is it legal to scrape Google Maps data?
Scraping public business listings (names, ratings, review counts) sits in a grey area and courts have generally protected scraping of public data. But Google's Terms of Service prohibit automated access, so use the official Places API or a SERP API for anything commercial, and never collect personal data.
Why can I only get about 120 results from Google Maps?
Google Maps caps each search at roughly 120 listings on purpose, so infinite scroll stops there. To cover more businesses you split the area into smaller geographic cells and query each one separately, then de-duplicate the combined list.
Can the Google Places API give me ranking position?
No. The Places API returns place details like name, rating and up to five reviews, but it does not tell you where a business ranks in the local pack for a given keyword and location. For ranking position you need to read the actual SERP.
What Google Maps fields does Serpent's SERP API return?
Serpent returns the Google local pack from the web SERP as structured JSON: business name, star rating, review count, category, address and hours, plus each result's position. It is not a places database and does not return full review text.
How do I scrape Google Maps without getting blocked?
DIY scrapers get blocked because Google detects automation and repeated IPs. The reliable path is the official Places API for place details, or a SERP API for local-pack data where there is no proxy pool or headless browser to maintain because access is handled for you.
How much does scraping Google Maps cost?
The Places API bills per request and atmosphere data like reviews sits in its highest-priced tier, so costs add up fast at scale. Serpent's SERP API charges flat per-call pricing from $0.60 per 10,000 searches down to $0.03 per 10,000, with 10 free searches and no subscription.



