google-mapsleadsapi

Google Maps Leads: API Not Scraper

Google Maps scraping violates ToS. SERP local pack API returns structured business data at $0.005/query. Legal, reliable, and no proxy management.

8 min

Google Maps scraping violates Google's Terms of Service and gets your IP addresses blocked. The official Google Places API works but costs $17-40 per 1,000 requests depending on the endpoint. The alternative: a SERP API that returns Google's local pack results as structured JSON at $0.005/query. Legal, reliable, and 3-8x cheaper than the official Places API for lead generation use cases.

Why scraping Google Maps fails at scale

  • CAPTCHAs trigger after ~50-100 requests from the same IP range
  • Residential proxies add $50-200/mo to costs
  • Google actively detects and blocks headless browsers
  • HTML structure changes break parsers every few weeks
  • ToS violation creates legal risk for your business

SERP local pack results: structured business data

Python
import requests, os

H = {"x-api-key": os.environ["SCAVIO_API_KEY"]}

def find_local_businesses(query: str, location: str = None):
    """Get structured business data from Google local pack."""
    payload = {"query": query, "platform": "google"}
    if location:
        payload["location"] = location
    resp = requests.post("https://api.scavio.dev/api/v1/search",
        headers=H, json=payload)
    data = resp.json()
    businesses = []
    for r in data.get("local_results", []):
        businesses.append({
            "name": r.get("title"),
            "rating": r.get("rating"),
            "reviews": r.get("reviews"),
            "address": r.get("address"),
            "phone": r.get("phone"),
            "website": r.get("website"),
            "type": r.get("type"),
        })
    return businesses

# $0.005 per search
leads = find_local_businesses("plumber", "Austin TX")
for b in leads:
    print(f"{b['name']} - {b['rating']} stars ({b['reviews']} reviews)")

Building a lead generation pipeline

Python
import csv, time

def generate_leads(business_type: str, cities: list):
    """Generate leads across multiple cities."""
    all_leads = []
    for city in cities:
        query = f"{business_type} in {city}"
        businesses = find_local_businesses(query, city)
        for b in businesses:
            b["city"] = city
            b["search_query"] = query
            all_leads.append(b)
        time.sleep(0.5)  # Rate limiting
    return all_leads

def export_to_csv(leads: list, filename: str):
    """Export leads to CSV for CRM import."""
    if not leads:
        return
    with open(filename, "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=leads[0].keys())
        writer.writeheader()
        writer.writerows(leads)

# 10 cities x $0.005 = $0.05 for lead generation across 10 cities
cities = ["Austin TX", "Dallas TX", "Houston TX", "San Antonio TX"]
leads = generate_leads("HVAC contractor", cities)
export_to_csv(leads, "hvac_leads.csv")
print(f"Generated {len(leads)} leads across {len(cities)} cities")

Cost comparison

  • Google Places API (Nearby Search): $32 per 1,000 requests
  • Google Places API (Text Search): $40 per 1,000 requests
  • SERP API local pack: $5 per 1,000 requests (Scavio at $0.005/query)
  • Google Maps scraping + proxies: $50-200/mo for proxy, plus maintenance time

Limitations of the local pack approach

Local pack results typically show 3-5 businesses per query. The Google Places API returns up to 20 per request. If you need comprehensive coverage of every business in a category/area, the Places API has better coverage. If you need the top-rated, most-visible businesses (the ones customers actually find on Google), local pack results are exactly that -- the businesses Google surfaces first.