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 jobGET /api/v1/jobs— list jobsGET /api/v1/jobs/{id}— inspect a jobDELETE /api/v1/jobs/{id}— remove a jobGET /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.