Use Google Maps Review & Contributor Activity Scraper with Python
Get reviews for any Google Maps business or place, or switch to author mode to pull everything one Google reviewer has written. Includes ratings, review text, dates, likes, and owner replies.
1. Choose the data you need
Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.
2. Prepare a source-based input
This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.
{
"maxReviews": 5,
"mode": "place",
"placeUrls": [
"https://www.google.com/maps/place/Eiffel+Tower/@48.8583701,2.2944813,17z/data=!3m1!4b1!4m6!3m5!1s0x47e66e2964e34e2d:0x8ddca9ee380ef7e0!8m2!3d48.8583701!4d2.2944813!16zL20vMDJqODE"
]
}
Download input.example.json and save your reviewed copy as input.json.
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | optional | Reviews of places you list, reviews of places found by a search, or everything specific Google reviewers have published. |
placeUrls | array | optional | Google Maps place links or IDs, one per line. Accepted: place links (also shared maps.app.goo.gl, goo.gl, g.page and share.google links, ?cid= links and review links), Place IDs starting with ChIJ, feature IDs like 0x89c259ab3c1ef289:0x3b67a41175949f55 and numeric CIDs. Used when collecting reviews of specific places. |
searchQueries | array | optional | Google Maps searches such as "dentists in Austin, TX" or "ramen Shibuya Tokyo". Include a city or area in each search. Used when finding places by search. |
maxPlacesPerQuery | integer | optional | How many places to take from each search. One Google search lists about 120 to 360 places; when you ask for more, the actor also searches sub-areas of the same region to reach them. |
contributorUrls | array | optional | Google Maps reviewer profile links (for example https://www.google.com/maps/contrib/108763873723673205857, or a shared maps.app.goo.gl profile link) or numeric reviewer IDs. Used when collecting everything specific reviewers have written. |
maxReviews | integer | optional | Upper limit of reviews collected for each place, or for each reviewer. Google publishes up to 200 contributions per reviewer. |
sortBy | string | optional | Order of a place's reviews. Newest first and most relevant reach a place's complete review history; Google lists at most 188 reviews per star level in rating order. |
language | string | optional | Language of Google Maps labels such as "2 weeks ago". Reviews written in another language also come with Google's translation into this language. |
reviewsNewerThan | string | optional | Keep reviews dated on or after this day, for example 2026-01-01, or a period such as 30 days. Reviews are then read newest first. |
reviewsOlderThan | string | optional | Keep reviews dated on or before this day. Combine with "Only reviews from" for a date range. |
keyword | string | optional | Words a review must mention, for example "parking" or "long wait". For places this uses Google's own review search, which also matches close word forms. |
starRatings | array | optional | Keep only reviews with these star ratings. Leave empty for all ratings. |
onlyWithText | boolean | optional | Skip star-only reviews that have no written text. |
ownerReplyFilter | string | optional | Keep all reviews, only reviews the business replied to, or only reviews still without a reply. |
onlyWithPhotos | boolean | optional | Keep only reviews that include photos or videos. |
reviewLanguages | array | optional | Keep only reviews written in these languages, as two-letter codes such as en, es, ko. Leave empty for all languages. |
monitoringKey | string | optional | Give scheduled runs the same name, for example my-restaurants. Each run then returns only reviews added or edited since the previous run with that name. |
includePlaceSummary | boolean | optional | Adds one record per place with its rating breakdown by stars, review topics, location, contact details and how many reviews were collected. These records have recordType "place". |
includeContributorSummary | boolean | optional | Adds one record per reviewer with their Local Guide level, points and lifetime contribution counts. These records have recordType "contributor". |
includeReviewerDetails | boolean | optional | Turn off to leave out reviewer names, profile pictures, profile links and reviewer IDs from place reviews. |
enrichReviewerProfiles | boolean | optional | For place reviews, also open each reviewer's public profile to add likes, first-published and edited dates, view counts, owner-reply dates and the reviewer's Local Guide level. Adds one request per reviewer. Reviews by private profiles, or older than a reviewer's 200 most recent contributions, keep the standard fields. |
includePartnerReviews | boolean | optional | Hotels on Google Maps also show reviews from partner sites such as Tripadvisor, Trip.com or Priceline. Turn on to add those reviews as separate records (recordType partnerReview), up to Max reviews per partner site, newest first. Places without partner reviews are not affected. |
includePhotoDetails | boolean | optional | For place reviews with photos or videos, add the width, height and upload date of each one. Adds one request per photo. |
3. Start an Actor run
Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.
Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.
import json
import os
import urllib.request
# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
actor_input = json.load(stream)
token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
"https://api.apify.com/v2/acts/SScmkjFpc4NuTczgt/runs?timeout=120&maxTotalChargeUsd=0.50",
data=json.dumps(actor_input).encode("utf-8"),
headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.
4. Inspect the actual results
Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.
One record per Google Maps review (place and search modes), per reviewer contribution (reviewer mode) or per partner-site review on hotels, with ratings, full text, translations, dates, owner replies, photos and place context. Optional place and reviewer summary records.
Questions before you run
Which inputs are required?
No top-level fields are marked required in the published schema. Conditional requirements can still apply; check the README.
What does this guide verify?
The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.
What if the run request times out?
Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.
Generated from source build JH65XCXfaCu7jh0t2 and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.