Google Maps Scraper - Places, Contacts & Emails
Pricing
from $1.50 / 1,000 results
Google Maps Scraper - Places, Contacts & Emails
Scrape Google Maps business listings without an API key: name, address, phone, website, rating, reviews, coordinates, categories, hours. Free email + social enrichment and geo-grid tiling to beat the 120-result cap. Export JSON/CSV/Excel.
Pricing
from $1.50 / 1,000 results
Rating
0.0
(0)
Developer
Shahryar
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Google Maps Scraper – Places, Contacts & Emails (No API Key)
This Google Maps scraper extracts structured business listings from Google Maps with no API key required: name, full address, phone, website, rating, reviews, coordinates, categories, price level, and opening hours — straight from a natural-language search query. It then enriches every place with contact emails and social profiles for free. Use it as a keyless Google Maps API alternative and export JSON, CSV, or Excel in one click.
Built for lead generation, local SEO, sales prospecting, and market research.
💡 Pairs perfectly with the Contact Details Scraper — feed in the
websiteURLs from this scraper to dig out even more emails, phones, and social links for end-to-end local lead generation.
Why this scraper
- 💸 Free email + social enrichment – most Google Maps actors charge extra (or sell it as a separate add-on) to turn a listing into a real lead. Here it is included: when a place has a website, the Actor visits it and pulls a contact email plus Facebook / Instagram / LinkedIn / X / YouTube / TikTok links.
- 🧱 Beats the ~120-result cap – a single Google query returns only ~120 places. This Actor subdivides the search area into a geo-grid of overlapping tiles and re-queries each one, so you can collect far more than 120 when you ask for it.
- ⚡ Browserless & fast – it calls Google Maps' internal
tbm=mapsearch endpoint and parses the protobuf-over-JSON response directly. No headless browser, which makes it much cheaper to run than Playwright-based scrapers. - 🔎 Transparent, flat behavior – one input, one output type, no hidden paid tiers for the data you already scraped.
What it does
- 🗺️ Search Google Maps by query – e.g.
"dentists in Austin TX", paginated automatically. - 🏢 Full place details – name, category, address (with city/state/postal split), phone, website, rating, review count (best-effort), latitude/longitude, price level, and opening hours.
- 📧 Email & social enrichment (free) – a secondary fetch of each business website extracts a contact email plus Facebook, Instagram, LinkedIn, X/Twitter, YouTube, and TikTok links.
- 🧩 Geo-grid tiling – automatically expands beyond Google's per-query cap when
maxItemsis large. - 🌍 Locale control – set
language(hl) and an optionalcountryCode(gl). - 📤 Export anywhere – download results as JSON, CSV, or Excel, or pull them via the Apify API.
Example input
{"searchQueries": ["dentists in Austin TX"],"maxItems": 100,"language": "en","countryCode": "us","scrapeEmails": true,"geoGridTiling": true,"maxTiles": 16,"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }}
Example output
{"type": "place","title": "Smile Dental of Austin","categoryName": "Dentist","categories": ["Dentist", "Cosmetic dentist"],"address": "123 Congress Ave, Austin, TX 78701, United States","neighborhood": null,"city": "Austin","state": "TX","countryCode": "US","postalCode": "78701","phone": "(512) 555-0142","website": "https://smiledentalaustin.com","email": "info@smiledentalaustin.com","socials": {"facebook": "https://facebook.com/smiledentalaustin","instagram": "https://instagram.com/smiledentalaustin"},"rating": 4.8,"reviewsCount": 412,"latitude": 30.2685,"longitude": -97.7426,"priceLevel": 2,"hours": [{ "day": "Monday", "hours": "9 AM–5 PM" }],"googleUrl": "https://www.google.com/maps/place/?q=place_id:...&ftid=0x...:0x...","placeId": "ChIJ...","fid": "0x8644b59a...:0x...","language": "en","scrapedAt": "2026-06-26T12:00:00.000Z","facebook": "https://facebook.com/smiledentalaustin","instagram": "https://instagram.com/smiledentalaustin","linkedin": null,"twitter": null,"youtube": null,"tiktok": null}
Output fields
Every item is a single place record (type: "place"). The table below lists every field the scraper emits, cross-checked against the source code. The most-used social links are also flattened to top-level columns (facebook, instagram, linkedin, twitter, youtube, tiktok) so they map cleanly to CSV/Excel cells.
| Field | Type | Description |
|---|---|---|
type | string | Always "place". Lets you filter records if you merge datasets. |
title | string | Business name. |
categoryName | string | null | Primary Google category (first of categories). |
categories | string[] | All Google categories for the place (may be empty). |
address | string | null | Full formatted address as shown on Google Maps. |
neighborhood | string | null | Neighborhood. Currently rarely populated by Google's list response. |
city | string | null | City, parsed from the address. |
state | string | null | State / region code, parsed from the address. |
countryCode | string | null | Two-letter country code. Falls back to your countryCode input when Google omits it. |
postalCode | string | null | Postal / ZIP code, parsed from the address. |
phone | string | null | Phone number (national format, with international +E.164 fallback). |
website | string | null | Business website URL, when Google lists one. |
email | string | null | Contact email scraped from the website (only when scrapeEmails is on and the site exposes one). |
socials | object | Map of social network → profile URL (only networks found). Empty {} when none. |
rating | number | null | Average star rating (0–5), when Google shows it. |
reviewsCount | number | null | Total number of reviews. Best-effort — Google does not return a count for every place, so this can be null even for listings that have reviews (see Notes). |
latitude | number | null | Latitude of the place. |
longitude | number | null | Longitude of the place. |
priceLevel | number | null | Price level 1–4 ($–$$$$), when Google shows it. |
hours | array | null | Opening hours as [{ "day": "Monday", "hours": "9 AM–5 PM" }, …], when shown. |
googleUrl | string | null | Deep link back to the Google Maps place. |
placeId | string | null | Google ChIJ... place ID, when present in the list response. |
fid | string | null | Google feature ID (0x...:0x...), used internally for deduplication. |
language | string | null | The language (hl) code used for the request. |
scrapedAt | string | ISO 8601 timestamp of when the record was scraped. |
facebook | string | null | Facebook profile URL (flattened from socials). |
instagram | string | null | Instagram profile URL (flattened from socials). |
linkedin | string | null | LinkedIn profile URL (flattened from socials). |
twitter | string | null | X / Twitter profile URL (flattened from socials). |
youtube | string | null | YouTube channel URL (flattened from socials). |
tiktok | string | null | TikTok profile URL (flattened from socials). |
Fields Google does not expose for a given place are returned as
null(or[]/{}for arrays/objects) rather than guessed — accuracy over completeness.
Common use cases
- Lead generation – build B2B contact lists (name, phone, website, email, socials) for any niche and city.
- Sales prospecting – target local businesses by category and area, pre-enriched with contact details.
- Local SEO & market research – measure competitor density, ratings, and review volume across a city.
- CRM enrichment – fill website/email/social fields for businesses you already track.
- End-to-end contact pipelines – chain the resulting
websiteURLs into the Contact Details Scraper to harvest even more emails, phones, and socials.
Input reference
| Field | Type | Description |
|---|---|---|
searchQueries | array | Google Maps searches, e.g. "dentists in Austin TX" (required). |
maxItems | integer | Max places in total (0 = no limit). Default 100. |
language | string | UI language code (hl), e.g. en. Default en. |
countryCode | string | Optional country bias (gl), e.g. us, gb, de. |
scrapeEmails | boolean | Visit each website to extract email + socials (free). Default true. |
maxReviews | integer | Optional filter: keep only places with at most this many reviews. |
geoGridTiling | boolean | Subdivide the area into tiles to beat the ~120 cap. Default true. |
maxTiles | integer | Safety cap on grid tiles per query. Default 16. |
proxyConfiguration | object | Proxy settings. Residential required (default). |
Notes & limits (please read)
- Residential proxies are mandatory. Google blocks datacenter IPs almost instantly. Datacenter or no-proxy runs typically see only ~15–30% success. The default proxy is Apify Residential — keep it.
- Google caps a single search at ~120 results. Geo-grid tiling pushes well past that, but it is not magic: very dense areas with thousands of businesses may still return partial coverage, and very large jobs may see some blocked requests. The Actor skips a parse miss or a blocked page and continues rather than crashing.
reviewsCountis best-effort. Google's map-search list response does not include a review count for every place, and it occasionally shifts where the count sits. The scraper reads the canonical position first and falls back to a tightly-scoped scan, but for some listingsreviewsCountwill still benulleven when the place clearly has reviews on the Maps UI. Treat it as a signal, not a guarantee, and do not key billing or hard filters on it being present.email/socialsdepend on the business having a reachable website. Places without a website, or whose site hides contact details, will haveemail: null.- Coordinates are needed to build the search viewport. The Actor geocodes the location part of your query via the keyless OpenStreetMap (Nominatim) service; if that is unavailable it falls back to a coarse country center, which may reduce precision.
- This Actor scrapes only data Google Maps exposes publicly without login. It does not log in, solve CAPTCHAs, or bypass paywalls.
FAQ
Do I need a Google API key? No. This works as a keyless Google Maps API alternative — no Places API key, billing, or login required. You just enter a search query.
How does it get more than 120 results? Google limits one query to ~120 places. With geoGridTiling on and a higher maxItems, the Actor splits the area into a grid of overlapping map tiles and queries each tile separately, then deduplicates by Google feature ID.
Is the email enrichment really free? Yes. When scrapeEmails is on, the Actor fetches each business website and extracts a contact email plus social links at no extra step or tier.
Why is reviewsCount sometimes null? Google's internal map-search response does not include a review count for every place, and occasionally moves it. We read the standard position and fall back to a scoped scan, but a null simply means Google did not return a usable count in that response — it is not an error. The rating may still be present even when the count is missing.
Why might other fields be empty? Google does not show every field for every place (e.g. price level, hours, or neighborhood), and email/socials require a reachable website. Missing fields are returned as null (or [] / {}) rather than guessed.
What export formats are supported? Every run's dataset can be downloaded as JSON, CSV, Excel (XLSX), HTML, RSS, or XML, or pulled programmatically via the Apify API.
Can I scrape a whole city or a single neighborhood? Both. Put the area in your query ("bakeries in Brooklyn NY" for a borough, "plumbers in Texas" for a wider region). Larger areas trigger geo-grid tiling automatically when maxItems is high.
Do I have to use residential proxies? Yes, for reliable results. Google blocks datacenter IPs almost immediately, so the default — and recommended — proxy is Apify Residential.
How do I turn the websites into more contacts? Take the website URLs from this scraper and run them through the Contact Details Scraper for deeper email/phone/social extraction — a clean two-step pipeline for local lead generation.
Why is it cheaper than other Google Maps scrapers? It calls Google's internal JSON search endpoint instead of driving a headless browser, so it uses far less compute per result.