A fast, intelligent Google Maps scraper that works for ANY location worldwide - no complex setup required.
- Smart Location Targeting - Works without proxies using intelligent location optimization
- Fast Async Scraping - Powered by Playwright
- Any Location Worldwide - Search dentists in Tokyo, restaurants in Paris, hotels in Dubai
- Job Management - Pause, resume, and stop scraping jobs
- Multiple Export Formats - CSV and JSON
- Real-time Progress - Track scraping progress in real-time
- RESTful API - Easy integration with Flask backend
-
Run the installer:
install.bat
This will automatically:
- Create a virtual environment
- Install all dependencies
- Install Playwright browser
-
Start the scraper:
start.bat
-
Open your browser:
- Navigate to
http://localhost:5000 - Start scraping!
- Navigate to
-
Run the installer:
bash install.sh
-
Start the scraper:
bash start.sh
-
Open your browser:
- Navigate to
http://localhost:5000
- Navigate to
curl -X POST http://localhost:5000/api/scrape \
-H "Content-Type: application/json" \
-d '{
"keyword": "Dentist",
"location": "Manhattan, New York, NY",
"max_results": 20
}'That's it! No proxy setup, no complex configuration.
The scraper uses multiple techniques to target your desired location:
- Location Optimization: Converts vague locations like "USA" to specific ones like "New York, NY, USA"
- Coordinate Extraction: Extracts exact coordinates from Google Maps for your location
- Smart Query Building: Creates location-specific queries like "Dentist located in Manhattan, New York, NY"
- URL Parameters: Adds country and language hints to Google Maps URLs
The more specific your location, the better the results:
| Location Input | Quality | Example |
|---|---|---|
| "123 Main St, New York, NY" | ⭐⭐⭐⭐⭐ | Street-level precision |
| "Manhattan, New York, NY" | ⭐⭐⭐⭐ | Neighborhood/district |
| "New York, NY" | ⭐⭐⭐ | City-level |
| "New York" | ⭐⭐ | State-level |
| "USA" | ⭐ | Auto-optimized to "New York, NY, USA" |
Tip: Always include city and country for best results (e.g., "Tokyo, Japan" not just "Tokyo")
POST /api/scrape
Content-Type: application/json
{
"keyword": "Coffee shop",
"location": "San Francisco, CA, USA",
"max_results": 50
}Response:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "running",
"keyword": "Coffee shop",
"location": "San Francisco, CA, USA"
}GET /api/jobs/{job_id}Response:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"keyword": "Coffee shop",
"location": "San Francisco, CA, USA",
"scraped_count": 48,
"failed_count": 2,
"created_at": "2024-01-10T12:00:00",
"completed_at": "2024-01-10T12:05:30"
}GET /api/jobs/{job_id}/resultsResponse:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"results": [
{
"name": "Blue Bottle Coffee",
"address": "66 Mint St, San Francisco, CA 94103",
"phone": "+1 510-653-3394",
"website": "https://bluebottlecoffee.com",
"rating": 4.5,
"reviews_count": 1842,
"category": "Coffee shop",
"hours": "Mon-Fri: 7AM-7PM, Sat-Sun: 8AM-7PM",
"latitude": 37.7786,
"longitude": -122.4095
}
]
}GET /api/jobs/{job_id}/export?format=csv
GET /api/jobs/{job_id}/export?format=jsonDownloads results as CSV or JSON file.
POST /api/jobs/{job_id}/pause # Pause a running job
POST /api/jobs/{job_id}/resume # Resume a paused job
POST /api/jobs/{job_id}/stop # Stop a job permanentlyGET /api/jobsGET /api/statsEdit .env file (copy from .env.example):
# Scraper Settings
MAX_WORKERS=3 # Number of concurrent jobs
DEFAULT_MAX_RESULTS=50 # Default results per job
HEADLESS_MODE=true # Run browser in background
# Storage
DATABASE_PATH=./data/scraper.db
EXPORT_PATH=./exportscurl -X POST http://localhost:5000/api/scrape \
-H "Content-Type: application/json" \
-d '{
"keyword": "French Restaurant",
"location": "Paris, France",
"max_results": 30
}'curl -X POST http://localhost:5000/api/scrape \
-H "Content-Type: application/json" \
-d '{
"keyword": "Hotel",
"location": "Shibuya, Tokyo, Japan",
"max_results": 25
}'curl -X POST http://localhost:5000/api/scrape \
-H "Content-Type: application/json" \
-d '{
"keyword": "Gym",
"location": "Central London, United Kingdom",
"max_results": 40
}'Each place includes:
- name - Business name
- address - Full address
- phone - Phone number
- website - Website URL
- rating - Star rating (0-5)
- reviews_count - Number of reviews
- category - Business category
- hours - Opening hours
- latitude - GPS latitude
- longitude - GPS longitude
- place_id - Google Maps place ID
- url - Google Maps URL
For even better location accuracy, you can optionally use a proxy:
# .env
PROXY_ENABLED=true
PROXY_SERVER=http://proxy.server.com:8080
PROXY_USERNAME=username
PROXY_PASSWORD=password
PROXY_COUNTRY=usThis is completely optional - the scraper works great without it.
- Average Speed: 5-10 places per minute
- Concurrent Jobs: Configurable (default: 3)
- Success Rate: Depends on location specificity
- Specific locations (city + country): High success
- Vague locations (country only): Lower success (auto-optimized)
Make your location more specific:
Instead of:
- ❌ "USA"
- ❌ "Texas"
- ❌ "London"
Use:
- ✅ "Austin, Texas, USA"
- ✅ "Houston, TX, United States"
- ✅ "Central London, United Kingdom"
The scraper will extract coordinates and build optimized queries for better targeting.
- Reduce
max_resultsfor faster jobs - Increase
MAX_WORKERSin.envfor parallel processing - Use
HEADLESS_MODE=truefor better performance
Run:
playwright install chromiumWhen you search for "Dentist in Manhattan, New York, NY":
- Location Optimization: Validates and enhances the location
- Coordinate Extraction: Navigates to "Manhattan, New York, NY" on Google Maps and extracts coordinates (40.7831, -73.9712)
- Query Building: Creates query "Dentist located in Manhattan, New York, NY"
- Country Detection: Detects country "US" from location
- URL Construction: Builds
https://www.google.com/maps/search/Dentist+located+in+Manhattan,+New+York,+NY?gl=us&hl=en - Browser Setup: Creates browser with coordinates (40.7831, -73.9712)
- Search: Navigates to search URL and extracts results
This multi-layer approach maximizes location accuracy without requiring proxies.
- Be Specific: Use "Tokyo, Japan" not just "Tokyo"
- Include Neighborhoods: "Shibuya, Tokyo" is better than "Tokyo"
- Add Country: Always include country for international searches
- Use English: Location names in English work best
- Avoid Abbreviations: "New York" is better than "NY" alone
MIT
For issues, questions, or feature requests, please open an issue on GitHub.