Google Maps Leads & Email Finder (with Website Audit)
Pricing
from $10.00 / 1,000 website enricheds
Google Maps Leads & Email Finder (with Website Audit)
Find local businesses on Google Maps and turn them into outreach-ready leads: emails and social profiles from each website, a website audit (HTTPS, mobile, analytics, booking), and filters for rating, reviews, no-website prospects and more.
Pricing
from $10.00 / 1,000 website enricheds
Rating
0.0
(0)
Developer
OptiRefine
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Turn a Google Maps search into an outreach-ready lead list in one run. This Google Maps scraper finds local businesses ("roofers in Houston, TX"), visits each business's own website to find emails, extra phone numbers and social profiles, audits the website (HTTPS, mobile layout, analytics, online booking, contact form, stale copyright), and keeps only the leads that match your filters — including the classic agency list: businesses with no website at all.
It is built for lead-generation and web-design agencies, local SEO consultants, and anyone who sells to local businesses and needs to know who to contact and what to pitch.
What makes it different
- Emails you can actually use. Addresses come from
mailto:links, visible text, Cloudflare-protected emails and structured data — and the junk every other scraper returns is removed: Wix error-tracking addresses, Squarespace'suser@domain.complaceholder, image filenames likelogo@2x.png, website vendors' addresses stamped on hundreds of sites, and the web designer's credit in the footer. Each email is classified (company domain / freemail / other, role / personal), MX-checked, and ranked, with the best one in theemailcolumn. - A website audit on every lead.
websiteIssueslists what each site is missing — the pitch your agency sells. Every claim is conservative: a site that blocked the crawler gets no "no analytics" finding, and "no contact form" is only claimed after a contact page was actually read. - "No website" prospecting. One setting returns businesses with no website — or only a Facebook/Instagram page, link-in-bio or directory listing.
- Deep coverage. A single Google Maps search stops somewhere between 120 and 260 businesses. Deep mode splits the area into a grid and zooms into dense parts — in a live test for roofers in Houston it found 800 businesses (where it hit the run's cap) versus 244 from a standard search.
- You pay for leads, not for waste. The run asks Google and business websites for only as much as your lead count needs: asking for 10 leads with emails never crawls 100 websites.
How to use it
- What businesses —
searchQueries, the way a customer searches:roofers,dentists,Italian restaurants. - Where —
locations, with state/province/country:Houston, TX,Whitby, ON,Manchester, UK. - How many —
maxLeads. The run stops once that many leads have passed your filters. - Filters (optional) — rating, reviews, website/no website, email required, required social profiles, website issues.
- Start. Export the dataset as CSV, Excel or JSON, or pull it through the Apify API.
Example: cold-email list of established roofers
{"searchQueries": ["roofers"],"locations": ["Houston, TX", "Katy, TX", "Sugar Land, TX"],"maxLeads": 200,"minRating": 4,"minReviews": 20,"emailRequirement": "companyEmail","onePerWebsite": true}
Example: web-design prospects — businesses without a website
{"searchQueries": ["handyman", "house cleaning"],"locations": ["Oshawa, ON"],"maxLeads": 100,"websiteFilter": "withoutWebsite","scrapePlaceDetails": false}
Example: sites that need a rebuild
{"searchQueries": ["dentists"],"locations": ["Dallas, TX"],"maxLeads": 50,"requiredWebsiteIssues": ["NO_MOBILE_VIEWPORT", "NO_HTTPS", "OUTDATED_COPYRIGHT"]}
Input
| Field | Default | What it does |
|---|---|---|
searchQueries | required | Kinds of business to find. |
locations | required | Places to search. Include the state/province/country. |
maxLeads | 100 | Stop after this many leads pass your filters. |
searchMode | standard | deep grids the location and zooms into dense areas to find more businesses. |
maxPlacesPerSearch | 200 | Businesses to examine per query × location, before filters — the main cost control. Raise it when strict filters leave you short. |
enrichWebsites | true | Visit websites for emails, phones, socials and the audit. |
maxPagesPerWebsite | 4 | Homepage plus contact/about/team pages. |
checkEmailMx | true | DNS check that each email domain can receive mail. |
scrapePlaceDetails | true | Review counts, full week of hours, description (one extra Google request per business). |
minRating / minReviews / maxReviews | — | Listing filters. maxReviews finds small or new businesses. |
websiteFilter | any | withWebsite, or withoutWebsite (none, or only a social/directory page). |
skipClosed | true | Skip permanently closed businesses. |
requirePhone | false | Skip listings without a phone. |
includeCategories / excludeCategories | — | Keep/drop by Google category words, e.g. exclude supplier. |
onePerWebsite | false | One lead per website domain — chains list the same site and email on every branch. |
emailRequirement | none | anyEmail, or companyEmail (on the business's own domain, MX-deliverable). |
requiredSocials | — | e.g. ["facebook", "instagram"]. |
requiredWebsiteIssues | — | Keep leads with at least one of these issues (see below). |
proxyConfiguration | Apify residential | For Google. Exits in the US unless you pick a country. |
websiteProxyConfiguration | none | Business websites are fetched directly by default. |
language, countryCode, maxConcurrency | en, —, 20 | Advanced. |
Filters on the Google listing run before a website is visited, so businesses they remove cost nothing to enrich.
What you get
One row per business. The main columns:
| Group | Fields |
|---|---|
| Business | name, primaryCategory, categories, rating, reviewsCount, businessStatus, openingHours, description, googleMapsUrl, placeId, cid |
| Contact | phone (E.164), phoneDisplay, email, emails, emailDetails, websitePhones |
| Social | facebook, instagram, linkedin, twitter, youtube, tiktok, pinterest, yelp |
| Location | address, street, neighborhood, city, state, postalCode, countryCode, latitude, longitude, timeZone |
| Website audit | website, websiteStatus, websiteIssues, websitePlatform, hasHttps, hasValidSsl, hasMobileViewport, hasContactForm, analyticsTools, adPixels, bookingTools, chatTools, copyrightYear, websiteResponseTimeMs |
| Provenance | searchQuery, location, searchMode, searchRank, searchUrl, scrapedAt, pagesCrawled |
Every field, its type and exactly when it is empty: docs/OUTPUT-REFERENCE.md. Console shows four ready-made views of the dataset: Leads, Website audit, Emails, Locations.
Example row
(An illustrative business, showing a subset of the fields — field names and value formats are exact.)
{"name": "Maple Ridge Roofing","primaryCategory": "Roofing contractor","phone": "+17135550142","email": "info@mapleridgeroofing.com","emails": ["info@mapleridgeroofing.com", "mapleridgeroofing@gmail.com"],"emailDetails": [{ "email": "info@mapleridgeroofing.com", "type": "role", "domainKind": "company", "source": "mailto", "foundOn": ["https://mapleridgeroofing.com/contact"], "hasMxRecord": true },{ "email": "mapleridgeroofing@gmail.com", "type": "personal", "domainKind": "freemail", "source": "text", "foundOn": ["https://mapleridgeroofing.com/"], "hasMxRecord": true }],"rating": 4.8,"reviewsCount": 214,"website": "https://mapleridgeroofing.com/","websiteStatus": "OK","websitePlatform": "WordPress","websiteIssues": ["NO_ANALYTICS", "NO_ONLINE_BOOKING", "OUTDATED_COPYRIGHT"],"hasHttps": true,"hasMobileViewport": true,"facebook": "https://www.facebook.com/mapleridgeroofing","instagram": null,"city": "Houston","state": "Texas","googleMapsUrl": "https://www.google.com/maps?cid=1234567890123456789","searchQuery": "roofers","location": "Houston, TX","searchRank": 7}
Website issues
| Code | Means |
|---|---|
NO_WEBSITE | The listing has no website. |
NO_OWN_WEBSITE | The "website" is a Facebook/Instagram profile, a link-in-bio or a directory listing. |
FREE_SUBDOMAIN | Hosted on a builder's subdomain (acme.wixsite.com, acme.square.site…). |
WEBSITE_UNREACHABLE | Domain doesn't resolve, connection refused, timeout, redirect loop. |
WEBSITE_HTTP_ERROR | The homepage returns an error page. |
PARKED_DOMAIN | A registrar parking or "domain for sale" page. |
NO_HTTPS | The site is served over plain HTTP. |
INVALID_SSL_CERTIFICATE | Expired or mismatched certificate — visitors see a warning. |
NO_MOBILE_VIEWPORT | No mobile viewport tag: the site doesn't scale to phones. |
NO_ANALYTICS | No analytics tag found (Google Analytics, Tag Manager, Clarity, Hotjar, builder analytics…). An ads-only tag doesn't count. |
NO_CONTACT_FORM | A contact page was read and has no form (including JavaScript-embedded ones). |
NO_ONLINE_BOOKING | No booking tool, booking page or "Book now"-style button found. |
OUTDATED_COPYRIGHT | The copyright notice is two or more years old. |
SLOW_HOMEPAGE | The homepage took 5 seconds or more to download. |
A website the crawler couldn't read (bot protection, not HTML) gets no audit findings — the actor never reports something it didn't see.
How many results can I get?
- Standard mode: Google usually stops returning results for one query in one place somewhere between 120 and 260 businesses — and the tail is padded with loosely related businesses (in a live test, only 79 of the 123 businesses returned for
roofers in Whitby, ONhad roofing as their main category). - Deep mode: the location's area is searched as a grid, and cells that are still dense are split into four. Live, for
roofersinHouston, TX: 800 businesses (the run's cap) versus 244 in standard mode — 752 of the 800 with a roofing category — in 52 seconds. - Deep mode searches the area Google frames for the location — the city and its surroundings (Houston's frame includes Katy, Sugar Land and Pasadena). Businesses Google pads in from outside that area are skipped. Use the
citycolumn to narrow further. - Your filters decide the final count. If a run comes back short, the run log and the Run summary say exactly how many businesses each filter removed; raise
maxPlacesPerSearch, add locations, or use deep mode.
Pricing
Pay per event: a small charge per run start, a charge per lead saved to the dataset, and a charge per business website crawled for enrichment — including a website that turns out to be down or blocked, because the request was made and that finding is part of the result. Social profiles and directory pages listed as a "website" are never fetched and never charged. Businesses removed by listing filters (rating, reviews, website presence, category…) are never crawled and cost nothing to enrich. Businesses removed after the crawl (for example "must have an email" when the site has none) were crawled, so the website charge applies to them. The actual prices are shown on the Store page.
Tips to spend less:
- Put your cheapest filters (rating, reviews, no-website) in the listing filters — they run first.
- Turn off
scrapePlaceDetailsif you don't need review counts or full opening hours. - Turn off
enrichWebsitesfor Google Maps data only. - Keep
maxPagesPerWebsiteat 4; more pages rarely find more emails.
FAQ
Why is reviewsCount sometimes empty?
Google randomly serves about half of its responses in a "limited view" without review counts. With scrapePlaceDetails on (the default) the actor re-asks Google up to four times per business until it gets the full response; a handful may still end up without a count. With details off, expect about half the rows to have no review count.
Why didn't it find an email for every business?
Many small businesses publish no email at all — only a phone number and a contact form. On a live run of Dallas dentists, 22 of 40 websites published one. emailRequirement keeps only the ones that do.
Are the emails verified?
They are MX-checked: the email's domain is confirmed to receive mail. That is a DNS check, not a mailbox test — no email is sent and no SMTP probing is done.
Does it collect personal data?
It collects what businesses publish for their customers: listing data from Google Maps and contact details from the business's own website. It reads only what a visitor can read, click or find in structured business data. Data embedded in page scripts — including reviewers' details that some review widgets leak into page code — is deliberately ignored. You are responsible for using the data lawfully (e.g. CAN-SPAM, GDPR, CASL) for your outreach.
Do I need a proxy?
Yes for anything beyond a small test — Google rate-limits a single IP. The default (Apify residential, US exits) is right for almost every run and cheap here: a page of 20 businesses is about 24 KB. Results depend on the searched location, not the proxy's country.
Why are two rows for the same company?
Chains and multi-location businesses have one Google listing per branch, often with the same website and email. Tick onePerWebsite to keep one lead per website domain.
Is this a browser-based scraper?
No. Google Maps results are fetched as JSON over plain HTTP and websites are fetched directly. There is no browser, which keeps runs fast and cheap. The flip side: a website that renders its content only with JavaScript can show fewer emails.
What happens when Google changes something?
Every Google response is classified as results, end of results, blocked, or unrecognised — never silently treated as "no results". Blocked requests retry on a new IP. If Google changes its request format, the actor reads the new format from Google's own page and switches automatically; if the data layout itself changes, the run log says so loudly.
This is an independent tool built on publicly accessible Google Maps pages and businesses' own public websites. It is not affiliated with, endorsed by, or sponsored by Google LLC. "Google Maps" is a trademark of Google LLC.