Google Maps Scraper
Pricing
from $3.20 / 1,000 place scrapeds
Google Maps Scraper
Scrapes Google Maps places — business data, reviews, images, contacts. Pay-per-event pricing.
Pricing
from $3.20 / 1,000 place scrapeds
Rating
0.0
(0)
Developer
Ian Emmanuel
Actor stats
1
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Extract business data, reviews, contacts, and images from Google Maps — with pay-per-event pricing and support for 20 languages.
What This Actor Does
The Google Maps Scraper searches Google Maps for businesses, landmarks, and services in any location worldwide. It returns structured place records and supports optional add-ons for reviews, images, contact details, and enriched business data. Results are returned in your chosen language — independent of the scraping location or proxy IP.
Output Fields
Each place record includes the following fields:
| Field | Description |
|---|---|
title | Business name |
address | Full formatted address |
phone | Phone number (E.164 formatted) |
website | Website URL (tracking params stripped) |
category | Google Maps category label |
totalScore | Star rating (1.0 – 5.0) |
reviewsCount | Total number of reviews |
lat / lng | GPS coordinates (7 decimal places) |
openingHours | Opening hours by day |
priceBracket | Price level ($ to $$$$) |
placeId | Unique Google Maps Place ID |
isExternalServicePlace | true for booking-provider injected results |
reviews[] | Array of review objects (when enabled) |
images[] | Array of image objects (when enabled) |
emails[] | Extracted email addresses (when enabled) |
socialUrls[] | Social media profile URLs (when enabled) |
scrapedAt | ISO 8601 timestamp of extraction |
Pricing
This actor uses a pay-per-event model. You are charged only for events that actually fire during your run — no subscriptions, no idle fees, no minimum commitments.
| Event | Rate | Billing Unit | When It Fires |
|---|---|---|---|
| Actor start | $0.0056 | Per run | Every run — infrastructure flat fee |
| Place scraped | $0.0032 | Per place | Every successfully returned place |
| Filter applied | $0.0008 | Per filter × place | When any filter is active (category, rating, website, keyword) |
| Additional place details | $0.0016 | Per place | When enriched details are enabled |
| Contact details scraped | $0.0016 | Per place w/ website | Only places with a website |
| Review scraped | $0.0004 | Per review | Each individual review extracted |
| Image scraped | $0.0004 | Per image | Each image including metadata |
Worked Examples
| Job Type | Configuration | Formula | Cost |
|---|---|---|---|
| Plain directory | 3,500 places, no add-ons | 3,500 × $0.0032 + $0.0056 | $11.21 |
| Filtered search | 1,200 places, 3 filters | 1,200 × $0.0032 + 1,200 × 3 × $0.0008 + $0.0056 | $6.73 |
| Contact leads | 2,000 places, 1,400 with websites | 2,000 × $0.0032 + 1,400 × $0.0016 + $0.0056 | $8.65 |
| Review extraction | 500 places, 60 reviews/place cap | 500 × $0.0032 + 30,000 × $0.0004 + $0.0056 | $13.61 |
| Full enrichment | 400 places, 2 filters, 350 websites, 25 reviews, 8 images | 400×$0.0032 + 800×$0.0008 + 400×$0.0016 + 350×$0.0016 + 10,000×$0.0004 + 3,200×$0.0004 + $0.0056 | $8.41 |
| Direct ID lookup | 5,000 Place IDs | 5,000 × $0.0032 + 5,000 × $0.0016 + $0.0056 | $24.01 |
💡 Multiple categories under the category filter = 1 filter event — no extra charge for category breadth.
💡 Direct Place ID/URL input always triggers Additional place details ($0.0016/place) — minimum base rate is $0.0048/place.
⚠️ SetreviewsPerPlaceLimitandimagesPerPlaceLimitbefore every run — these are the highest-scaling line items.
Input Fields
Search
| Field | Type | Default / Required | Description |
|---|---|---|---|
searchTerms | array | Required (or directPlaceIds) | Keywords to search Google Maps (e.g. "restaurant", "pharmacy"). Each term triggers a full map-scroll pass. |
directPlaceIds | array | Optional | List of Place IDs or Google Maps URLs. Skips the search step and extracts specific places directly. |
Location
| Field | Type | Default / Required | Description |
|---|---|---|---|
location | string | Recommended | City, region, or country name. Resolved via OpenStreetMap. |
country | string | Optional | ISO 3166-1 alpha-2 country code (e.g. "KE", "NG", "ZA"). |
state | string | Optional | State or province name. |
city | string | Optional | City name. |
postalCode | string | Optional | Postal or ZIP code. |
customGeolocation | object | Optional | GeoJSON Polygon, MultiPolygon, or Point with radiusKm. Subdivides the area into tiles and bypasses the 120-place limit. |
Run Control
| Field | Type | Default | Description |
|---|---|---|---|
maxCrawledPlaces | integer | 100 | Hard cap on total places returned. Set before every run to control cost. |
language | string | English | Result language — 20 supported including Mandarin Chinese, Arabic, Hindi, and Swahili. |
Filters
| Field | Type | Default | Description |
|---|---|---|---|
categories | array | Optional | Only keep places matching these category labels. |
minimumStarRating | number | Optional | Exclude places below this rating (1.0 – 5.0). |
requiresWebsite | boolean | false | Only return places with a website URL. Recommended when contact scraping is enabled. |
titleKeyword | string | Optional | Only return places whose name contains this string (case-insensitive). |
Add-ons
| Field | Type | Default | Description |
|---|---|---|---|
scrapeAdditionalDetails | boolean | false | Extract enriched fields: reservations, web results, Q&A, menu URLs, booking links. |
scrapeContacts | boolean | false | Visit each business website to extract emails and social media URLs. Charged $0.0016/place with a website. |
enrichSocialMedia | boolean | false | Categorise discovered social URLs by platform. Requires scrapeContacts. |
scrapeBusinessLeads | boolean | false | Pull LinkedIn profiles for key personnel. Part of Additional place details — $0.0016/place. |
Reviews
| Field | Type | Default | Description |
|---|---|---|---|
scrapeReviews | boolean | false | Extract individual reviews per place. |
reviewsPerPlaceLimit | integer | 50 | Cap on reviews per place. Set conservatively — 200 reviews × 5,000 places = $400 in review charges alone. |
scrapeReviewerData | boolean | false | Include reviewer name, ID, photo, isLocalGuide flag. Separate toggle — enabling reviews does not automatically enable this. |
Images
| Field | Type | Default | Description |
|---|---|---|---|
scrapeImages | boolean | false | Extract gallery images and metadata per place. |
imagesPerPlaceLimit | integer | 10 | Cap on images per place. 50 images × 10,000 places = $200 in image charges alone. |
Other
| Field | Type | Default | Description |
|---|---|---|---|
estimatedPlaces | integer | Optional | Enter your expected place count to log a pre-run cost estimate before scraping begins. |
proxyConfiguration | object | Optional | Apify proxy settings. Residential proxy recommended for production runs. |
debugMode | boolean | false | Enable verbose logging — XHR hits, selector misses, filter rejection reasons. |
Important Notes
⚠️ 120-place limit without geolocation
Without a location, country, city, or customGeolocation, Google Maps renders a single screen and returns at most ~120 results. Provide any geolocation field to get full coverage. The customGeolocation field (GeoJSON polygon) subdivides the area into tiles and bypasses this limit entirely.
⚠️ GeoJSON coordinate order
GeoJSON (RFC 7946) uses [longitude, latitude] order — the opposite of Google Maps display order. Pasting coordinates from Google Maps directly will scrape the wrong area with no error. Use geojson.io to build and visually verify your polygon before running.
⚠️ Direct Place ID billing
Inputting Place IDs or Google Maps URLs directly skips the search step and goes straight to detail extraction. This automatically triggers the Additional place details add-on ($0.0016/place) on every place — the minimum base rate for direct-ID runs is $0.0048/place.
⚠️ Social enrichment dependency
enrichSocialMedia requires scrapeContacts to also be enabled. Without contact scraping, there are no discovered social URLs to enrich and the feature produces no output.
⚠️ Overlapping search terms
Each search term triggers a full independent map-scroll pass. Near-duplicate terms like "restaurant" and "restaurants" re-scrape the same places, inflating run time and cost. Use distinct, non-overlapping terms only, and use category filters to narrow results instead.
ℹ️ External service places
Hotel and accommodation searches may include places sourced from booking providers. These are flagged with isExternalServicePlace: true and may have incomplete fields (phone, address, and hours may be null). Filter them post-run using this field.
ℹ️ Review data and privacy
Reviewer personal data (name, ID, photo, isLocalGuide) is disabled by default for privacy compliance. Only enable scrapeReviewerData when you have a documented lawful basis.
ℹ️ 5,000-review dataset limit
Places with more than 5,000 reviews are split into multiple dataset items sharing the same place fields. Use the Reviews export view (append &view=reviews to the dataset API URL) to get one flat row per review.
Getting Started Example
The following example runs a full-enrichment scrape of cafes in Nairobi with all major add-ons enabled. It is designed to test every billing event type with a minimal place count to keep cost predictable.
{"searchTerms": ["cafe"],"location": "Nairobi, Kenya","country": "KE","city": "Nairobi","maxCrawledPlaces": 5,"language": "English","categories": ["Cafe", "Coffee shop", "Espresso bar", "Bakery"],"minimumStarRating": 1.0,"requiresWebsite": false,"scrapeAdditionalDetails": true,"scrapeContacts": true,"enrichSocialMedia": true,"scrapeReviews": true,"reviewsPerPlaceLimit": 3,"scrapeReviewerData": true,"scrapeImages": true,"imagesPerPlaceLimit": 3,"estimatedPlaces": 5,"debugMode": false}
Expected cost: ~$0.08 – $0.12 depending on how many places have websites.
Each place record will include:
| Field Group | Fields |
|---|---|
| Core | title, address, phone, website, category, totalScore, reviewsCount, lat, lng, openingHours, priceBracket, placeId, scrapedAt |
| Additional details | reservationUrl, orderUrl, menuUrl, qaItems[], webResults[] |
| Contacts | emails[], socialUrls[], socialProfiles{}, phonesFromSite[] |
| Reviews | reviewId, text, stars, publishedDate, ownerResponse, reviewerName, reviewerUrl, isLocalGuide* |
| Images | url, authorName, uploadDate |
*Only included when scrapeReviewerData is enabled.
Built with Node.js 18+ · Crawlee · Playwright · Apify SDK