Google Maps scraper that requires no API key or login. Extracts business listings by country, region, or coordinates with TLS fingerprinting and anti-blocking measures. CLI and interactive TUI modes. Exports to SQLite and CSV.
- Table of Contents
- Key Features
- Installation
- Quick Start
- CLI Reference
- Data Fields
- Anti-Blocking
- Architecture
- AI Agent Skill
- Tech Stack
- Acknowledgments
- License
| Feature | Description |
|---|---|
| No API Key | Scrapes Google Maps directly, no credentials or billing required |
| Anti-Blocking | TLS fingerprinting (utls), Chrome UA rotation, exponential backoff, cookie consent |
| Country Mode | Scan entire countries with automatic grid generation and ocean filtering |
| Coordinate Mode | Search within a radius around any lat/lng point |
| Interactive TUI | Full terminal UI with search form, live progress, result explorer |
| Country Autocomplete | Searchable country selector with 177 countries (English + Spanish names, ISO codes) |
| Live Filtering | Accent-insensitive, multi-word fuzzy search across all business fields |
| Geo Filtering | Business coordinates validated against country polygon boundaries |
| SQLite Storage | Deduplicated results with UNIQUE(cid, query) constraint |
| CSV Export | Export filtered or full results to CSV from TUI or CLI |
| Proxy Support | HTTP and SOCKS5 proxy for IP rotation |
| Cross-Platform | macOS (Apple Silicon + Intel), Linux (amd64/arm64), Windows |
| Agent Skill | Built-inAI coding agent guidance |
curl -fsSL https://raw.githubusercontent.com/rendis/geotap/main/install.sh | bashgo install github.com/rendis/geotap/cmd/geotap@latestgit clone https://github.com/rendis/geotap.git
cd geotap
make buildRequirements: Go 1.24+
Launch the interactive terminal UI:
geotapNavigate with arrow keys, tab between fields, enter to confirm. The search form includes a live country autocomplete that matches by name, Spanish name, and ISO codes.
Scan an entire country:
geotap scan -queries "restaurants,cafes" -country Chile -output ./projectsScan a specific region:
geotap scan -queries "hotels" -country Spain -region "Catalonia" -output ./projectsScan around coordinates:
geotap scan -queries "pharmacies" -lat 40.4168 -lng -3.7038 -radius 5 -output ./projectsFull options:
geotap scan \
-queries "restaurants,bars" \
-country Germany \
-zoom 12 \
-concurrency 50 \
-min-rating 4.0 \
-lang de \
-output ./datageotap export -db ./projects/geotap_20260212_120000.db| Flag | Default | Description |
|---|---|---|
-queries |
required | Comma-separated search terms |
-output |
required | Output directory for .db and .log files |
-country |
Country name or ISO code (2/3 letter) | |
-region |
Region or state within country | |
-lat / -lng |
Center coordinates (alternative to -country) |
|
-radius |
10 |
Search radius in km (coordinate mode) |
-zoom |
auto | Grid level 10-16. Lower = faster/fewer results, higher = slower/more coverage |
-concurrency |
10 |
Max parallel requests |
-max-pages |
1 |
Pagination depth per sector |
-min-rating |
0 |
Minimum star rating filter |
-max-rating |
0 |
Maximum star rating filter |
-lang |
en |
Search language code |
-proxy |
HTTP or SOCKS5 proxy URL | |
-debug |
false |
Dump raw Google responses |
Each scan generates timestamped files: geotap_YYYYMMDD_HHMMSS.db (SQLite) and .log (session log).
Each business record contains 21 fields:
| Field | Type | Description |
|---|---|---|
name |
string | Business name |
rating |
float | Star rating (0-5) |
review_count |
int | Number of reviews |
category |
string | Primary category |
categories |
string | All categories |
address |
string | Street address |
city |
string | City |
postal_code |
string | Postal/ZIP code |
country_code |
string | ISO country code |
lat / lng |
float | Coordinates |
phone |
string | Phone number |
website |
string | Website URL |
google_url |
string | Google Maps profile URL |
description |
string | Business description |
price_range |
string | Price indicator |
cid |
string | Google business CID |
place_id |
string | Google Places ID |
open_hours |
string | Operating hours |
thumbnail |
string | Thumbnail image URL |
query |
string | Search query used |
Google's bot detection targets repetitive patterns: same endpoint, same parameters, rapid-fire from one source. GeoTap avoids this by design — each request targets unique geographic coordinates across a grid, so the traffic looks like a user browsing different map areas. Combined with TLS fingerprinting that mimics a real Chrome browser, Google sees normal browsing, not scraping.
- TLS Fingerprinting —
refraction-networking/utlswith Chrome Auto preset and HTTP/1.1 ALPN. Standard Go TLS gets fingerprinted and blocked. - Unique Coordinates per Request — Grid-based scanning ensures every request hits different lat/lng. No repeated endpoints.
- Ocean Filtering — Country polygon boundaries discard grid sectors that fall over oceans or outside borders, avoiding unnecessary requests.
- User Agent Rotation — Chrome UAs across Windows, macOS, and Linux, rotated randomly per request.
- Cookie Consent — Pre-sets
CONSENT=YES+cookie to bypass the consent interstitial. - Adaptive Throttling — On rate limits (429/403/302): +500ms delay per consecutive hit (max 5s), -100ms on success. Aborts after 50 consecutive blocks.
- Exponential Backoff — Per-request retries: 2s base, 30s max, 50% jitter, 3 attempts.
- Connection Pooling — 150 max idle connections per host with 90s timeout and keep-alive.
- Proxy Support — Optional HTTP/SOCKS5 proxy via
-proxyflag for IP rotation.
cmd/geotap/
main.go Entry point: TUI (default) or CLI subcommand
scan.go Headless scan: flags → grid → scraper → SQLite
export.go SQLite → CSV export
internal/
model/ Business (21 fields), SearchParams, Sector
engine/
geo/ Grid generation, 177-country boundaries, geocoding
scraper/ utls HTTP client, worker pool, Google Maps parser
storage/ SQLite with dedup (UNIQUE cid+query)
tui/
views/ home, search, progress, explorer, recent, filepicker
styles/ Color theme (violet/cyan palette)
components/ Reusable UI components
GeoTap includes an Agent Skill that provides AI coding agents (Claude Code, Cursor, etc.) with structured guidance for using this tool.
Install via skills.sh
npx skills add https://github.com/rendis/geotap --skill geotapln -s /path/to/geotap/skills/geotap ~/.claude/skills/geotap| Component | Technology |
|---|---|
| Language | Go 1.24 |
| TUI Framework | Bubbletea + Lipgloss |
| TLS Fingerprinting | utls |
| Database | modernc.org/sqlite (pure Go) |
| Geospatial | paulmach/orb |
| Text Normalization | golang.org/x/text |
| Boundaries | Natural Earth ne_110m (embedded) |
| Release | GoReleaser + GitHub Actions |
The core ideas behind GeoTap's anti-blocking strategy were inspired by this thread from @edu_seo_scraper. Thanks for sharing the insights.
MIT — Copyright (c) 2025 rendis

