# πΊοΈ Google Maps Business Listings Scraper
A **stable, human-like, low-volume** web scraper for collecting publicly visible business listings from Google Maps using **Playwright + Node.js**.
> β‘ Features: REST API, CLI tool, authentication, intelligent scrolling, duplicate prevention, JSON/CSV export
---
## π Table of Contents
- Features
- Quick Start
- API Server
- CLI Usage
- Configuration
- Output Format
- How It Works
- Safety & Ethics
- License
---
# πΊοΈ Google Maps Business Listings Scraper
## π₯ Live Demo
[](https://www.youtube.com/watch?v=9DB4_ekxsMU)
## β¨ Features
### π― Core Capabilities
- Extract business name, rating, address, phone, website
- REST API with authentication
- CLI tool for manual scraping
- Intelligent scrolling detection
- Automatic duplicate removal
- JSON & CSV export
### π Performance
- Human-like delays (800β1500ms randomized)
- Headful browser mode (visible automation)
- Fresh browser context per request
- Graceful error handling
- CAPTCHA detection & auto-stop
### π Safety
- Low volume (50β100 results max)
- Rate-limited scrolling
- 10-minute max runtime
- Respects Google Maps ToS
- No aggressive automation
---
## π Quick Start
### 1. Prerequisites
- Node.js v18+
- npm or yarn
---
### 2. Installation
```bash
git clone https://github.com/Aminemazari/Scrape-Google-Map.git
cd scrape
npm installcp .env.example .envEdit .env:
PORT=3000
API_KEY=your-secure-key-herenpm startServer runs on:
http://localhost:3000
curl http://localhost:3000/healthcurl -X POST http://localhost:3000/scrape \
-H "Content-Type: application/json" \
-H "x-api-key: your-secret-key" \
-d '{"query": "restaurants in New York"}'{
"success": true,
"query": "restaurants in New York",
"totalListings": 42,
"data": [
{
"name": "Best Pizza Place",
"rating": "4.5 stars",
"address": "123 Main St, New York",
"phone": "+1 555-0123",
"website": "https://example.com",
"url": "https://google.com/maps/place/...",
"extractedAt": "2026-03-26T12:00:00.000Z"
}
]
}npm run cli "coffee shops in Barcelona"npm start -- --query "hotels in Paris" --max-results 80
npm start -- -q "gyms" -m 50results/
βββ google_maps_listings.json
βββ google_maps_listings.csv
Edit src/config.js
timing: {
actionDelayMin: 2000,
actionDelayMax: 5000,
scrollDelayMin: 800,
scrollDelayMax: 1500
}limits: {
maxResults: 100,
maxScrolls: 20,
maxRuntimeMinutes: 10
}browser: {
headless: false,
slowMo: 100
}{
"name": "Restaurant Name",
"rating": "4.5 stars",
"address": "123 Main Street",
"phone": "+1 555-0123",
"website": "https://example.com",
"category": "Restaurant",
"extractedAt": "2026-03-26T12:00:00.000Z"
}name,rating,address,phone,website,category,extractedAt
Restaurant Name,4.5 stars,123 Main Street,+1 555-0123,https://example.com,Restaurant,2026-03-26T12:00:00.000Z- Launch Chromium (Playwright)
- Search Google Maps query
- Extract visible listings
- Scroll progressively (lazy load)
- Click listings for extra details
- Remove duplicates
- Export JSON + CSV
- Close browser
- Personal research
- Educational use
- Manual/low-volume scraping
- Bulk scraping entire regions
- Data resale
- High-frequency automation
- Violating Google Maps ToS
- Max 100 results per run
- Max 10 minutes runtime
- CAPTCHA detection stops scraper
- Random delays to reduce load
scrape/
βββ src/
β βββ server.js
β βββ scraper.js
β βββ index.js
β βββ config.js
β βββ exporter.js
β βββ utils.js
βββ results/
βββ .env.example
βββ package.json
βββ README.md
Required header:
x-api-key: YOUR_API_KEY
Generate key:
openssl rand -hex 32- Playwright
- Express.js
- Node.js core modules
MIT License Β© 2026 Lacos
This tool is for educational and personal research purposes only. Users are responsible for complying with applicable terms of service and laws.