A lightweight REST API for extracting business leads from Google Maps using Playwright.
# Windows
run_api.bat
# Manual
pip install -r requirements.txt
playwright install chromium
python api.pyAPI: http://localhost:8000
Swagger Docs: http://localhost:8000/docs
| Method | Endpoint | Description |
|---|---|---|
GET |
/health |
Simple health check |
GET |
/status |
Detailed service status |
POST |
/v1/scrape |
Start scraping job |
GET |
/v1/scrape/status |
Get scraping progress |
POST |
/v1/scrape/stop |
Stop current scrape |
GET |
/v1/results |
Get scraped results |
DELETE |
/v1/results |
Clear stored results |
Set API_KEY in .env, then include in requests:
# Header method (recommended)
curl -H "X-API-Key: YOUR_KEY" http://localhost:8000/status
# Query parameter
curl "http://localhost:8000/status?api_key=YOUR_KEY"Leave
API_KEYempty to disable authentication (dev only).
curl -X POST http://localhost:8000/v1/scrape \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"keyword": "coffee shop",
"location": "jakarta",
"limit": 20,
"phone_required": true,
"min_rating": 4.0
}'Response:
{
"message": "Scraping started",
"query": "coffee shop jakarta",
"limit": 20
}curl -H "X-API-Key: YOUR_KEY" http://localhost:8000/v1/scrape/statusResponse:
{
"is_running": true,
"progress": 45,
"total": 100,
"status": "Scraped 5/10: Coffee Place...",
"current_query": "coffee shop jakarta",
"results_count": 5,
"started_at": "2026-01-17T01:00:00",
"error": null
}curl -H "X-API-Key: YOUR_KEY" http://localhost:8000/v1/resultsResponse:
{
"total": 15,
"limit": 100,
"offset": 0,
"count": 15,
"data": [
{
"name": "Kopi Kenangan",
"phone": "628123456789",
"address": "Jl. Sudirman No. 1, Jakarta",
"website": "https://example.com",
"rating": "4.5",
"category": "Coffee shop",
"lat": -6.2088,
"lng": 106.8456
}
]
}| Parameter | Type | Default | Description |
|---|---|---|---|
keyword |
string | required | Search keyword (e.g., "coffee shop") |
location |
string | optional | Location (e.g., "jakarta") |
limit |
int | 20 | Max businesses to scrape |
headless |
bool | true | Run browser in headless mode |
phone_required |
bool | true | Skip results without phone |
website_required |
bool | false | Skip results without website |
min_rating |
float | 0.0 | Minimum rating filter |
country_code |
string | "ID" | Phone number format |
- Python 3.10+
- Chrome/Chromium (auto-installed by Playwright)
# Create virtual environment
python -m venv venv
venv\Scripts\activate # Windows
source venv/bin/activate # Linux/Mac
# Install dependencies
pip install -r requirements.txt
playwright install chromium
# Configure
cp .env.example .env
# Edit .env and set your API_KEY
# Run
python api.pyfastapi>=0.100.0
uvicorn>=0.23.0
python-dotenv>=1.0.0
playwright>=1.40.0
beautifulsoup4>=4.12.0
pydantic>=2.0.0
.
βββ api.py # FastAPI app & routes
βββ scraper_async.py # Scraping logic (Playwright)
βββ requirements.txt
βββ .env.example
βββ .env # Your local config (not in Git)
βββ run_api.bat
βββ .gitignore
βββ README.md
Private and proprietary.
Created by dewhush π