Google Maps Scraper + Email & Social Extractor
Pricing
from $1.50 / 1,000 scraped results
Google Maps Scraper + Email & Social Extractor
Scrape businesses from Google Maps and get their emails, phones and social profiles from their websites in one run. Includes address, rating, reviews, hours and coordinates. Replaces a Maps scraper plus an email extractor. Pay only per result.
Pricing
from $1.50 / 1,000 scraped results
Rating
0.0
(0)
Developer
Eonix Pvt Ltd
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 minutes ago
Last modified
Categories
Share
Google Maps Scraper with Email Extractor: Business Leads, Phones & Social Profiles
Type a search like "dentist in Austin, TX" and get every business Google Maps shows. Each result includes address, phone, website, rating, review count and opening hours, plus the emails, phone numbers and Facebook / Instagram / LinkedIn / X / YouTube / TikTok profiles found on the business's own website. One Actor and one price, with results ready to download as CSV or Excel.
Replaces two tools: a Google Maps scraper and a separate email extractor. There's no exporting URLs from one tool and importing them into another, and no paying twice.
What can you use it for?
- Agencies & cold outreach: build lists of local businesses in any niche and city, with a verified email or phone for each. Push them to your CRM or outreach tool.
- Local SEO: find unclaimed Google listings (
claimed: false), businesses with weak ratings or few reviews, and competitors' categories, all ready to pitch. - Sales prospecting: filter by rating, review count or price level to find the right-sized customers, then contact them through the channel they actually use.
- Market research: count and map every gym, clinic or café in an area, compare ratings, and track new openings over time.
- AI agents & RAG: clean, flat JSON with consistent field names. You can call it from an AI agent through Apify's MCP server (see below).
- Monitoring: schedule the Actor weekly to catch rating changes, new businesses and updated contact details.
What data do you get?
Every place includes:
| Group | Fields |
|---|---|
| Identity | name, category, categories, placeId, cid, googleMapsUrl, imageUrl |
| Location | address, street, city, state, postalCode, countryCode, neighborhood, lat, lng, plusCode, timezone |
| Business | phone, phoneUnformatted, website, domain, rating, reviewsCount, priceLevel, openingHours, claimed |
| Contacts from website | emails, genericEmails (info@, office@…), personalEmails (e.g. jane.doe@…), phones, facebook, instagram, linkedin, twitter, youtube, tiktok, contactPageUrl, websitePagesCrawled, enrichmentStatus |
| Optional | reviewsDistribution (number of 1★ … 5★ reviews) |
| Run info | searchQuery, rank, scrapedAt |
Sample output
These are the first 3 results of a real run with the default input ("dentist in Austin, TX"), trimmed to the most useful fields:
[{"name": "Dentist in Austin.","category": "Dentist","address": "2110 W Slaughter Ln Ste 190, Austin, TX 78748","city": "Austin","postalCode": "78748","phone": "(209) 315-7212","website": "http://dentistinaustin.health/","rating": 3.4,"reviewsCount": 342,"claimed": true,"googleMapsUrl": "https://www.google.com/maps/search/?api=1&query=Dentist+in+Austin.&query_place_id=ChIJ3yK4QPRMW4YRZX-45mkvQwQ","emails": [],"phones": [],"facebook": null,"contactPageUrl": null,"enrichmentStatus": "website-unreachable"},{"name": "South Austin Dentist","category": "Dentist","address": "3901 S Lamar Blvd Ste 480, Austin, TX 78704","city": "Austin","postalCode": "78704","phone": "(737) 437-3801","website": "http://southaustindentisttx.com/","rating": 4.9,"reviewsCount": 178,"claimed": true,"googleMapsUrl": "https://www.google.com/maps/search/?api=1&query=South+Austin+Dentist&query_place_id=ChIJf5afhV5LW4YRy--94BL_3jg","emails": [],"phones": ["+15124483131"],"facebook": null,"contactPageUrl": null,"enrichmentStatus": "success"},{"name": "Emergency Dentist of Austin","category": "Dentist","address": "1030 Norwood Park Blvd #324, Austin, TX 78753","city": "Austin","postalCode": "78753","phone": "(512) 961-6200","website": "https://emergencydentistofaustin.com/","rating": 4.8,"reviewsCount": 1530,"claimed": true,"googleMapsUrl": "https://www.google.com/maps/search/?api=1&query=Emergency+Dentist+of+Austin&query_place_id=ChIJpXb4FgrJRIYRyRpdhSsCHHk","emails": ["info@emergencydentistofaustin.com"],"genericEmails": ["info@emergencydentistofaustin.com"],"personalEmails": [],"phones": ["+15129616200"],"facebook": null,"contactPageUrl": "https://www.emergencydentistofaustin.com/contact","enrichmentStatus": "success"}]
For that whole 50-place test run: 46 of 50 places came back with at least one contact, 29 with a verified email, 45 with a phone number from the website and 41 with at least one social profile.
Export to CSV / Excel
Open the run's Storage → Dataset tab and choose Export → CSV (or Excel, JSON, XML). The "Leads" view gives you a spreadsheet with these columns:
Name, Category, City, Phone (Maps), Website, Emails, Phones (website), Facebook, Instagram, LinkedIn, Rating, Reviews, Enrichment, Google Maps
That's one row per business, ready for Google Sheets, HubSpot, Lemlist, Instantly or Mailchimp. Lists such as emails become comma-separated cells. The "Places" view shows the Google Maps details with a photo thumbnail.
How much does it cost?
You pay only for results, with no monthly fee. Prices are per event:
| What | Price | When you pay |
|---|---|---|
| Actor start | $0.01 | Once per run |
| Place scraped | $0.0015 | For each business saved (that's $1.50 per 1,000) |
| Place enriched | $0.005 | Only when we found at least one email, phone or social profile on its website |
Worked examples:
- 500 leads with contact enrichment: $0.01 + 500 × $0.0015 + 500 × $0.005 ≈ $3.25 (the maximum, if every website has contacts; you pay less for places where nothing is found).
- 1,000 places, Google Maps data only (enrichment switched off): $0.01 + 1,000 × $0.0015 ≈ $1.51.
- 1,000 places with enrichment, typical 80% hit rate: $0.01 + $1.50 + 800 × $0.005 ≈ $5.51.
Budget control: set Maximum cost per run in the run options. The Actor never goes over it. When the limit is close it stops cleanly, keeps everything collected so far, and marks budgetReached: true in the run's STATS record. Enrichments already started are finished and delivered. Places that can't be fully paid for are delivered without contact data (enrichmentStatus: "skipped-budget"), so you never pay for contacts you didn't get.
Input
The default input works as-is: it searches "dentist in Austin, TX" and returns 50 enriched places.
| Field | What it does | Default |
|---|---|---|
Search queries (searchQueries) | What you'd type into Google Maps, including the place, e.g. plumber in Denver, CO. One per line. | ["dentist in Austin, TX"] |
Google Maps search URLs (startUrls) | Optional. Paste a Maps search URL to scrape exactly the map area you're looking at. | [] |
Max places per search query (maxPlacesPerQuery) | Limit per query (1–500). | 50 |
Max results (total) (maxResults) | Total limit across all queries. Raise it when you add queries. | 50 |
Language (language) | Language of names, categories and hours. | en |
Country (countryCode) | Two-letter code. Leave empty and it's detected from the query ("Austin, TX" → US). | (auto) |
Extract emails, phones & social profiles (enrichContacts) | Visit each business website for contacts. | true |
Max pages per website (maxPagesPerWebsite) | Homepage plus the best contact / about / team / impressum pages (1–20). | 5 |
Email types (emailTypes) | all, or generic-only (info@, office@… for GDPR-sensitive outreach). | all |
Validate email domains (validateEmailMx) | Drop emails whose domain can't receive mail. | true |
Include reviews summary (includeReviewsSummary) | Adds the 1★–5★ breakdown. One extra request per place. | false |
Proxy for Google Maps (proxyConfiguration) | Residential proxies, with the country matched automatically. | Apify Proxy, RESIDENTIAL |
Proxy for business websites (enrichmentProxyConfiguration) | Cheaper datacenter proxy by default. | Apify Proxy (datacenter) |
Max request retries (maxRequestRetries) | Retries for blocked or failed Google requests (websites: max 2). | 4 |
Use it from your tools
Replace <YOUR_APIFY_TOKEN> with your token from Apify Console → Settings → Integrations.
REST API (run and get results in one call)
curl -X POST "https://api.apify.com/v2/acts/yasaslive~google-maps-leads-enricher/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>&format=json" \-H "Content-Type: application/json" \-d '{"searchQueries": ["dentist in Austin, TX"], "maxPlacesPerQuery": 50, "enrichContacts": true}'
Use &format=csv to get a CSV file instead.
Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("yasaslive/google-maps-leads-enricher").call(run_input={"searchQueries": ["dentist in Austin, TX", "orthodontist in Austin, TX"],"maxPlacesPerQuery": 100,"maxResults": 200,})for lead in client.dataset(run["defaultDatasetId"]).iterate_items():print(lead["name"], lead["emails"], lead["phone"])
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('yasaslive/google-maps-leads-enricher').call({searchQueries: ['plumber in Denver, CO'],emailTypes: 'generic-only',});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.filter((lead) => lead.emails.length > 0));
Make (Integromat)
- Add the Apify → Run an Actor module. Actor:
yasaslive/google-maps-leads-enricher. Run synchronously: Yes. Input JSON:{"searchQueries": ["{{1.niche}} in {{1.city}}"]}. - Add Apify → Get Dataset Items, with Dataset ID from the previous module (
defaultDatasetId). - Add Google Sheets → Add a Row (or HubSpot → Create a Contact) and map
name,emails[],phone,website,city.
n8n
Use the official Apify node (Run Actor and get dataset), or an HTTP Request node:
{"parameters": {"method": "POST","url": "https://api.apify.com/v2/acts/yasaslive~google-maps-leads-enricher/run-sync-get-dataset-items","sendQuery": true,"queryParameters": { "parameters": [{ "name": "token", "value": "={{$credentials.apifyToken}}" }] },"sendBody": true,"specifyBody": "json","jsonBody": "={\"searchQueries\": [\"{{$json.niche}} in {{$json.city}}\"], \"maxPlacesPerQuery\": 50}","options": { "timeout": 600000 }},"name": "Google Maps leads","type": "n8n-nodes-base.httpRequest","typeVersion": 4.2}
Each returned item is one lead. Connect it to Google Sheets, Airtable or your CRM node.
AI agents (MCP)
Give Claude, Cursor or any MCP client the ability to find leads. Add this to the client's MCP config:
{"mcpServers": {"google-maps-leads": {"command": "npx","args": ["-y", "@apify/actors-mcp-server", "--actors", "yasaslive/google-maps-leads-enricher"],"env": { "APIFY_TOKEN": "<YOUR_APIFY_TOKEN>" }}}}
Then ask: "Find 30 physiotherapy clinics in Leeds with an email address."
FAQ
How many places can I get per search? Google Maps shows at most about 120 places for one search. To cover a whole city, split it into neighborhoods or nearby towns ("dentist in Round Rock, TX", "dentist in Cedar Park, TX"). Duplicates across queries are removed automatically.
Why didn't some places get an email?
Many businesses only offer a contact form, or show their email as an image or through JavaScript. You still get the phone number and social profiles where available, and you only pay the enrichment fee when something was found. enrichmentStatus tells you why: no-website, no-contacts-found, website-unreachable, blocked or social-only-website.
What's the difference between generic and personal emails?
Generic emails are role addresses like info@, office@ or appointments@. Personal emails are everything else, and may belong to a named person (e.g. maria.delgado@clinic.com). If you contact people in the EU/UK, consider emailTypes: "generic-only".
Are the emails verified? We check that the email's domain accepts mail (MX record) and filter out obvious junk: placeholders, image file names, tracking addresses. We don't send test emails, so run your list through a deliverability checker before a large campaign.
Can I scrape reviews? You can get the review count, the average rating and (optionally) the 1★–5★ breakdown. Individual review texts and reviewer names are deliberately not collected.
Does it work outside the US? Yes. Include the location in your query ("Zahnarzt in Berlin", "café in Lyon, France"). The Google region and proxy country are picked automatically, or you can set Country yourself. Phone numbers are normalized to international format (+49…, +33…).
Limitations
- About 120 places per individual Google Maps search (a Google limit).
- Google Maps place URLs aren't accepted as start URLs; use a search query instead.
- Contacts that a website shows only after running JavaScript, or behind a form, can't be extracted.
- If Google changes its internal format, the run stops with a clear error instead of returning bad data, and we fix it quickly. Report it in the Issues tab.
Is it legal?
This Actor collects publicly available business information: what anyone can see on Google Maps and on the businesses' own public websites. It doesn't log in, bypass paywalls, or collect individual reviews or personal Google account data.
However, you are responsible for how you use the data:
- Respect Google's Terms of Service and the websites' terms.
- Comply with GDPR / UK GDPR (a lawful basis and data minimization; prefer generic emails for EU contacts), CAN-SPAM, CASL and other local marketing laws.
- Honor opt-out requests.
If you're unsure, ask a lawyer before running outreach campaigns. For background, read Apify's article Is web scraping legal?.