Google Maps Local Business Leads Scraper
Pricing
from $1.80 / 1,000 business results
Google Maps Local Business Leads Scraper
Scrape local business leads from Google Maps by keyword and location. Export clean, flat, CSV-friendly business data for outreach, SEO, web design sales, competitor research, and local lead generation.
Pricing
from $1.80 / 1,000 business results
Rating
0.0
(0)
Developer
Delowar Munna
Actor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share

Lead-focused Google Maps scraping by keyword + location. Returns a clean, flat, CSV-friendly business row per result — built for outreach, SEO, web design sales, competitor research, and local lead generation.
V1 deliberately avoids website crawling, email extraction, full review scraping, photos, menus, and AI enrichment so the run stays fast and cheap. You only pay for unique business rows that pass your filters and are successfully written to the dataset.
✨ Why this scraper
- Lead-focused — 28 flat fields tuned for cold outreach (phone, website, rating, review count, address parts, lead score, reason tags).
- Pay-Per-Event —
$per saved unique business row. Duplicates, filtered rows, and failed pushes are not charged. - No login, no cookies, no sessions — just keyword + location.
- CSV-friendly output — flat structure, no nested objects, drops cleanly into Sheets/Excel/CRMs.
- Transparent lead score — rule-based (no AI), explained below.
🚀 Quick start — sample inputs
Example 1 — single query
{"searchQueries": [{ "key": "plumbers", "value": "Canberra ACT" }],"maxResults": 100,"country": "AU","language": "en","websiteFilter": "any","phoneRequired": false,"includeOpeningHours": true,"includeCoordinates": true,"includeLeadScore": true,"deduplicateResults": true,"proxyConfiguration": { "useApifyProxy": true }}
Example 2 — multi-query, phone required, only businesses without a website (web-design lead list)
{"searchQueries": [{ "key": "electricians", "value": "Sydney NSW" },{ "key": "dentists", "value": "Melbourne VIC" },{ "key": "cafes", "value": "Brisbane QLD" }],"maxResults": 200,"country": "AU","language": "en","minRating": 4.0,"minReviewCount": 10,"websiteFilter": "missingWebsite","phoneRequired": true,"categoryFilter": "","includeOpeningHours": true,"includeCoordinates": true,"includeLeadScore": true,"deduplicateResults": true,"proxyConfiguration": { "useApifyProxy": true }}
The
searchQueriesfield uses Apify's Key/Value form editor — the Key column is the business keyword (e.g.plumbers), the Value column is the location (e.g.Canberra ACT). Add one row per search.
📦 Output
The dataset has one view: Business leads — a 28-column flat table.

Sample record — Business leads
{"search_keyword": "electricians","search_location": "Sydney NSW","business_name": "Hello Electrical | Electrician Sydney","category": "Electrician","rating": 5,"review_count": 442,"phone": "+61 2 8000 1185","website": "https://www.helloelectrical.com.au/","website_domain": "helloelectrical.com.au","address": "192 Edgeware Rd, Newtown NSW 2042, Australia","street_address": "192 Edgeware Rd","suburb": "","city": "Newtown","state": "NSW","postcode": "2042","country": "Australia","google_maps_url": "https://www.google.com/maps/place/Hello+Electrical+%7C+Electrician+Sydney/","place_id": "0x6b0d57cca361e2b1:0x3828b97e7714dc6d","latitude": -33.9044935,"longitude": 151.1733881,"opening_hours": "Closes 5 pm","is_open_now": true,"has_website": true,"has_phone": true,"lead_quality_score": 100,"lead_quality_label": "Strong","reason_tags": ["has_phone","has_website","high_rating","many_reviews","complete_address","category_found","opening_hours_found","outreach_ready"],"scraped_at": "2026-05-05T05:20:53.092Z"}
Output fields (28)
search_keyword, search_location, business_name, category, rating, review_count, phone, website, website_domain, address, street_address, suburb, city, state, postcode, country, google_maps_url, place_id, latitude, longitude, opening_hours, is_open_now, has_website, has_phone, lead_quality_score, lead_quality_label, reason_tags, scraped_at.
🎯 Lead quality score
Transparent rule-based score (0–100) computed from visible fields — no AI, no external enrichment.
| Signal | Points |
|---|---|
| Has phone | +20 |
| Has website | +20 |
| Rating ≥ 4.3 | +15 |
| Review count ≥ 30 | +15 |
| Has full address | +10 |
| Category found | +10 |
| Opening hours found | +10 |
Labels: Strong (80–100) · Good (60–79) · Moderate (40–59) · Weak (0–39).
Reason tags include outreach_ready when has_phone, business_name, and address are all present — sort by this tag to get a clean call/email list.
💰 Pricing
Pay-Per-Event. The actor charges a single business-result event for each unique, filtered business row that is successfully written to the dataset. The actor honors the user-configured per-run spending cap (Apify eventChargeLimitReached) and stops cleanly when reached.
Not charged:
- Duplicates (de-duplicated by
place_id, listing URL, or name+address). - Rows filtered out by
minRating,minReviewCount,websiteFilter,phoneRequired, orcategoryFilter. - Rows missing a
business_name. - Failed dataset pushes.
- Anything after the per-run spending cap is reached.
📊 Run summary
After each run, a RUN_SUMMARY entry is written to the key-value store:
{"search_queries_total": 3,"successful_queries": 3,"failed_queries": 0,"raw_results_found": 240,"results_saved": 187,"duplicates_removed": 21,"filtered_out": 32,"charged_events": 187,"blocked_requests": 0,"retried_requests": 4,"runtime_seconds": 142,"scraped_at": "2026-05-05T12:00:00.000Z"}
charged_events always equals results_saved.
⚙️ Filters
| Filter | Effect |
|---|---|
minRating | Drop businesses below this star rating (0 disables). |
minReviewCount | Drop businesses with fewer reviews (0 disables). |
websiteFilter | any / hasWebsite / missingWebsite. |
phoneRequired | If true, keep only businesses with a visible phone. |
categoryFilter | Case-insensitive contains match against the business category. |
deduplicateResults | Drop duplicates across queries (recommended ON). |
Filters are applied after extraction and before dataset push or event charge.
🚧 Limitations (V1)
- Cards-only extraction: V1 reads each business row directly from the search results panel and does not click into individual place detail panels. Phone, website, full opening hours, and
place_idonly appear when Google surfaces them on the card itself; otherwise these fields are empty/null. - No website crawling, email extraction, or social link extraction.
- No full review text or sentiment.
- No photos, menus, prices, or popular times.
- No login/cookie/session-based scraping.
- Address parsing into street/suburb/city/state/postcode is best-effort; the full
addressfield is the source of truth. - Per-query hard cap is 500 results; per-run hard cap is 5,000 results.
🛠️ Technical notes
- Stack: Node.js 22 · Apify SDK 3 · Crawlee · Puppeteer.
- Concurrency:
min=1,max=3(conservative to reduce blocking). - Memory: 1 GB min · 2 GB default · 4 GB max.
- Proxy: Apify Proxy enabled by default; custom configs accepted.
- Diagnostics: On the first failed render (no feed, or feed but zero cards), the actor saves the page HTML and URL to the key-value store as
debug-no-feed-html/debug-zero-cards-html.