Google Maps Scraper: Open-Source Lead Extraction at Scale

Explore a Go-based Google Maps scraper with CLI, Web UI, REST API, proxy support, email extraction, and distributed scaling.

Google Maps Scraper: Open-Source Lead Extraction at Scale

Collecting structured local-business data is useful for sales prospecting, market research, local SEO, enrichment, and automation—but manually copying listings from Google Maps does not scale. The open-source gosom/google-maps-scraper turns Google Maps searches into structured records containing business details, contact information, reviews, coordinates, and optional email addresses.

The project is MIT licensed and offers several ways to run the scraper: a command-line interface, a local Web UI, a REST API, an optional self-hosted SaaS edition, and an AI-agent skill for natural-language workflows. It is written primarily in Go and uses Playwright for browser-based extraction.

What the scraper collects

A typical result can include more than 33 fields, including:

  • Business name, category, description, and status
  • Street address and complete formatted address
  • Phone number and official website
  • Google Maps link, Place ID, CID, and other identifiers
  • Average rating, review count, rating breakdown, and customer reviews
  • Latitude, longitude, timezone, plus code, and Street View URL
  • Operating hours and popular-times information
  • Price range, reservations, menu, and online-ordering links
  • Images, thumbnail, owner status, accepted credit cards, and additional metadata
  • Email addresses discovered by optionally crawling business websites

Extended review collection can retrieve up to approximately 300 reviews per place with the -extra-reviews flag. Email extraction is opt-in because visiting every business website significantly increases runtime.

Quick start with Docker

Docker is the recommended installation method because the image includes the browser automation environment. Create an output directory and mount an input file containing one query per line:

mkdir -p gmaps-output

docker run \\
  -v gmaps-playwright-cache:/opt \\
  -v "$PWD/example-queries.txt:/queries.txt:ro" \\
  -v "$PWD/gmaps-output:/out" \\
  gosom/google-maps-scraper \\
  -input /queries.txt \\
  -results /out/results.csv \\
  -depth 1 \\
  -exit-on-inactivity 3m

A query file might look like this:

restaurants in Berlin
software companies in Austin
coffee shops in Athens

The default output is CSV. To write JSON instead, add -json and use a .json result path:

docker run \\
  -v gmaps-playwright-cache:/opt \\
  -v "$PWD/queries.txt:/queries.txt:ro" \\
  -v "$PWD/output:/out" \\
  gosom/google-maps-scraper \\
  -input /queries.txt \\
  -results /out/results.json \\
  -json \\
  -depth 1 \\
  -exit-on-inactivity 3m

The first run may download browser libraries and initialize the Playwright cache. Persisting /opt in a named Docker volume avoids repeating that work.

Three ways to use it

1. Command line

The CLI is ideal for repeatable jobs, shell scripts, cron tasks, and data pipelines. Important options include:

Option Purpose
-input Input file containing queries or Google Maps URLs
-results CSV, JSON, or JSONL output path
-depth Maximum result scrolling depth; default is 10
-c Number of concurrent scrape jobs; default is half the CPU cores
-email Crawl business websites for email addresses
-extra-reviews Collect extended review data
-resume Continue an interrupted file-based scrape
-fast-mode Quickly collect up to 21 results per query
-lang Google Maps language, such as de
-geo Search coordinates, for example 37.7749,-122.4194
-radius Search radius in meters
-grid-bbox Divide a geographic bounding box into cells

2. Web UI and REST API

Start the local Web UI with:

mkdir -p gmapsdata

docker run \\
  -v "$PWD/gmapsdata:/gmapsdata" \\
  -p 8080:8080 \\
  gosom/google-maps-scraper \\
  -data-folder /gmapsdata

Open http://localhost:8080. The server also exposes an OpenAPI 3.0.3 specification at http://localhost:8080/api/docs.

The main API endpoints are:

  • POST /api/v1/jobs — create a scraping job
  • GET /api/v1/jobs — list jobs
  • GET /api/v1/jobs/{id} — inspect a job
  • DELETE /api/v1/jobs/{id} — remove a job
  • GET /api/v1/jobs/{id}/download — download CSV results

This makes the scraper suitable for integrating with internal dashboards, CRM workflows, or scheduled lead-generation services.

3. AI-agent workflow

The repository includes an Agent Skills package that works with tools such as Claude Code, Codex, Cursor, and GitHub Copilot. Install it with:

npx skills add gosom/google-maps-scraper

You can then request something like:

Find dentists in Berlin and include their websites and email addresses.

The skill can infer search defaults, perform a small validation run, launch the Docker crawl, monitor progress, and help save or analyze results. Proxy credentials are entered through a masked local terminal prompt rather than pasted into the agent conversation. Docker and Node.js are required on macOS, Linux, or Windows through WSL.

Handling large jobs

The project reports approximately 120 places per minute with -c 8 -depth 1, although actual throughput depends on query complexity, browser resources, network conditions, and blocking.

A representative estimate is:

Keywords Results per keyword Total places Estimated time
100 16 1,600 ~13 minutes
1,000 16 16,000 ~2.5 hours
10,000 16 160,000 ~22 hours

Concurrency controls the number of simultaneous jobs. Browser process and page settings provide additional control:

./google-maps-scraper \\
  -c 8 \\
  -browser-pool-size 2 \\
  -pages-per-browser 4 \\
  -input queries.txt \\
  -results results.csv \\
  -depth 1

Here, eight jobs are distributed across two browser processes, with four tabs per browser. Monitor resource use with htop or docker stats; Chromium can consume substantial CPU and memory. The product of browser-pool-size and pages-per-browser should roughly match or exceed -c to keep workers busy.

For interrupted jobs, use resume mode:

./google-maps-scraper \\
  -resume \\
  -input queries.txt \\
  -results results.csv \\
  -depth 10

Resume mode reads existing CSV or JSONL output, skips written places, and maintains a <results>.resume.json sidecar containing completed input queries. It requires a regular file output and is incompatible with stdout, custom writers, LeadsDB output, and fast mode.

Geographic coverage with grid scraping

A single Google Maps search may not expose enough results for a dense area. Grid scraping divides a bounding box into cells and runs a query from each cell:

./google-maps-scraper \\
  -input queries.txt \\
  -results peristeri-cafes.csv \\
  -grid-bbox "38.0077,23.6719,38.0257,23.6947" \\
  -grid-cell 0.5 \\
  -zoom 16 \\
  -depth 1 \\
  -c 4

Grid mode helps increase geographic coverage, but it does not strictly clip results to the bounding box. For strict distance filtering, use -geo with -radius in fast mode or post-filter records using latitude and longitude.

Fast mode returns up to 21 results per query, ordered by distance:

./google-maps-scraper \\
  -input queries.txt \\
  -results results.csv \\
  -fast-mode \\
  -zoom 15 \\
  -radius 5000 \\
  -geo '37.7749,-122.4194'

Fast mode is currently beta and may be more susceptible to blocking. It cannot be combined with -grid-bbox.

Proxy configuration

For larger jobs, proxies can help distribute traffic and reduce rate limiting. Supported protocols include SOCKS5, SOCKS5H, HTTP, and HTTPS:

./google-maps-scraper \\
  -input queries.txt \\
  -results results.csv \\
  -proxies 'socks5://user:pass@host:port,http://host2:port2' \\
  -depth 1 \\
  -c 2

You can also place one proxy URL per line in a file:

./google-maps-scraper \\
  -input queries.txt \\
  -results results.csv \\
  -proxies-file proxies.txt

Proxy use is not a substitute for responsible crawl design. Start with low concurrency, validate a small sample, and comply with applicable laws and the terms governing the data you access.

Exporting directly to LeadsDB

Instead of writing intermediate files, the scraper can send records directly to LeadsDB, which provides deduplication, filtering, API access, and exports:

export LEADSDB_API_KEY="your-api-key"
./google-maps-scraper \\
  -input queries.txt \\
  -exit-on-inactivity 3m

Or provide the key explicitly with -leadsdb-api-key. Google Maps fields are mapped to lead fields such as name, category, phone, website, address, coordinates, rating, review count, email, logo URL, and source ID. Additional Maps metadata is retained as custom attributes.

Scaling with PostgreSQL and Kubernetes

For distributed workloads, PostgreSQL can act as a shared job provider. Start the development database, seed jobs, and run scraper workers on multiple machines:

docker-compose -f docker-compose.dev.yaml up -d

./google-maps-scraper \\
  -dsn "postgres://postgres:postgres@localhost:5432/postgres" \\
  -produce \\
  -input example-queries.txt \\
  -lang en

./google-maps-scraper \\
  -c 2 \\
  -depth 1 \\
  -dsn "postgres://postgres:postgres@localhost:5432/postgres"

A Kubernetes deployment can run multiple replicas:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: google-maps-scraper
spec:
  replicas: 3
  selector:
    matchLabels:
      app: google-maps-scraper
  template:
    metadata:
      labels:
        app: google-maps-scraper
    spec:
      containers:
        - name: google-maps-scraper
          image: gosom/google-maps-scraper:latest
          args: ["-c", "1", "-depth", "10", "-dsn", "postgres://user:pass@host:5432/db"]
          resources:
            requests:
              memory: "512Mi"
              cpu: "500m"

Headless browsers require meaningful CPU and memory allocations, so resource requests should be tuned through load testing rather than copied blindly.

Build from source

The project requires Go 1.26.6 or newer:

git clone https://github.com/gosom/google-maps-scraper.git
cd google-maps-scraper
go mod download
go build
./google-maps-scraper \\
  -input example-queries.txt \\
  -results results.csv \\
  -exit-on-inactivity 3m

Developers can also create custom Go writer plugins:

go build -buildmode=plugin -tags=plugin -o myplugin.so myplugin.go
./google-maps-scraper \\
  -writer ~/plugins:MyWriter \\
  -input queries.txt

Operational considerations

Anonymous telemetry is enabled by default and can be disabled with:

export DISABLE_TELEMETRY=1

The repository is MIT licensed, but users remain responsible for complying with applicable privacy, data-protection, and website terms. Avoid collecting data you do not need, protect exported contact information, and build rate limits and retry policies into production workflows.

With its combination of browser-based extraction, structured output, resumable jobs, geographic controls, proxy support, APIs, and distributed execution, Google Maps Scraper is more than a one-off command. It is a practical foundation for developers who need to turn local search results into repeatable, inspectable data pipelines.

Source

gosom/google-maps-scraper: scrape data from Google Maps. Extracts data such as the name, address, phone number, website URL, rating, reviews number, latitude and longitude, reviews,email and more for each place