DrProspect is a Python CLI tool for map-based business prospecting. Given a keyword and a geographic center point, it partitions the search area into an Uber H3 hexagon grid, queries the Google Places API (New) at each cell center, and exports qualified leads to CSV — with a checkpoint system so interrupted runs resume without duplicates.
What it does
Keyword search by industry
The tool searches by business type or industry keyword (e.g. "gyms", "gardening services", "seguridad privada") — matching Google’s text search semantics, not just exact business names. This makes it useful for outbound sales, market research, and competitive mapping.
Hexagon grid coverage
hexgrid.py uses Uber’s H3 library to tile the area around a center coordinate:
- Converts center lat/lng to an H3 cell at a chosen resolution (7–11)
- Expands outward with
grid_disk()for configurable ring size - Returns a list of cell-center coordinates to search systematically
Resolution controls granularity: resolution 9 ≈ 174 m cell edges (city-block scale); higher resolution means smaller cells and more API calls but denser coverage.
Data extraction
places_client.py calls the Places API Text Search endpoint with a circular location bias per hexagon. For each place it extracts:
| Field | Source |
|---|---|
place_id | Unique Google place identifier (dedup key) |
name | Business display name |
phone | International or national phone number |
website | Website URI |
rating | Star rating |
review_count | Total review count |
address | Formatted address |
coordinates | Lat/lng pair |
reviews_preview | Text from up to 3 recent reviews |
Pagination follows nextPageToken (up to 3 pages / 60 results per hexagon). A 100 ms delay between requests avoids rate-limit bursts.
CSV export & checkpoint
checkpoint.py manages durable output:
- CSV — Appends rows with a fixed column schema; creates header on first write
- Checkpoint JSON — Stores
processed_place_idsandprocessed_hexagons - Deduplication — Skips places already in the checkpoint or existing CSV
- Resumability — Re-running with the same output path continues from the last saved state
- Buffered writes — Flushes every 10 new places to limit data loss on crash
CLI interface
python prospector.py "gyms" --lat 40.7831 --lng -73.9712 -o gyms.csv
Required: search term, --lat, --lng. Optional: --output, --resolution, --ring-size, --radius, --api-key (or GOOGLE_PLACES_API_KEY env var). API key loads from .env via python-dotenv.
A test_api.py script runs a minimal Places query to verify API key connectivity before a full prospecting run.
Real-world runs
The repo includes sample output from Mexico-focused prospecting campaigns:
mx_mascotas.csv/gdl_mascotas.csv— Pet-related businesses (national and Guadalajara)mx_seguridad_privada.csv/gdl_seguridad_privada.csv— Private security companies
Each run pair has a matching .checkpoint.json demonstrating the resume workflow.
Tech stack
| Layer | Choice |
|---|---|
| Language | Python 3.13 |
| Hex grid | Uber H3 (h3>=4.0.0) |
| HTTP | requests |
| Config | python-dotenv |
| API | Google Places API (New) — Text Search REST |
| Output | CSV + JSON checkpoint |
No database or web UI — the tool is designed as a scriptable pipeline for batch lead generation.
Development process
Project design
ProjectSprint.md captured the initial spec: keyword search over a hexagon-partitioned area, extract name/phone/website/rating/reviews/location to CSV, with checkpoint-based deduplication and resume support.
Initial implementation
Single-day build across four modules:
hexgrid.py— H3 center generation and resolution-to-radius mappingplaces_client.py— Text Search client with field mask, pagination, and place data extractioncheckpoint.py— JSON checkpoint + CSV append with dedupprospector.py— CLI orchestrator wiring grid → API → CSV → checkpoint
Added requirements.txt, README.md with setup/usage docs, and test_api.py for API key validation. Committed sample prospecting runs for pet businesses and private security firms in Mexico and Guadalajara.


Building Smartclic Demo