Google Maps Local Leads Scraper — Emails & Phones avatar

Google Maps Local Leads Scraper — Emails & Phones

Pricing

from $20.00 / 1,000 lead extracteds

Go to Apify Store
Google Maps Local Leads Scraper — Emails & Phones

Google Maps Local Leads Scraper — Emails & Phones

Build local business lead lists from Google Maps. Search niche + city, export names, phones, websites, addresses, ratings, reviews, coordinates, and optional website emails/social links for CRM, cold-call, Clay, n8n, or Google Sheets workflows.

Pricing

from $20.00 / 1,000 lead extracteds

Rating

0.0

(0)

Developer

Tugelbay Konabayev

Tugelbay Konabayev

Maintained by Community

Actor stats

1

Bookmarked

27

Total users

4

Monthly active users

8 hours ago

Last modified

Share

Google Maps Scraper API — Local Business Leads & Emails

Build local outreach lists from Google Maps. Search a niche + city such as roofers in Austin TX, dentists in Miami FL, or commercial HVAC contractors in Phoenix, then export business names, phones, websites, ratings, reviews, addresses, coordinates, and optional website emails.

Two modes for lead generation teams:

  • Fast list build — collect Google Maps business data quickly for research, cold-call lists, market maps, and CRM import.
  • Enriched outreach list — visit business websites, find email/social links, MX-check email domains, and add a per-record quality score before you send the list to your email verifier, CRM, Clay/n8n workflow, or Google Sheet.

For implementation notes, examples, and local lead-generation workflows, see the Google Maps Leads Extractor guide on Konabayev.com.

Google Maps Leads — local prospecting with optional email enrichment

Google Maps Leads input and output example Google Maps local business lead dataset preview

Built For Local Lead Generation

Most local lead-gen workflows are not "scrape everything and hope." You usually need a clean list for a concrete campaign:

  • plumbers, roofers, HVAC contractors, dentists, clinics, restaurants, gyms, or agencies in a target city
  • phone-first cold-call lists with addresses and categories
  • website/email enrichment for cold email, CRM cleanup, or Clay/n8n-style automation
  • markets where you need rating, review count, category, and website signals to prioritize who to contact first

This actor is built around that workflow:

  • Search the way prospectors think. Use plain phrases like roofing companies in Dallas TX or med spas in Scottsdale.
  • Keep the first run cheap. Default mode extracts core Maps data without website enrichment so you can validate the niche before spending more.
  • Turn on enrichment only when the list is worth it. Email/social extraction, MX domain checks, Firecrawl fallback, and quality scoring are opt-in controls for higher-intent runs.
  • Export verification-ready records. Use emailVerified, qualityScore, phone, website, and reviewsCount to decide which rows go into ZeroBounce/NeverBounce, Apollo, Clay, HubSpot, Pipedrive, n8n, or Google Sheets.

When To Use This Instead Of A Basic Scraper

NeedBasic Maps scraperThis actor
Build a simple phone listUsually enoughYes
Test a niche/city cheaplyOften possibleDefault mode is built for this
Find emails from business websitesVaries by scraperOptional website crawl
Drop obvious junk email domainsUsually noMX domain check
Recover data from JS-heavy or protected websitesUsually noOptional Firecrawl fallback
Prioritize rows for outreachManual cleanupqualityScore, rating, reviews, phone/website/email flags
Use in API, MCP, n8n, or CRM workflowsDepends on actorPPE dataset rows and stable field names

What You Extract

Core Google Maps fields (always present)

  • name — business name (deduped within the run)
  • category — primary Google category
  • address + parsed city, state, postalCode, country
  • phone — when listed
  • website — when listed
  • rating, reviewsCount — when visible
  • priceLevel$ / $$ / $$$ / $$$$ when visible
  • openingHours — raw text from Google Maps
  • latitude, longitude — from the place URL
  • placeUrl — Google Maps URL
  • searchQuery — which input query found this place
  • extractedAt — ISO 8601 UTC timestamp

Premium fields (Pro only)

  • email — extracted from the business website
  • emailVerifiedtrue only when DNS confirmed the domain accepts mail
  • socialMedia{facebook, instagram, twitter, linkedin, youtube, tiktok} URLs
  • websiteEnrichedtrue if Firecrawl rescue was used (anti-bot-protected sites)
  • websiteTitle, websiteDescription — meta tags from business website
  • openingHoursStructured{monday: {open: "09:00", close: "17:00"}, tuesday: ..., ...}
  • qualityScore — 0.0-1.0 weighted completeness score

Quality Controls

Every record can include a qualityScore from 0.0 to 1.0 so you can filter the list before outreach:

SignalWhy it matters
phone or websiteBasic contactability for cold calls or enrichment
emailVerifiedThe email domain has MX records and can receive mail
rating + reviewsCountUseful for prioritizing businesses by reputation
city, state, postalCode, coordinatesUseful for routing, territory mapping, and dedupe
openingHoursStructuredLets you filter by day/time downstream

Recommended filters:

  • qualityScore >= 0.5 for broad prospecting lists
  • qualityScore >= 0.6 plus phone OR emailVerified for sales outreach
  • send email through a mailbox-level verifier before large cold email sends

Input Examples

Fast niche test (no enrichment)

{
"searchQueries": ["roofers in Austin TX"],
"maxItems": 10
}

Enriched cold outreach list

{
"searchQueries": ["commercial HVAC contractors in Phoenix AZ"],
"maxItems": 100,
"extractEmails": true,
"extractSocialMedia": true,
"verifyEmailMx": true,
"firecrawlFallback": true,
"parseOpeningHours": true,
"includeQualityScore": true,
"solveCaptcha": true
}

Multi-city agency prospecting

{
"searchQueries": [
"plumber in Phoenix AZ",
"plumber in Tucson AZ",
"plumber in Mesa AZ"
],
"maxItems": 50,
"extractEmails": true,
"verifyEmailMx": true
}

Direct place URLs (CRM enrichment)

{
"placeUrls": [
"https://www.google.com/maps/place/Mama+Joe's+Pizza/@40.7,-74.0",
"https://www.google.com/maps/place/Joe's+Coffee/@40.71,-74.01"
],
"extractEmails": true,
"extractSocialMedia": true,
"verifyEmailMx": true
}

Cost-controlled high-volume market map

{
"searchQueries": ["restaurants in Brooklyn NY"],
"maxItems": 200,
"extractEmails": false,
"maxConcurrency": 5,
"includeQualityScore": true
}

Output Example

{
"name": "Mama Joe's Pizza",
"category": "Pizza restaurant",
"address": "123 Main St, Brooklyn, NY 11201, USA",
"city": "Brooklyn",
"state": "NY",
"postalCode": "11201",
"country": "USA",
"phone": "+1 718-555-0142",
"website": "https://mamajoes.com",
"email": "info@mamajoes.com",
"emailVerified": true,
"socialMedia": {
"facebook": "https://facebook.com/mamajoespizza",
"instagram": "https://instagram.com/mamajoespizza"
},
"rating": 4.6,
"reviewsCount": 1247,
"priceLevel": "$$",
"openingHours": "Monday: 11 AM–10 PM; Tuesday: 11 AM–10 PM; ...",
"openingHoursStructured": {
"monday": { "open": "11:00", "close": "22:00" },
"tuesday": { "open": "11:00", "close": "22:00" },
"wednesday": { "open": "11:00", "close": "22:00" },
"thursday": { "open": "11:00", "close": "22:00" },
"friday": { "open": "11:00", "close": "23:00" },
"saturday": { "open": "12:00", "close": "23:00" },
"sunday": { "open": "12:00", "close": "21:00" }
},
"latitude": 40.6892,
"longitude": -74.0445,
"placeUrl": "https://www.google.com/maps/place/...",
"websiteEnriched": false,
"websiteTitle": "Mama Joe's Pizza — Real New York Slices",
"websiteDescription": "Brooklyn's pizza institution since 1978. Order online for delivery.",
"qualityScore": 0.95,
"searchQuery": "pizza in Brooklyn",
"extractedAt": "2026-05-06T12:34:56Z"
}

Pricing — Pay Per Event (effective 2026-05-20)

Premium pricing reflects the higher cost of CAPTCHA solving and Firecrawl enrichment, charged only when those services actually deliver a result.

EventPriceWhen charged
actor-start$0.05Once per run
lead-extracted$0.02Per business pushed to dataset
email-verified$0.05Only when MX verification confirms the email domain accepts mail
website-enriched$0.05Only when Firecrawl recovered fields the basic fetch missed

Realistic run costs

ScenarioCost breakdownTotal
100 leads, no enrichment$0.05 + 100 × $0.02$2.05
100 leads, 60 MX-checked emails$0.05 + 100 × $0.02 + 60 × $0.05$5.05
100 leads, 60 MX-checked + 30 enriched$0.05 + 100 × $0.02 + 60 × $0.05 + 30 × $0.05$6.55

Compared with a DIY Places API workflow, this actor also handles scraping orchestration, retries, website email discovery, dataset output, and API/MCP usage in one Apify run.

Best Use Cases

  1. Local agency prospecting — build plumber, roofer, HVAC, clinic, restaurant, gym, or real-estate-service lists by city.
  2. Cold-call list building — export phone, business name, category, address, rating, and website into a dialer or spreadsheet.
  3. Cold email prep — turn on website email extraction, keep MX-checked domains, then send the list to a mailbox-level verifier before outreach.
  4. CRM enrichment — feed existing Google Maps place URLs through the actor to add phone, website, email, social links, and structured hours.
  5. Clay/n8n/automation workflows — call the actor from Apify API/MCP and pass rows into enrichment, verification, or outreach steps.
  6. Local market mapping — quantify competitor density, average rating, review count, and website coverage by neighborhood.
  7. Recurring local-market monitoring — schedule weekly runs and watch new entrants, closures, or category changes.

Programmatic Usage

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("tugelbay/google-maps-leads").call(run_input={
"searchQueries": ["roofers in Austin TX"],
"maxItems": 50,
"extractEmails": True,
"verifyEmailMx": True,
"firecrawlFallback": True,
})
outreach_rows = [
item for item in client.dataset(run["defaultDatasetId"]).iterate_items()
if (item.get("emailVerified") or item.get("phone")) and item.get("qualityScore", 0) >= 0.6
]
print(f"Got {len(outreach_rows)} outreach-ready rows")

JavaScript / TypeScript

import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "YOUR_TOKEN" });
const run = await client.actor("tugelbay/google-maps-leads").call({
searchQueries: ["commercial HVAC contractors in Phoenix AZ"],
maxItems: 100,
extractEmails: true,
extractSocialMedia: true,
verifyEmailMx: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const outreachRows = items.filter(
(it) => (it.emailVerified || it.phone) && (it.qualityScore ?? 0) >= 0.6,
);
console.log(`${outreachRows.length} outreach-ready rows`);

LangChain tool

from langchain_core.tools import tool
@tool
def find_local_businesses(query: str, n: int = 25) -> list[dict]:
"""Find local businesses with contact info for outreach prep."""
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("tugelbay/google-maps-leads").call(run_input={
"searchQueries": [query],
"maxItems": n,
"extractEmails": True,
"verifyEmailMx": True,
"firecrawlFallback": True,
})
return [
it for it in client.dataset(run["defaultDatasetId"]).iterate_items()
if it.get("qualityScore", 0) >= 0.5
]

MCP (Apify MCP Server, Streamable HTTP)

npx mcpc connect mcp.apify.com
npx mcpc call tugelbay/google-maps-leads --json '{"searchQueries":["roofers in Austin TX"],"maxItems":20}'

FAQ

Q: What happens when Google blocks or slows a run? A: The actor uses conservative default concurrency, accepts common Google consent dialogs, and can retry CAPTCHA challenges through 2Captcha/CapSolver when the required secret keys are configured. For cost-controlled first runs, keep maxItems low and enrichment off until you know the niche has useful listings.

Q: Why MX verification instead of full SMTP probe? A: SMTP probes are unreliable (many mail servers refuse anonymous RCPT-TO checks) and slow. MX verification confirms the domain is set up to receive mail at all, which catches obvious dead or parked domains without slowing every row down. If you need mailbox-level validation, pipe email to a service like NeverBounce, ZeroBounce, or your existing verifier after this run.

Q: When does websiteEnriched get charged? A: Only when the basic httpx fetch returned no email and Firecrawl rescue actually retrieved new data. If both fail or basic fetch worked, no website-enriched event fires.

Q: What if my business doesn't list a website on Google Maps? A: You still get name, phone, address, hours, rating, coordinates. email, socialMedia, and websiteEnriched will be null. The lead is still useful — phone-based outreach.

Q: How many leads can I extract per run? A: 1-500 per query. Across multiple queries, no hard cap. Apify-side limits: 4 GB max memory, 24 hours max runtime. A 500-lead query with full enrichment takes ~30-45 minutes.

Q: Does it work outside the US? A: Yes. Address parsing is best for US ("Street, City, ST ZIP" pattern); international addresses appear in address but city/state/postalCode may be null. All other fields work globally. Set language to your locale's ISO 639-1 code (es, de, ru, ar, etc.).

Q: Can I schedule recurring runs? A: Yes — Apify Schedules. Common patterns: weekly per-city refresh, daily for hot markets, hourly for new-listing detection on a specific category.

Q: What about Google's Terms of Service? A: We extract publicly visible data the same way a human user would. We do not log into Google accounts, do not bypass auth, do not access private/business owner-only fields. Standard public-web-scraping legal posture applies — review your jurisdiction's stance and your specific use case.

Q: Why not just use the Google Places API? A: Three reasons: (1) Places API field tiers cost $5-17 per 1,000 requests for similar fields. (2) No website-email enrichment in the official API at all. (3) You build the orchestration, retries, deduplication, and proxy yourself. With this actor, you get all of it on one PPE invoice.

Troubleshooting

Empty dataset returned

  • Check that searchQueries or placeUrls is set (run will fall back to a demo query and warn).
  • Try a different region — some niches have very few Google Maps listings.
  • Set maxConcurrency: 1 to slow down and avoid being rate-limited.

Low emailVerified rate

  • Many small-business websites use contact forms instead of mailto links — emails simply aren't on the page.
  • Disable verifyEmailMx to keep raw emails (you'll get more results but need to validate downstream).
  • Enable firecrawlFallback if not already — recovers emails from JS-rendered/anti-bot-protected sites.

CAPTCHA logs but no 2captcha solves logged

  • The TWOCAPTCHA_API_KEY env var must be set on the actor (Console → Settings → Environment variables, marked Secret).
  • Check your 2Captcha balance: https://2captcha.com/enterpage
  • CapSolver (CAPSOLVER_API_KEY) acts as fallback if 2Captcha returns no token.

Run took too long

  • Drop maxItems, raise maxConcurrency (cap is 10).
  • Disable extractEmails/extractSocialMedia for the first scoping run, then re-run with enrichment on confirmed targets.

Limitations

  • Email enrichment only works when the business website lists an email. No magic — if a business uses a contact form, the email isn't there.
  • MX verification is necessary but not sufficient. A domain with MX records can still have a non-existent mailbox. For deeper validation, pipe email through NeverBounce / ZeroBounce after this run.
  • Opening-hours parser handles common formats. "Mon-Fri 9-5", "Monday: 9 AM-5 PM", "Open 24 hours", "Closed". Exotic formats (e.g., "Shabbat Closed") fall back to null for that day; the raw text remains in openingHours.
  • CAPTCHA solver is best-effort. ~95% accuracy on standard reCAPTCHA v2. Image-grid challenges occasionally return wrong tokens — those runs hit the proxy fallback path.
  • No reviews extracted. This actor focuses on the place's metadata + contact info. For reviews, use a dedicated reviews scraper.

Changelog

  • 3.0 (2026-05-06) — Premium rebrand. CAPTCHA bypass via 2Captcha + CapSolver, MX-verified emails, Firecrawl fallback for website enrichment, structured opening-hours JSON, per-record quality score, premium PPE pricing scheduled for 2026-05-20.
  • 2.0 (2026-04-24) — Fixed proxy support for browser, retry logic, race condition fix.
  • 1.0 (2026-04-15) — Initial release: Google Maps search + place extraction with optional email/social enrichment.