Google Maps Business Leads Scraper with Phone
Pricing
from $3.40 / 1,000 results
Google Maps Business Leads Scraper with Phone
Extract local businesses from Google Maps in any city, with phone, website, address, rating, review count, opening hours and coordinates. Filter only businesses with no website.
Pricing
from $3.40 / 1,000 results
Rating
0.0
(0)
Developer
Alex Vega
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
4 hours ago
Last modified
Categories
Features
Share
📍 Google Maps Scraper — Business Leads with Phone & No-Website Filter
Extract local businesses from Google Maps in any city, in any country and get a clean, ready-to-sell table: name, phone, website, address, rating, review count, opening hours and coordinates. No code: type what you are looking for and where.
Every row also flags whether the business has a website — and with one switch you can return only the businesses without one: exact-fit leads for web-design and marketing agencies.
💲 One flat price, everything included: $4.00 per 1,000 leads with phone numbers — the same base price as the category leader, but with everything included: no add-on events, no enrichment upsells, no "from" pricing. The price you see is the price you pay.
✅ From a real run of this Actor (dentists in Mexicali, Baja California): 16 businesses saved in a single run, with ratings, review counts and phone numbers — see the actual rows in Example output below.
💲 Price
Pay per event: $0.004 per business ($4.00 per 1,000 leads) — everything included, no paid add-ons, no surprises.
- Trying it out is cheap: a run with the default
maxResultsof 40 costs about $0.16. - Businesses removed by your filters are NOT charged — you only pay for rows that actually land in your dataset.
- A small run-start event ($0.00005) applies per run.
⚙️ How it works
- Type what and where — e.g. Search term
dentists, LocationMexicali, Baja California(the pre-filled values are a ready-to-run example; replace them with yours). Or paste Google Maps place URLs instartUrlsand skip searching entirely. - Press Run — the scraper collects the businesses, opens each place page and extracts phone, website, rating, hours and coordinates. Watch the log: every business is reported by name.
- Download your leads — results are saved incrementally as JSON, CSV or Excel (or via the Apify API), one row per business, ready for your CRM or outreach.
🎯 Get better results
Search terms decide what you get. A few rules that work:
- Good: distinct trades —
dentists,orthodontists,dental clinics— each term finds its own places. - Weak: near-duplicates —
dentist,dentists,best dentist— Google returns mostly the same places, so you spend time, not coverage. - One city per location string, with state and country
(
Mexicali, Baja California) — ambiguous city names mix in results from other places. - Need more than ~120 businesses? Add more terms or more cities
(
searchTerms×locations) instead of raising a single search.
👥 Who it is for
- Web-design & marketing agencies hunting local clients (start with the "no website" filter)
- B2B sales teams building lead lists by city and trade
- Directories & data projects that need structured local business data
Works anywhere Google Maps does — dentists in Mexicali, taquerías in Guadalajara, coffee shops in Austin, clinics in Madrid, plumbers in Toronto.
⬇️ Input
| Field | Example | What it does |
|---|---|---|
searchTerm | dentists | Business type to search for (pre-filled example) |
location | Mexicali, Baja California | City/region + country (pre-filled example) |
maxResults | 40 | Max businesses per search (1–120 — the real limit of one Google Maps search) |
onlyWithoutWebsite | true | Only businesses with no website |
requirePhone | true | Only businesses with a phone number |
minRating | 4.0 | Only businesses rated at least this (0 = no minimum) |
minReviews | 20 | Only businesses with at least this many reviews |
searchTerms | ["dentists", "orthodontists"] | Several terms in one run (term × location) |
locations | ["Mexicali, Baja California", "San Luis Rio Colorado, Sonora"] | Several locations in one run |
startUrls | ["https://www.google.com/maps/place/..."] | Extract these place pages directly, no search |
language | en | Google Maps UI language (en, es, pt-BR, …) |
concurrency | 3 | Place pages extracted in parallel (1–5) |
categoryFilter | clinic | Only businesses whose Maps category contains this text (v0.10) |
onlyOpenNow | true | Only businesses open at extraction time, best-effort from the hours line (v0.10) |
extractEmailsAndSocials | false | Phase 2, off by default: visit each business's homepage only and extract email + socials (v0.10) |
includeReviews | false | Phase 2, off by default: up to 3 review snippets if already present on the place page (v0.10) |
includeImages | false | Phase 2, off by default: up to 3 image URLs from the place page (v0.10) |
proxyConfiguration | Apify Proxy | Standard Apify proxy settings (see below) |
If searchTerms/locations are provided they take precedence over
the singular fields (fallback is per field: plural first, then the
singular). If you provide only startUrls and leave the search
fields at their example defaults, no search is run — only your
URLs are extracted.
Filters (onlyWithoutWebsite, requirePhone, minRating,
minReviews) are applied after collection, to the businesses
actually extracted. That means your final row count is
maxResults − filtered out — and, as said above, filtered-out
businesses are not pushed and not charged.
Example input
{"searchTerms": ["dentists", "dental clinics"],"locations": ["Mexicali, Baja California", "Guadalajara, Jalisco"],"language": "en","maxResults": 40,"onlyWithoutWebsite": true,"minRating": 4.0}
📊 Output — one row per business
| Field | Type | Notes |
|---|---|---|
name | string | Business name |
category | string | Primary Google Maps category |
rating | number | null | ⭐ Google rating (0–5) |
reviews_count | integer | null | Number of Google reviews |
address | string | 📍 Full address as shown on Maps |
phone | string | 📞 Phone as listed (empty if none) |
website | string | 🌐 Website URL (empty if none) |
has_website | boolean | false = lead with no website |
opening_hours | string | Summary hours line as shown on the place page (e.g. "Open · Closes 10 PM"); empty if not shown |
plus_code | string | Google plus code |
latitude / longitude | number | null | Place coordinates |
google_maps_url | string | Link to the place on Google Maps |
feature_id | string | Google feature ID of the place |
search_term / search_location | string | Which search produced this row (empty for direct URLs) |
is_open_now | boolean | null | Open at extraction time, from the hours summary line (best-effort, English/Spanish); null if unclear |
email | string | ✉️ First contact email found on the business's own homepage — only with extractEmailsAndSocials on; empty otherwise |
socials | object | Social links found on that homepage (instagram, facebook, linkedin, whatsapp, tiktok, x) — same opt-in; {} otherwise |
reviews | array | Up to 3 review snippets — only with includeReviews on and only if already present on the place page; [] otherwise |
images | array | Up to 3 image URLs from the place page — only with includeImages on; [] otherwise |
Downloadable as JSON, CSV or Excel, or consumable via the Apify API.
📋 Example output
Real rows from an actual run of this Actor (dentists in Mexicali, Baja California, Mexico):
| Name | Phone | Rating | Reviews |
|---|---|---|---|
| Simply Dental | +52 686 517 3408 | 5 | 285 |
| Dentista García Mexicali | +52 686 552 8777 | 4.8 | — |
| Edificio Médico Dental Vela | +52 686 553 2523 | 4.8 | — |
Example output row (full JSON)
{"name": "Simply Dental — Dentista en Mexicali","category": "Dentist","rating": 5,"reviews_count": 285,"address": "…Mexicali, Baja California","phone": "+52 686 517 3408","website": "https://dentistalgodones.com/...","has_website": true,"opening_hours": "Open · Closes 6 PM","plus_code": "MJ22+C2 Mexicali","latitude": 32.6510903,"longitude": -115.399963,"google_maps_url": "https://www.google.com/maps/place/…","feature_id": "0x…:0x…","is_open_now": true,"email": "","socials": {},"reviews": [],"images": [],"search_term": "dentists","search_location": "Mexicali, Baja California"}
❓ FAQ / troubleshooting
Why did I get fewer rows than maxResults?
Three honest reasons: Google Maps itself shows only so many results
for one search; some places fail to load and are skipped after a
retry; and your filters remove rows after collection — final
count = collected − filtered out (filtered rows are never charged).
Google showed a captcha / the run stopped early. The run stops cleanly and keeps everything extracted so far. Retry with the RESIDENTIAL group selected in the run's Proxy configuration — residential IPs are far less likely to be blocked (see the proxy section for its cost).
Do you extract email addresses or social profiles?
Yes — as an opt-in since 0.10: turn on extractEmailsAndSocials
and for every business with a website the Actor visits only its
homepage (short per-site timeout, no deep crawling) and extracts
visible contact emails (email, first one found) and social links
(socials). Businesses without a website get empty fields, and so
does any site that cannot be read in time — the run never hangs on
a website. See the v0.10 section below for the time cost.
Are opening hours the full weekly schedule?
No — opening_hours is the summary line exactly as Google Maps
shows it on the place page (e.g. "Open · Closes 10 PM"), not a
structured week table.
How do I pull 2,000 businesses?
Split the work: use several search terms and/or several locations in
one run (searchTerms × locations), or run once per city. A single
search is capped by Google Maps and by the run timeout; for very
large pulls, raise the run timeout in Apify as well.
The first rows appear fast but the run takes a while — is that normal? Yes. Results are saved incrementally as each place is extracted (roughly 20 seconds per business at the default parallelism), so a long run still delivers partial results if it hits a limit. The log reports each business by name as it finishes.
📌 Good to know
- Results are saved incrementally: if a long run hits a limit, the businesses extracted so far stay in the dataset.
- The run has a global time budget tied to the run timeout: if the work cannot fit, the log says so honestly and you get partial results instead of a silent cut.
- Google Maps itself caps how many results a single search shows;
maxResultsis also bounded by the Actor's run timeout — for very large pulls (hundreds per search), raise the run timeout in the run's Run options first — or split the pull into several runs (by search terms and by cities, as in the FAQ above) so each run fits comfortably in its budget.
🌐 Proxy
Every run goes through Apify Proxy by default, using datacenter IPs; that traffic is part of the run's normal platform usage cost and there is nothing extra to configure.
For large runs — or if Google shows a captcha — select the RESIDENTIAL group in the run's Proxy configuration instead. Residential IPs are real household connections and are far less likely to be blocked, but they cost more: roughly $8 per GB of traffic, added to the run's usage cost. That is why residential is an opt-in rescue, never forced on you.
If a proxy configuration cannot be created for a run, the run does not crash: it continues without a proxy and the log carries a warning saying so, so you always know which way your run went out.
🛠️ Support & changelog
Support: reach the author through the Apify profile incredible_expertise (Store page / profile messaging). Bug reports land best with the run's input and a couple of log lines.
🆕 What's new in 0.10
- Honest cap:
maxResultsis now 1–120. One Google Maps search returns ~120 results at most (the leaders document the same limit); 500 used to be accepted and then silently returned ~120. The per-search time budget is now proportional to themaxResultsyou ask for, and the extraction budget stays proportional to the places found, so 120 is actually reachable — for larger pulls, split by terms/locations as in the FAQ. - Phase 2 options — all OFF by default, so the proven core is
untouched:
extractEmailsAndSocials: visits only the homepage of each business website (max ~15 s per site, no crawling) and fillsemailandsocials. Cost: extra seconds for every business with a website; none for the rest.includeImages: up to 3 image URLs from the place page (images). Small extra extraction time per place.includeReviews: up to 3 review snippets (reviews) only if already present on the place page — the Actor deliberately does not open the reviews panel, because that would multiply the per-place time and risk the run; expect this field to often be empty.
- Two cheap filters:
categoryFilter(category contains text) andonlyOpenNow(best-effort, read from the hours summary line already extracted — no extra cost; unclear lines are excluded). Every row also carriesis_open_now(true/false/null). - Price unchanged in 0.10 ($0.005 per business at the time); lowered to $0.004 per business ($4.00 per 1,000) on 2026-11-09.
Example output with phase 2 on
{"name": "Example Dental Clinic","category": "Dentist","phone": "+1 555 010 2030","website": "https://exampledental.com","has_website": true,"is_open_now": true,"email": "contact@exampledental.com","socials": {"instagram": "https://www.instagram.com/exampledental","facebook": "https://www.facebook.com/exampledental"},"reviews": [],"images": ["https://lh3.googleusercontent.com/…"]}
Note the honest reviews: []: with no extra navigation, snippets
are only captured when Google already shows them on the place page.
Changelog
- 0.11.3 — 2026-11-09 — Price lowered to $0.004 per business ($4.00 per 1,000): the same base price as the category leader, with everything still included — no add-on events, no upsells. Same scraper.
- 0.11.2 — 2026-11-06 — Wording: worldwide-first framing in the "Who it is for" section (city examples from several countries); the author's public profile bio and README were rewritten worldwide-first as well. Same scraper, same price.
- 0.11.1 — 2026-11-06 — Emojis added to the listing title and section headings for scannability, in the style of the category leaders. Same scraper, same price.
- 0.11 — 2026-11-06 — Listing refresh: the flat-price promise and a real-run proof block moved to the top, new Get better results search-tips section, clearer store description. Same scraper, same price.
- 0.10.2 — 2026-11-06 — Fix:
reviews_countwas being overwritten by the review-snippets list, so dataset schema validation rejected every item and runs finished with zero results. The count is now kept as its own integer field. - 0.10.1 — 2026-11-06 — Fix: a run could crash when a browser page closed with resource-blocker routes still in flight (the route handler now ignores closed pages, and a failed dataset push no longer stops the run). Same price.
- 0.10 — 2026-11-06 — Honest
maxResultscap of 120 per search with proportional search/extraction budgets; opt-in phase 2 (off by default): emails & socials from business homepages, up to 3 place image URLs, up to 3 review snippets if already on the place page; new cheap filterscategoryFilterandonlyOpenNowplus theis_open_nowfield. Same price. - 0.9 — 2026-11-06 — Added the dataset and output schemas wired into the Actor definition, so results render as a table in the Store listing; same scraper, same price.
- 0.8 — 2026-11-06 — Renamed to Google Maps Business Leads for a clear, global Store listing; same scraper, same price.
- 0.7 — 2026-11-06 — Global Google Maps scraper with phone numbers and the no-website lead filter; optional Apify Proxy (datacenter by default, RESIDENTIAL on demand); a global run time budget so runs finish cleanly with partial results instead of silent cuts; filters for website, phone, rating and reviews (filtered-out businesses are not charged); opening-hours summary line; several search terms × locations in one run, plus direct Google Maps place URLs.
🌎 En español (resumen)
Extrae negocios de Google Maps en cualquier ciudad y país — nombre, teléfono, sitio web, dirección, calificación, reseñas, horario resumido y coordenadas — sin programar: escribes qué buscas y dónde. Cada fila marca si el negocio tiene sitio web, y con un interruptor obtienes solo los que no tienen: clientes ideales para agencias de diseño web y marketing.
Precio: $0.004 por negocio ($4.00 por cada 1,000), todo incluido; los negocios que tus filtros descartan no se cobran. Por defecto la corrida usa el proxy de centro de datos de Apify; el grupo RESIDENTIAL es opcional para corridas grandes o si Google muestra un captcha (cuesta ~$8 per GB de tráfico, por eso nunca es obligatorio).