Geospatial scraper for Google Maps using Uber's H3 hexagonal grid. Extracts business listings (name, phone, website, address, rating, category, coordinates) and enriches each result with emails and social links harvested directly from the business website.
pip install -r requirements.txt
playwright install chromiumEdit QUERY and LOCATION in main.py, then run:
python main.pyThree files are written automatically:
| File | Format | Notes |
|---|---|---|
results.json |
JSON | Always written (also as a crash-safe checkpoint before enrichment) |
results.csv |
CSV | Always written |
results.xlsx |
Excel | Written if openpyxl is installed |
{
"nome": "Clinica Veterinaria XYZ",
"categoria": "veterinary care",
"telefono": "+39 06 123456",
"sito": "https://clinicaxyz.it",
"indirizzo": "Via Roma 1, 00100 Roma RM",
"rating": "4.2 stelle",
"lat": 41.90,
"lng": 12.49,
"h3": "891e2650b3bffff",
"url": "https://maps.google.com/maps/place/...",
"source": "veterinari Dragoncello, Roma",
"emails": ["info@clinicaxyz.it"],
"social": {
"instagram": ["https://instagram.com/clinicaxyz"],
"facebook": ["https://facebook.com/clinicaxyz"]
}
}main.py
├── src/geocoder.py → place name → coordinates (OpenStreetMap Nominatim)
├── src/h3_grid.py → H3 hexagonal cells (fallback: src/grid.py Cartesian)
├── src/scraper_worker.py → Playwright scraping engine
├── src/enricher.py → per-website email + social harvesting
├── src/writer.py → JSON / CSV / Excel output
├── src/config.py → speed profiles + multilingual cookie labels
└── src/logger.py → LOW / MEDIUM / HIGH log levels
| Parameter | Default | Description |
|---|---|---|
QUERY |
— | What to search (e.g. "dentisti") |
LOCATION |
— | Where to search (e.g. "Roma", "Prati, Roma") |
SKIP_DETAILS |
False |
True = names + URL only (≈ 4× faster) |
H3_RESOLUTION |
9 |
Hexagon size: 7 ≈ 5 km, 8 ≈ 1 km, 9 ≈ 200 m |
H3_K_RINGS |
2 |
Radius in rings (5 → ~61 cells ≈ 3 km) |
MAX_WORKERS |
1 |
1 = sequential; 2–3 = parallel tabs |
HEADLESS |
False |
True = invisible browser (server mode) |
LOG_LEVEL |
"MEDIUM" |
LOW / MEDIUM / HIGH |
For full documentation see ADVANCED.md.