Google Maps Scraper + Email & Social Extractor avatar

Google Maps Scraper + Email & Social Extractor

Pricing

from $1.50 / 1,000 scraped results

Go to Apify Store
Google Maps Scraper + Email & Social Extractor

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

Eonix Pvt Ltd

Maintained by Community

Actor 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:

GroupFields
Identityname, category, categories, placeId, cid, googleMapsUrl, imageUrl
Locationaddress, street, city, state, postalCode, countryCode, neighborhood, lat, lng, plusCode, timezone
Businessphone, phoneUnformatted, website, domain, rating, reviewsCount, priceLevel, openingHours, claimed
Contacts from websiteemails, genericEmails (info@, office@…), personalEmails (e.g. jane.doe@…), phones, facebook, instagram, linkedin, twitter, youtube, tiktok, contactPageUrl, websitePagesCrawled, enrichmentStatus
OptionalreviewsDistribution (number of 1★ … 5★ reviews)
Run infosearchQuery, 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:

WhatPriceWhen you pay
Actor start$0.01Once per run
Place scraped$0.0015For each business saved (that's $1.50 per 1,000)
Place enriched$0.005Only 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.

FieldWhat it doesDefault
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 ApifyClient
client = 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)

  1. Add the Apify → Run an Actor module. Actor: yasaslive/google-maps-leads-enricher. Run synchronously: Yes. Input JSON: {"searchQueries": ["{{1.niche}} in {{1.city}}"]}.
  2. Add Apify → Get Dataset Items, with Dataset ID from the previous module (defaultDatasetId).
  3. 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.

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?.