How to Scrape Google Maps and Local Pack Data with Proxies

How to Scrape Google Maps and Local Pack Data with Proxies

Google Maps is the largest business directory on the planet. It contains millions of business listings with addresses, phone numbers, opening hours, reviews, ratings, photos, and competitive positioning data. For SEO professionals, marketers, and data analysts, this data is invaluable — and nearly impossible to access at scale without proxies.

Google Maps data powers local SEO competitive analysis, lead generation, market research, and reputation monitoring. This guide covers the complete technical approach to extracting it reliably.

Google Maps Data Structure

Before scraping, you need to understand what data is available and how it is organized.

Business Listing Data Points

Each Google Maps business listing contains:

  • Business name and category classification.
  • Address and geographic coordinates (latitude/longitude).
  • Phone number and website URL.
  • Opening hours (regular and special/holiday hours).
  • Star rating (aggregate, 1.0-5.0 scale).
  • Total review count and individual reviews with text, rating, date, and reviewer info.
  • Photos uploaded by the business and by customers.
  • Popular times data showing foot traffic patterns by hour and day.
  • Attributes such as “wheelchair accessible,” “outdoor seating,” “free Wi-Fi.”
  • Google Business Profile category and subcategories.
  • Price level indicator (where applicable).
  • Q&A section with user-submitted questions and business responses.

Local Pack vs Maps Interface

Google Maps data appears in two contexts that SEOs care about:

  1. The local pack (also called the map pack) — the 3-5 business results that appear directly in Google Search for local queries. This is the data that drives local SEO strategy.
  2. The Google Maps interface — the full maps.google.com experience with more detailed listings, directions, and discovery features.

Both can be scraped, but they require different approaches. The local pack is embedded in standard Google SERP HTML. The Maps interface loads dynamically through JavaScript and API calls.

Proxy Setup for Google Maps Scraping

Google Maps applies the same anti-bot protections as Google Search, with some additions specific to map interactions.

Why Proxies Are Essential

Without proxies, Maps scraping hits walls quickly:

  • Rate limiting kicks in after 20-50 requests from a single IP.
  • CAPTCHA challenges appear for sustained automated access.
  • IP bans block the IP for hours or days after detected abuse.
  • Result modification — Google may serve simplified or incomplete results to suspected bots.

Recommended Proxy Types

Mobile proxies are the strongest choice for Maps scraping:

  • Google Maps is predominantly a mobile product. Mobile carrier IPs match the expected user profile perfectly.
  • Mobile IPs have the highest trust scores, meaning fewer CAPTCHAs and more complete data in responses.
  • Geo-targeting is built in — a Singapore mobile carrier IP returns Singapore-local results naturally.

Residential proxies work well for broad Maps scraping:

  • Larger IP pools allow more parallel connections.
  • Good for scraping across many geographic areas where you do not need carrier-level trust.
  • Lower cost per GB for high-volume extraction.

Datacenter proxies are not recommended for Maps scraping. Google identifies datacenter IPs easily, and Maps results may be incomplete or modified for requests from these IPs.

Proxy Configuration

For Maps scraping, configure your proxies with:

  • Geo-targeting matching your search area. If you are scraping Singapore businesses, use Singapore-based proxies.
  • Rotation per request or per small batch. Rotate IPs every 5-10 requests when scraping different businesses. Use sticky sessions when extracting multiple data points from a single listing.
  • Appropriate User-Agent strings. Match the proxy type — mobile User-Agent for mobile proxies, desktop for residential.

Scraping Business Listings

There are several methods to extract business listing data from Google Maps.

Method 1: Scraping Local Pack from Google Search

The simplest approach is to query Google Search for local keywords and extract the local pack results from the SERP.

import requests
from bs4 import BeautifulSoup

def scrape_local_pack(keyword, location_proxy):
    """Scrape the local pack from a Google SERP."""
    url = f"https://www.google.com.sg/search?q={keyword.replace(' ', '+')}&gl=sg&hl=en"

    headers = {
        'User-Agent': 'Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36',
        'Accept-Language': 'en-SG,en;q=0.9',
    }

    response = requests.get(
        url,
        headers=headers,
        proxies={'https': location_proxy},
        timeout=30
    )

    soup = BeautifulSoup(response.text, 'html.parser')
    local_results = []

    for result in soup.select('div[data-cid]'):
        name = result.select_one('span.OSrXXb')
        rating = result.select_one('span.MW4etd')
        review_count = result.select_one('span.UY7F9')
        address = result.select_one('span.lqhpac div')

        if name:
            local_results.append({
                'name': name.get_text(),
                'rating': float(rating.get_text()) if rating else None,
                'reviews': review_count.get_text() if review_count else None,
                'address': address.get_text() if address else None,
            })

    return local_results

This method is fast and works through any proxy type, but it only returns the data shown in the local pack (typically 3 businesses with limited details).

Method 2: Scraping Google Maps Directly

For full listing details, you need to interact with the Google Maps interface. Maps loads data through XHR requests to internal APIs.

The most reliable approach uses a headless browser configured with a mobile viewport:

from playwright.sync_api import sync_playwright

def scrape_maps_listing(place_name, city, proxy_config):
    """Scrape a full Google Maps listing."""
    with sync_playwright() as p:
        browser = p.chromium.launch(
            proxy={
                'server': proxy_config['server'],
                'username': proxy_config['username'],
                'password': proxy_config['password'],
            }
        )

        context = browser.new_context(
            viewport={'width': 412, 'height': 915},
            user_agent='Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36',
        )

        page = context.new_page()
        search_query = f"{place_name} {city}".replace(' ', '+')
        page.goto(f"https://www.google.com/maps/search/{search_query}")

        # Wait for results to load
        page.wait_for_selector('[data-value]', timeout=10000)

        # Extract listing data
        listing = {}

        name_elem = page.query_selector('h1')
        if name_elem:
            listing['name'] = name_elem.inner_text()

        rating_elem = page.query_selector('div.F7nice span[aria-hidden]')
        if rating_elem:
            listing['rating'] = rating_elem.inner_text()

        # Extract additional fields...

        browser.close()
        return listing

Method 3: Google Maps Place Details API (Unofficial)

Google Maps internal API endpoints can be called directly, bypassing the need for a headless browser. These endpoints return structured data but are undocumented and change without notice.

The general approach:

  1. Identify the Place ID for a business (from search results or known listings).
  2. Construct a request to Google’s internal place details endpoint.
  3. Parse the protobuf or JSON response.

This method is the most efficient for large-scale scraping but requires reverse-engineering Google’s internal APIs and maintaining the implementation as endpoints change. It is best suited for teams with dedicated engineering resources.

Scraping Reviews and Ratings

Reviews are among the most valuable data points for competitive analysis and reputation monitoring.

Review Data Extraction

For each review, extract:

  • Reviewer name and profile link.
  • Star rating (1-5).
  • Review date.
  • Review text (full text, not truncated).
  • Business response (if any).
  • Review photos (if any).

Pagination Handling

Google Maps loads reviews in batches, typically 10 at a time. To get all reviews for a business:

  1. Load the initial review page.
  2. Scroll or trigger “load more” to fetch the next batch.
  3. Continue until all reviews are loaded.

For businesses with thousands of reviews, this requires patience and careful rate limiting to avoid triggering blocks.

Sorting Options

Google Maps allows sorting reviews by:

  • Most relevant (default).
  • Newest.
  • Highest rating.
  • Lowest rating.

For competitive analysis, scraping “newest” sorted reviews gives you the most current reputation data. For comprehensive analysis, scrape all reviews or at minimum the most recent 50-100.

Handling Google’s Rate Limiting

Google Maps is aggressive about rate limiting. Here is how to stay under the radar.

Request Timing

  • Between different businesses: 5-15 seconds delay.
  • Between review page loads for the same business: 2-5 seconds.
  • Between search queries: 8-20 seconds.

Add randomization to all delays. Exact intervals are a bot fingerprint.

Session Management

For Maps scraping, use sticky proxy sessions when drilling into a single listing:

  1. Connect to a proxy IP.
  2. Load the Maps search.
  3. Click into a specific listing.
  4. Scrape the listing details and reviews.
  5. Return to search results or rotate IP for the next listing.

Rotating IP mid-listing is a bot signal because real users maintain sessions.

Error Handling

Monitor for these rate limiting signals:

  • HTTP 429 (Too Many Requests): Back off for 60-120 seconds, then retry with a new IP.
  • CAPTCHA pages: Retire the IP and rotate.
  • Empty or minimal results: Google may serve stripped-down results as a soft rate limit. Back off and retry.
  • Redirect to consent pages: Handle cookie consent prompts programmatically.

Geo-Targeted Searches

For local SEO analysis, you often need to see Maps results as they appear from different locations.

Location-Based Result Differences

Google Maps results for the same query vary based on:

  • IP location: The primary geographic signal for non-GPS requests.
  • Explicit location in query: “Restaurant in Orchard Road” returns different results than “restaurant in Jurong.”
  • Map viewport: If interacting with the Maps interface, the visible map area influences results.

Multi-Location Scraping Setup

To analyze local competition across different areas:

locations = [
    {'name': 'Central Singapore', 'proxy': 'sg-central-proxy:port'},
    {'name': 'East Singapore', 'proxy': 'sg-east-proxy:port'},
    {'name': 'West Singapore', 'proxy': 'sg-west-proxy:port'},
]

keywords = ['restaurant', 'plumber', 'gym', 'dentist']

for location in locations:
    for keyword in keywords:
        results = scrape_local_pack(keyword, location['proxy'])
        store_results(keyword, location['name'], results)
        time.sleep(random.uniform(8, 15))

For a single city like Singapore, one mobile proxy with a local carrier IP is typically sufficient for city-level results. For larger countries, you need proxies in each target region.

Coordinate-Based Searches

For precise geo-targeting, you can include coordinates in your Maps query:

https://www.google.com/maps/search/restaurant/@1.3521,103.8198,15z

This searches for restaurants near the specified coordinates (Singapore’s approximate center) at zoom level 15. Varying the coordinates lets you simulate searches from different neighborhoods.

Building a Local Business Database

Combining Maps scraping with systematic data collection lets you build a comprehensive local business database.

Data Collection Pipeline

  1. Seed keywords: Start with category keywords relevant to your analysis (e.g., “dentist,” “restaurant,” “real estate agent”).
  2. Location grid: Divide your target area into a grid of coordinates, spacing them based on the density of businesses you expect.
  3. Scrape search results: For each keyword-location combination, scrape the Maps search results.
  4. Deduplicate: The same business appears in overlapping searches. Deduplicate by Place ID or name+address combination.
  5. Enrich: For each unique business, scrape the full listing details (hours, reviews, attributes).
  6. Update regularly: Schedule periodic re-scrapes to track changes in ratings, review counts, and listing details.

Database Design

Structure your database with three core tables: a businesses table (storing place ID, name, category, address, coordinates, phone, website, rating, review count, and timestamps), a reviews table (linked to businesses, storing reviewer name, rating, text, date, and business response), and a scrape history table (tracking which keywords and locations were scraped and when). Use the Place ID as a unique identifier for deduplication across overlapping searches.

Use Cases for a Local Business Database

A well-maintained local business database supports multiple SEO and business intelligence applications:

  • Competitive analysis: Track how competitors’ ratings and review counts change over time. Identify when a competitor launches a review campaign or receives negative press.
  • Local SEO auditing: Compare a client’s listing completeness, rating, and review velocity against the local competition.
  • Market research: Identify underserved areas (high search volume for a category but few well-rated businesses).
  • Lead generation: Identify businesses with poor online presence (low ratings, few reviews, no website) that could benefit from SEO services.

For the rank tracking side of local SEO, see our local SEO rank tracking guide. For a broader view of how proxies support these workflows, see the SEO proxies hub.

Scaling and Maintenance

Scaling Considerations

As your scraping operation grows:

  • Parallel workers: Run 5-10 concurrent scrapers, each with its own proxy connection, to increase throughput.
  • Batch scheduling: Spread your scraping over 24 hours to maintain consistent, low-profile query rates.
  • Priority queuing: Scrape high-value targets (direct competitors, key categories) more frequently than supplementary data.

Maintaining Data Freshness

Business data changes constantly. Ratings change daily. Reviews are posted hourly. Hours get updated seasonally. Plan your re-scrape schedule:

  • Ratings and review counts: Weekly for competitive monitoring, daily for reputation management clients.
  • Full listing details: Monthly for most businesses.
  • Reviews: Weekly for primary competitors, monthly for the broader database.

Legal and Ethical Considerations

Google’s Terms of Service prohibit scraping. Use scraped data for analysis and internal decision-making, not republishing. Respect rate limits, avoid storing personal information beyond what is publicly displayed, and consult legal counsel if you plan to use scraped data commercially.

Proxy Investment for Maps Scraping

Google Maps scraping at scale requires reliable proxies. The proxy cost is a fraction of the value of the data you extract — a single competitive analysis project or lead generation campaign typically justifies months of proxy expenses.

DataResearchTools mobile proxies provide Singapore carrier IPs that are ideal for scraping Singapore-local Maps results. The mobile carrier trust level ensures high success rates and complete data in responses, reducing the need for retries and the risk of modified results.

For managing multiple client accounts alongside your scraping operation, see our multi-account proxy guide.

Ready to build your local business intelligence infrastructure? Start with mobile proxies designed for reliable Google Maps data extraction.


Related Reading

Scroll to Top