Use Amazon Review Aggregates & Extended History Scraper with Python
Collect Amazon customer reviews and rating summaries by product URL, ASIN, or keyword across 19 marketplaces, with star-rating and sort filters, reviewer images, and an optional session for deeper review history.
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.
{
"categoryUrls": [],
"country": "amazon.com",
"extendedHistory": true,
"filterKeywords": [],
"includeAggregates": true,
"includeGdprSensitive": false,
"includeImages": true,
"keywords": [],
"maxProductsToDiscover": 10,
"maxReviews": 15,
"mediaReviewsOnly": false,
"mergeMarketplaces": [],
"productUrls": [
"https://www.amazon.com/dp/B09X7MPX8L"
],
"reviewsNewerThan": "",
"sortBy": "helpful",
"verifiedPurchasesOnly": false
}
Download input.example.json and save your reviewed copy as input.json.
| Field | Type | Required | Description |
|---|---|---|---|
productUrls | array | optional | List of Amazon product URLs to scrape reviews from. Supports /dp/, /gp/product/, /gp/aw/d/ and /product/ URL formats across 19+ Amazon domains. A bare 10-character ASIN (e.g. "B09X7MPX8L", no URL) is also accepted -- it is expanded into a full URL using the `country` domain below. Leave empty and use `keywords`/`categoryUrls` instead to discover products automatically. |
keywords | array | optional | Search keywords used to auto-discover products when `productUrls` is empty (e.g. "wireless earbuds"). Fetches Amazon's public `/s?k=` search results page for each keyword and reviews up to `maxProductsToDiscover` resulting products. |
categoryUrls | array | optional | Advanced mode: supply your own Amazon `/s?...` or `/b?node=...` category/search URL(s) directly (used only when `productUrls` is empty). Products are discovered the same way as `keywords`. |
maxProductsToDiscover | integer | optional | Maximum number of products to discover per run from `keywords`/`categoryUrls`. Ignored when `productUrls` is supplied directly. |
extendedHistory | boolean | optional | Merge Amazon's public extended review feed for each ASIN (no login, no cookie): up to 100 reviews per star/sort bucket, and walking every bucket yields 100-850+ unique reviews for popular US products, deduplicated against the product-page sample. Coverage varies by ASIN (some products expose few or no rows) and the feed carries Amazon.com reviews only; when off, only the ~8-13 product-page top reviews are returned. |
mergeMarketplaces | array | optional | Additional Amazon marketplaces whose product page is fetched for the same ASIN and whose reviews are merged (deduplicated by review ID and content). Each marketplace typically adds a handful of locally-written reviews. Empty = only the product's own marketplace. |
includeAggregates | boolean | optional | Emit one additional `amazon_review_aggregate` record per product with the product title, average rating, global ratings count, star histogram (plus derived per-star counts), and "Customers say" AI summary with aspects -- parsed from the same page HTML already fetched. These widgets render server-side even when individual review cards are gated, so this record is available more reliably than the reviews themselves. |
country | string | optional | Amazon country domain to scrape from. URLs from a different domain are honored automatically. |
maxReviews | integer | optional | Hard cap on the number of reviews returned per product AFTER merging and deduplication (1-2000). The product-page sample alone yields ~8-13; the extended review feed can add 100-850+ for popular US products. |
sortBy | string | optional | How to sort the returned reviews: most helpful first, or most recent first. |
filterByStar | string | optional | Keep only reviews with this rating. `positive` keeps 4-5 star reviews; `critical` keeps 1-2 star reviews. Applied to the merged set, so narrow filters can legitimately return few or no rows. |
verifiedPurchasesOnly | boolean | optional | Keep only reviews carrying Amazon's Verified Purchase badge. Applied server-side for the extended feed and client-side for product-page rows. |
filterKeywords | array | optional | Keep only reviews whose title or text contains at least one of these keywords (case-insensitive). Empty = no keyword filter. |
reviewsNewerThan | string | optional | Keep only reviews dated on or after this date (e.g. 2026-01-15 or any ISO date). Reviews whose localized date cannot be parsed are kept. Empty = no date filter. |
mediaReviewsOnly | boolean | optional | Keep only reviews that include at least one reviewer-uploaded image or video. |
includeImages | boolean | optional | Extract images and videos uploaded by reviewers (full-resolution URLs). |
includeGdprSensitive | boolean | optional | Include reviewer names, profile links, and avatars. Set to false for GDPR compliance. |
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/OgPzorRclF6tasDvP/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 collected Amazon customer review — rating, title, body, verified-purchase/Vine flags, helpful-votes count, reviewer location, sentiment hint, images/videos, the pipeline that produced the row (`source`: productPage / extendedHistory / cookieMode), its marketplace, a stable dedup fingerprint, and product/source metadata. One additional `amazon_review_aggregate` record per product carries the product title, average rating, global ratings count, star histogram with derived per-star counts, and Amazon's "Customers say" summary with aspects. Empty / null fields are dropped at push time, so any field documented below may be absent if the source did not populate it. Records may carry `collectionCompleteness: "INLINE_SAMPLE"` when `sourceMode=FULL_PAGE` was requested without a valid `cookieString` and `onAuthRequired=RETURN_PARTIAL` fell back to the cookie-free product-page sample instead of the full paginated set.
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 3eBuV9sO4ltC6gYLd and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.