Google Maps Scraper - Places, Contacts & Emails avatar

Google Maps Scraper - Places, Contacts & Emails

Pricing

from $1.50 / 1,000 results

Go to Apify Store
Google Maps Scraper - Places, Contacts & Emails

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

Shahryar

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

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 website URLs 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=map search 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 maxItems is large.
  • 🌍 Locale control – set language (hl) and an optional countryCode (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.

FieldTypeDescription
typestringAlways "place". Lets you filter records if you merge datasets.
titlestringBusiness name.
categoryNamestring | nullPrimary Google category (first of categories).
categoriesstring[]All Google categories for the place (may be empty).
addressstring | nullFull formatted address as shown on Google Maps.
neighborhoodstring | nullNeighborhood. Currently rarely populated by Google's list response.
citystring | nullCity, parsed from the address.
statestring | nullState / region code, parsed from the address.
countryCodestring | nullTwo-letter country code. Falls back to your countryCode input when Google omits it.
postalCodestring | nullPostal / ZIP code, parsed from the address.
phonestring | nullPhone number (national format, with international +E.164 fallback).
websitestring | nullBusiness website URL, when Google lists one.
emailstring | nullContact email scraped from the website (only when scrapeEmails is on and the site exposes one).
socialsobjectMap of social network → profile URL (only networks found). Empty {} when none.
ratingnumber | nullAverage star rating (0–5), when Google shows it.
reviewsCountnumber | nullTotal 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).
latitudenumber | nullLatitude of the place.
longitudenumber | nullLongitude of the place.
priceLevelnumber | nullPrice level 14 ($$$$$), when Google shows it.
hoursarray | nullOpening hours as [{ "day": "Monday", "hours": "9 AM–5 PM" }, …], when shown.
googleUrlstring | nullDeep link back to the Google Maps place.
placeIdstring | nullGoogle ChIJ... place ID, when present in the list response.
fidstring | nullGoogle feature ID (0x...:0x...), used internally for deduplication.
languagestring | nullThe language (hl) code used for the request.
scrapedAtstringISO 8601 timestamp of when the record was scraped.
facebookstring | nullFacebook profile URL (flattened from socials).
instagramstring | nullInstagram profile URL (flattened from socials).
linkedinstring | nullLinkedIn profile URL (flattened from socials).
twitterstring | nullX / Twitter profile URL (flattened from socials).
youtubestring | nullYouTube channel URL (flattened from socials).
tiktokstring | nullTikTok 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 website URLs into the Contact Details Scraper to harvest even more emails, phones, and socials.

Input reference

FieldTypeDescription
searchQueriesarrayGoogle Maps searches, e.g. "dentists in Austin TX" (required).
maxItemsintegerMax places in total (0 = no limit). Default 100.
languagestringUI language code (hl), e.g. en. Default en.
countryCodestringOptional country bias (gl), e.g. us, gb, de.
scrapeEmailsbooleanVisit each website to extract email + socials (free). Default true.
maxReviewsintegerOptional filter: keep only places with at most this many reviews.
geoGridTilingbooleanSubdivide the area into tiles to beat the ~120 cap. Default true.
maxTilesintegerSafety cap on grid tiles per query. Default 16.
proxyConfigurationobjectProxy 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.
  • reviewsCount is 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 listings reviewsCount will still be null even 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/socials depend on the business having a reachable website. Places without a website, or whose site hides contact details, will have email: 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.