Google Maps Email Extractor — Emails, Phones & Socials ($1/1K)
Pricing
from $1.00 / 1,000 business website analyzeds
Google Maps Email Extractor — Emails, Phones & Socials ($1/1K)
Google Maps email extractor and lead generator: get emails, phone numbers, socials (Facebook, Instagram, LinkedIn, WhatsApp) and contact pages from business websites, plus a website audit (dead/parked, HTTPS, SSL, mobile, CMS). $1 per 1,000 sites.
Pricing
from $1.00 / 1,000 business website analyzeds
Rating
0.0
(0)
Developer
Fer
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Google Maps Email Extractor: Leads, Contact Details, Phones, Socials & Website Audit
Google Maps Email Extractor (Google Maps Leads) turns a list of business websites, or the results of our Google Maps scraper, into a ready-to-use lead list. For every business it visits the website and returns emails, phone numbers, social media profiles (Facebook, Instagram, LinkedIn, X/Twitter, TikTok, YouTube, WhatsApp) and the contact page, plus a website health audit: is the site dead or parked, does it use HTTPS, is the SSL certificate valid, is it mobile-friendly, which CMS it runs on (WordPress, Wix, Shopify, Squarespace...) and how fast it responds.
Use it as a Google Maps email extractor, a contact details scraper (emails, phone numbers, socials) or a website audit tool. It is built for lead generation, cold email outreach and web agencies that sell websites: find local businesses on Google Maps, get their contact details, and instantly see which ones have a broken, insecure or outdated website.
Works out of the box for English, Spanish and Portuguese sites (US, Mexico, Latin America, Spain, Brazil), and also understands German and French contact pages (Kontakt, Impressum, Contact, À propos).
What can this Google Maps email extractor do?
- 📧 Find emails from the homepage and the most likely contact pages (Contact, About, Impressum, Contacto, Nosotros, Quiénes somos, Contato, Fale conosco, Kontakt...). Decodes Cloudflare-protected emails (
[email protected]),mailto:links, schema.org/JSON-LD data andinfo (at) domain (dot) comstyle obfuscation. - 🧹 Clean, deduplicated emails: syntax-validated, junk removed (example.com, tracking/error-reporting addresses, image file names like
logo@2x.png, placeholder addresses), and the business's own domain ranked first. - 📞 Phone numbers from
tel:links, structured data and the page text, validated and formatted internationally (+52 33 1527 7234,+1 402 709 7059). - 🔗 Social profiles: Facebook, Instagram, LinkedIn, X/Twitter, TikTok, YouTube and WhatsApp (
wa.melinks, very common for Latin American businesses). Share buttons and website-builder footer links are ignored. - 🩺 Website audit for agencies: reachable or dead, parked/for-sale domains, HTTP status, redirects, HTTPS and SSL errors, mobile viewport, page title and meta description, detected platform/CMS, response time.
- 🗺️ Google Maps integration: enrich a dataset from our Google Maps scraper, paste places directly, or let this Actor run the Google Maps search for you. All place fields (name, placeId, address, phone, categories, rating...) are kept next to the enrichment.
- 💸 Cheap and light: plain HTTP requests (no browser), runs in 256 MB of memory, a handful of requests per website.
How to use it
1. Enrich a list of websites
Paste the websites into Business websites (plain domains like acme-plumbing.com work too) and click Start.
{"startUrls": [{ "url": "https://inlawplumbing.com/" },{ "url": "https://yucatandental.com/" }],"maxPagesPerSite": 5}
2. Enrich results of our Google Maps scraper
Run our Google Maps Scraper, copy the dataset ID of the run and paste it into Google Maps dataset ID. Every place becomes one row, with all its Maps fields kept.
{"datasetId": "YOUR_GOOGLE_MAPS_DATASET_ID","onlyWithEmail": true}
You can also pass places directly in the places field (only website is required), which is handy from the API or from integrations.
3. Search Google Maps and enrich in one run
Fill in Search Google Maps first and Search location. The Actor starts our Google Maps scraper, waits for it, and enriches every place it finds.
{"searchStringsArray": ["dentista", "plomero"],"locationQuery": "Guadalajara, Jalisco","maxPlaces": 50,"mapsLanguage": "es","includePlacesWithoutWebsite": true}
The Google Maps run is a separate run on your account and is billed by the Google Maps scraper.
Input options
| Option | Default | What it does |
|---|---|---|
startUrls / websites | 3 example sites | Websites to enrich. |
datasetId / places | – | Google Maps places to enrich. |
searchStringsArray, locationQuery, maxPlaces, mapsLanguage | – / – / 20 / en | Run the Google Maps search first. |
includePlacesWithoutWebsite | false | Also output places without a website (siteStatus: no_website), great for agencies. |
maxPagesPerSite | 5 | Homepage + up to 4 contact-like pages. Stops early once contact page, email and phone are found. |
maxConcurrency | 30 | Websites crawled in parallel. Automatically lowered when memory is tight, so the default is safe at 256 MB. |
requestTimeoutSecs | 15 | Timeout per page. |
siteTimeoutSecs | 60 | Maximum time spent on one website (all its pages). |
maxRetries | 1 | Retries for the homepage on network errors, 5xx, 429 and 403. |
onlyWithEmail | false | Save only businesses with at least one email. |
skipDeadSites | false | Do not save dead, parked or missing websites. |
includeBlockedSites | false | Save captcha/WAF blocked sites too. By default they are listed in FAILED_SITES and not charged. |
proxyConfiguration | none | Optional. First pass uses this proxy if you set it (off by default). Blocked sites are retried via SHADER → Apify automatic (no groups, FREE datacenter) → none. Residential is never selected automatically. Your input, if set, is used as-is. |
Output example
One row per business. Example from a real run:
{"name": "Yucatan Dental","website": "https://yucatandental.com/","domain": "yucatandental.com","primaryEmail": "info@yucatandental.com","emails": ["info@yucatandental.com", "yucatandental@gmail.com"],"phones": ["+52 999 924 9895"],"facebook": "https://www.facebook.com/yucatandental","instagram": null,"linkedin": null,"twitter": null,"tiktok": null,"youtube": null,"whatsapp": null,"contactPageUrl": "https://yucatandental.com/contact-us/","siteStatus": "ok","reachable": true,"httpStatus": 200,"finalUrl": "https://yucatandental.com/","redirected": false,"redirectedToOtherDomain": false,"https": true,"sslValid": true,"sslError": null,"responseTimeMs": 241,"hasMobileViewport": true,"hasTitle": true,"pageTitle": "Inicio - Yucatan Dental","hasMetaDescription": true,"metaDescription": "Yucatan Dental is a small professional dental practice located in the Centro Historico of Merida, Mexico...","platform": "WordPress (WooCommerce)","language": "en","parkedReason": null,"hasContactForm": true,"pagesCrawled": 2,"error": null,"checkedAt": "2026-10-08T04:20:29.990Z"}
When the input comes from Google Maps, the place fields (title, placeId, address, city, phone, categories, rating, reviewsCount, googleUrl...) are added to the same row. Heavy fields such as reviews and opening hours are left out.
Website status values
siteStatus | Meaning |
|---|---|
ok | Website loads normally. |
dead | Domain does not resolve, refuses connections or times out. |
parked | Parked or for-sale domain, suspended hosting account, registrar landing page or bare server page ("Index of /", "It works!"). See parkedReason. |
blocked | Site is online but refuses automated visits (403/429 or a bot challenge). |
http_error | Homepage returns an error such as 404 or 500. |
social_only | The listed website is a social profile or a WhatsApp chat link (wa.me, wa.link, api.whatsapp.com, chat.whatsapp.com). The link (and the phone, when the URL contains it) is saved; WhatsApp's own page is not crawled. |
directory_listing | The listed website is a profile on a directory, booking or delivery platform (Doctoralia, Yelp, Tripadvisor, Linktree, OpenTable, Booksy, Uber Eats, Rappi, Zocdoc, Healthgrades...). The platform's own phones, emails and social accounts are not returned. |
no_website | Google Maps place without any website (only with includePlacesWithoutWebsite). |
You can download results as CSV, Excel, JSON or XML, or use the Leads overview, Contacts and Website audit views in the Output tab.
Pricing
This Actor uses pay-per-event pricing: $1.00 per 1,000 websites analyzed ($0.001 per business row saved to the dataset), plus a tiny $0.00005 fee per run start.
- You only pay for rows saved to the dataset. Filtered rows (
onlyWithEmail,skipDeadSites), invalid URLs, and captcha/WAF blocked sites (unless you turn onincludeBlockedSites) are free. Dead and parked sites are saved, because they are useful leads for web agencies. - Example: enriching 1,000 Google Maps places costs about $1.00. No proxy, browser or compute costs are added on top.
- The run stops automatically, with a clear status message, when it reaches your maximum number of results or your maximum cost per run.
- Each run saves a
RUN_SUMMARYrecord in the key-value store with counts, email/phone/social hit rates, skipped rows and the stop reason. - When you use Search Google Maps first, the Google Maps scraper run is billed separately by that Actor.
Performance
Designed to run at 256 MB. Pages are fetched over HTTP (no browser), bodies keep the first ~1.35 MB plus the last 150 KB (so footer mailto links are not cut), and parallelism backs off when memory is tight. Shared-host IPs are limited to 2 concurrent requests; SiteGround (detected from host-header / sg-captcha / CNAME / 35.214.0.0/16 and 35.215.0.0/16) is limited to 1 in-flight request so a large run does not trip their volume captcha. Bot-challenge pages (SiteGround 202, Cloudflare, Sucuri) are not charged by default: they go to the FAILED_SITES key-value record and are retried at the end of the run through Apify Proxy (SHADER, then automatic/no-groups for FREE plans, new session per site). A further 45 s concurrency-1 retry runs only when a proxy is actually available. RUN_SUMMARY.retryProxy records which proxy was used and blockedRecovered how many sites came back. primaryEmail is the best guess: same-domain addresses first, then free-provider addresses; legal, privacy, hiring and abuse mailboxes are kept but ranked last. Internal, localhost and private-IP URLs are rejected. Each run writes RUN_SUMMARY even if the run is aborted or is about to time out.
On 1,000 mixed websites at 256 MB (concurrency 30): about 160 s (~6 sites/s), 159 MB peak RSS, 0 OOM. On 50 real dentist and plumber sites: about 6 s, 56% with email, 78% with phone, 74% with a social profile.
Spanish and Latin America support
The crawler recognizes Spanish and Portuguese contact pages (Contacto, Contáctanos, Nosotros, Quiénes somos, Ubicación, Sucursales, Contato, Fale conosco, Quem somos), Spanish obfuscation (hola (arroba) dominio (punto) mx), WhatsApp links, and formats Mexican and other Latin American phone numbers correctly even when the site has no country hints — including pre-2019 Mexican mobiles written as +52 1 …, 044/045 or 01. It also detects platforms common in the region such as Tiendanube, VTEX and Site123.
FAQ
Is it legal to extract emails from websites? The Actor only reads publicly available business websites. Contact details of businesses are generally public, but personal data may be protected by laws such as GDPR or CAN-SPAM. Use the data responsibly and check the rules in your country before sending marketing emails.
Why didn't it find an email for some businesses? Many small businesses publish only a contact form or a phone number. The Actor checks the homepage and the most likely contact pages, but it does not fill in forms, run JavaScript, or guess addresses. In our test on 50 US and Mexican dentists and plumbers, about 56% of businesses had an email on their website.
Does it work with websites built with Wix, Squarespace or other JavaScript-heavy builders? Usually yes: most builders still include contact details in the HTML. Pages that load everything with JavaScript after the page opens may return fewer results.
Some sites show as blocked. Can I still get them?
Those sites returned a bot challenge (SiteGround captcha, Cloudflare 403, …). By default they are not saved and not charged; they are listed in the FAILED_SITES key-value record and retried through Apify Proxy. Turn on includeBlockedSites if you want the empty rows in the dataset anyway.
Can I use it without Google Maps? Yes. Any list of websites works: from a CRM, a directory export or a spreadsheet.
How do I connect it to Google Sheets, Make, Zapier or my CRM? Use the Apify integrations or the API. Example API call:
curl -X POST "https://api.apify.com/v2/acts/datamech~google-maps-email-extractor/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-H "Content-Type: application/json" \-d '{"websites": ["inlawplumbing.com", "yucatandental.com"], "onlyWithEmail": true}'
Do I need a proxy?
No for the first pass on normal lists. Blocked SiteGround/Cloudflare sites are retried automatically through Apify Proxy when the account has datacenter access (SHADER, or automatic mode on the FREE plan). You can also set proxyConfiguration yourself; that value is respected. Residential proxy is never selected unless you choose it.
Feedback
Found a website where an email, phone or social profile was missed or wrong? Open an issue in the Issues tab with the URL, and we will improve the extractor.