Fast, lightweight HTTP-based Google Maps scraper for places & reviews.
A request-based scraper that extracts Google Maps place data and reviews without browser automation.
Key features:
- Concurrency -> Parallel workers with independent sessions
- Resume support -> Job tracking + per-place review resumption from saved cursors
- Session persistence -> 0-RTT TLS resumption via
session.json - Rate limit handling -> Exponential backoff + connection refresh on 429
- WAL-mode SQLite -> Concurrent reads/writes without lock contention
- Email extraction -> Fetches the business website and extracts contact emails
pip install -r requirements.txtRequires Python 3.10+.
# Search + scrape places and reviews
python main.py search "restaurants in Paris" --max-places=20 --max-reviews=50
# Scrape a single place by ID
python main.py place "0x89e377427d7f0199:0x5937c65cee2427f0" --max-reviews=200
# Search only (fast discovery, no details/reviews)
python main.py list "hotels in Dubai" --max-places=30
# Resume an interrupted job
python main.py resume <job_id> --max-reviews=100
# Database stats
python main.py stats
# Extract emails from business websites
python main.py search "hotels in London" --max-places=50 --extract-emails| Command | Description | Returns |
|---|---|---|
search |
Search + full scrape | All fields + reviews |
place |
Scrape a single known place | All fields + reviews (resumes from DB cursor) |
list |
Search only -> no details/reviews | Name, address, rating, coords, categories |
resume |
Resume a job | Continues from last saved cursor per place |
stats |
Database statistics | Place count, review count, pending jobs |
| Flag | Description | Default |
|---|---|---|
--db |
SQLite database path | output/gmaps.db |
--max-places |
Max places to scrape (None = unlimited) |
unlimited |
--max-reviews |
Max reviews per place (None = all, 0 = skip) |
unlimited |
--workers |
Concurrent workers | 4 |
--delay |
Min seconds between requests | 2.5 |
--proxy |
Proxy URL (socks5://... or http://...) |
None |
--session-file |
Session persistence path | output/session.json |
--lang |
Language code | en |
--gl |
Country/region code | us |
--extract-emails |
Fetch website & extract email if missing | false |
python main.py list "coffee shops in Amsterdam" --max-places=20
python main.py place "0x47c609c7..." --max-reviews=200python main.py search "restaurants in Nairobi" --max-places=20 --max-reviews=0
python main.py resume <job_id> --max-reviews=300python main.py search "hotels in London" --max-places=100 --max-reviews=50 --workers=8When Google Maps doesn't list an email, the scraper can visit the business website and extract it:
python main.py search "restaurants in Nairobi" --max-places=30 --extract-emailsWorks with search, place, and resume.
search/place--> Saves a pagination cursor per place in the databaseresume <job_id>--> Re-opens places that need more reviews and continues from their saved cursorsplacerepeat runs --> Skips if you already have enough reviews; fetches more if you increased--max-reviews
This tool is provided for educational and research purposes. By using it, you agree to comply with applicable laws regarding data collection.
