Complete Guide: How to Scrape Amazon Using Amazon Product & Price Scraper
Run an Apify Actor from Python and turn Amazon search results into rows: ASIN, price, list price, discount, rating, reviews, Prime and ad flags.

This guide covers how to scrape Amazon search results with Amazon Product & Price Scraper, an Apify Actor published as reventadata/amazon-scraper. You give it keywords and a marketplace; it returns one structured row per product, with the ASIN, title, current price, crossed-out list price, a computed discount percentage, star rating, review count, a Prime flag, a sponsored flag, the thumbnail and a clean /dp/ link.
The use case is price and assortment tracking. A seller watching competitors, an analyst comparing countries, or a developer feeding a price table all need a search result page as rows instead of cards. The Actor covers 9 Amazon marketplaces: amazon.com, amazon.co.uk, amazon.de, amazon.es, amazon.fr, amazon.it, amazon.ca, amazon.co.jp and amazon.in.
You will configure a search, run it through the Apify API from Python, read every output field, and learn which filters run on Amazon's side and which run inside the Actor. You need Python 3.11+ and an Apify account; setup takes about 10 minutes.
All sample rows in this guide come from captures dated 2026-10-22 (amazon.com page 1 for "thinkpad" and amazon.in page 2 for "pressure cooker"), read with the Actor's own parser. They are not from a run started for this post.
TL;DR
In this tutorial, you'll learn to run Amazon Product & Price Scraper from Python and save Amazon search results as structured rows. The steps: install apify-client, export your API token, set searchQueries and country, call client.actor("reventadata/amazon-scraper").call(...), and read the run's dataset. Add sortBy to change Amazon's order, and minPrice, maxPrice, minRating, primeOnly or excludeSponsored to filter rows before they are saved. The outcome is a dataset with 14 fields per product that exports as JSON, CSV, Excel and more. Actor: apify.com/reventadata/amazon-scraper.
Prerequisites and setup
- An Apify account. Apify is the platform the Actor runs on; you can sign up for free.
- Apify Console is the web app where you run Actors, read their logs and browse their datasets.
- An API token, from the Integrations settings page.
- Python 3.11 or newer: the Apify API client for Python requires it.
Install the client:
pip install "apify-client~=3.0"
Keep the token in the environment so it never sits in source code:
export APIFY_API_TOKEN="<your token>"
A run started with a token runs under that token's account, so use the token of the account you want the runs to belong to.
Understanding Amazon Product & Price Scraper
What it does. For each keyword in searchQueries, the Actor builds Amazon's own search URL (/s?k=<keyword>, plus page and the sort parameter s), reads the result cards, and saves one row per product. It reads up to 7 result pages per keyword, stopping earlier when a page is empty or has no next-page link, and pauses one second between pages.
How it works. Each card is parsed for its ASIN, title, prices, rating, review count, Prime line, sponsored label and image. A captcha page is recognised by its text, not its HTTP status, and retried while the run has time left. For marketplaces outside the US and Canada, the Actor fetches pages through a web-unlocking service first: in our recon on 2026-10-17, amazon.de and amazon.es answered requests from US datacenter IPs with a captcha page.
Key capabilities. Nine marketplaces, five sort orders, price and rating filters, Prime and sponsored switches, de-duplication by ASIN.
Limitations. A row holds only what the search card shows: nothing from behind a login, nothing from the product page. The Prime flag depends on what Amazon prints for a logged-out visitor. And 7 pages per keyword is the ceiling.
Step-by-step guide to using Amazon Product & Price Scraper
Step 1: Accessing the Actor
Open the Amazon Product & Price Scraper page on Apify Store. In Apify Console, the same fields are in the Actor's Input tab, and Start runs it. This guide uses the API instead, so every step is a line of code you can repeat.
Step 2: Configuring input parameters
The primary field is searchQueries, a list of keywords searched one by one. country picks the marketplace: US, UK, DE, ES, FR, IT, CA, JP or IN, with prices in USD, GBP, EUR, CAD, JPY or INR. maxItems caps saved rows across all keywords (default 20).
The script below uses the Actor's own example input:
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_API_TOKEN"])
run_input = {
"searchQueries": ["thinkpad"],
"country": "US",
"maxItems": 20,
"sortBy": "relevance",
}
run = client.actor("reventadata/amazon-scraper").call(run_input=run_input)
if run is None or run.status != "SUCCEEDED":
raise SystemExit(f"Run did not succeed (status: {run.status if run else 'unknown'})")
for item in client.dataset(run.default_dataset_id).iterate_items():
print(item["asin"], "|", item["price"], item["currency"], "|", item["rating"], "|", item["title"][:60])
Two more example configurations, described in words:
- Several keywords, one country:
searchQueries: ["thinkpad", "mechanical keyboard"],country: "UK",maxItems: 100. Rows come back in GBP; a product that matches both keywords is saved once. - Same keyword, another country: keep the input and change
countrytoDEto read amazon.de in EUR.
Best practice: keep keywords specific. The Actor requires every word of the keyword to appear in the product title, ignoring case and accents. On the captured "thinkpad" page, 20 of 22 results passed; the two dropped were a "Lenovo 15.6 FHD Essential Laptop" and a sponsored MacBook.
Step 3: Advanced configuration
sortBy is sent to Amazon in the search URL: relevance, price_low_to_high, price_high_to_low, review_rank or newest. Because country and sortBy are enums in the input schema, a wrong value is refused before the run starts ("the caller receives an error and the Actor is not started", input schema docs).
The filters run inside the Actor, after each page is read, and filtered rows are never saved:
| Field | What it keeps |
|---|---|
minPrice, maxPrice |
Rows inside the band, in marketplace currency. Unpriced rows drop when either is set. |
minRating |
Rows rated at least this whole number of stars (1-5). Unrated rows drop. |
primeOnly |
Rows with isPrime true. |
excludeSponsored |
Rows Amazon does not label as sponsored. |
The trade-off is depth versus precision. Because filters do not change which pages Amazon serves, a tight band can leave few rows from the 7 pages a keyword gets. Pair maxPrice with price_low_to_high, or minPrice with price_high_to_low, so the pages you reach start inside your band.
Step 4: Optional enrichment features
There are none to enable. Every row carries the same 14 fields whatever the input, and the Actor opens no product pages.
Step 5: Running the Actor
Run the script. .call() starts the run and waits; with apify-client 3.3.0 it returns the run, or None, and the script exits unless the status is SUCCEEDED. A run goes from RUNNING to SUCCEEDED or FAILED.
The log shows each page's URL, how many cards were parsed and how many were kept, then a summary line with rejections by reason.
Step 6: Examining the results
Here is a real row from the 2026-10-22 amazon.com capture, the third result on the page (scrapedAt, the time the page was read, left out):
{
"asin": "B0HB8D3NQ3",
"title": "Lenovo ThinkPad E16 Gen 3, 16GB DDR5 RAM, 512GB SSD, 500GB External HDD",
"price": 1139.98,
"currency": "USD",
"listPrice": 1749.99,
"discountPercentage": 35,
"rating": 4.6,
"reviewsCount": 343,
"url": "https://www.amazon.com/dp/B0HB8D3NQ3",
"image": "https://m.media-amazon.com/images/I/71GqQ5PQ+hL._AC_UY218_.jpg",
"isPrime": true,
"isSponsored": false,
"country": "US"
}
And a trimmed row from the amazon.in capture:
{
"asin": "B0843YY4QP",
"price": 3292.0,
"currency": "INR",
"listPrice": 4140.0,
"discountPercentage": 20,
"rating": 4.3,
"reviewsCount": 1687,
"isPrime": false,
"country": "IN"
}
Step 7: Downloading and exporting data
In Console, the run's Output tab holds the rows and Export downloads them. Apify datasets export as JSON, CSV, XML, Excel, HTML table, RSS or JSONL (dataset docs). From code, iterate_items() streams the same rows.
Working with the API
The script above is the whole API pattern: ApifyClient(token), client.actor("reventadata/amazon-scraper").call(run_input=...), then client.dataset(run.default_dataset_id).iterate_items().
Authentication. The token is read from APIFY_API_TOKEN; never commit it.
Webhooks. Instead of waiting in a script, attach a webhook for the ACTOR.RUN.SUCCEEDED event. Its payload's resource is "the response of the Get Actor run API endpoint" (webhook actions), which carries defaultDatasetId; your endpoint reads the dataset by that id. Add ACTOR.RUN.FAILED to hear about failures.
Scheduling. Save the input as a task and add a schedule. Schedules use cron expressions (schedules docs).
Error handling. Expect three kinds of failure. An input outside the schema, such as an unknown country, is refused before the run starts. A page that comes back as a captcha is retried while the run has time left. A run that saves zero rows ends FAILED if a page was blocked, could not be read or held no product cards; if pages loaded with product cards but your filters removed them all, it ends SUCCEEDED with an empty dataset and a status message saying so. Either way the log's summary line tells you which filter removed them.
Reading the log from code. When a run fails, client.log(run.id).get() returns its log as text (apify-client 3.3.0), so your script can print the summary line next to the error instead of sending you to Console.
Politeness. The Actor already pauses between pages. Put several keywords in one run's searchQueries rather than starting many runs in parallel for the same marketplace.
Advanced usage patterns
Batch processing. One run takes many keywords. Rows are de-duplicated by ASIN across them, and an ASIN is marked as seen only when its row is kept, so a product rejected under one keyword can still be saved under another. Remember that maxItems is a total across keywords, not per keyword.
Several marketplaces. One run reads one country. To compare a product line across the UK, Germany and France, start one run per country with the same keywords, then join the datasets on asin.
Integrations. Apify connects to workflow tools such as n8n, Make and Zapier (integrations), so a finished run can feed a sheet or a chat channel.
Monitoring. Pair a schedule with an ACTOR.RUN.FAILED webhook. The failed webhook catches runs that saved nothing because a page was blocked or unreadable. A filter that stops matching ends SUCCEEDED with an empty dataset, so check the dataset item count or the run's status message as well.
Scaling. Depth per keyword is fixed at 7 pages, so scale by splitting: more specific keywords, different sort orders, or price bands. For example, thinkpad e16 and thinkpad x1 carbon reach different products than thinkpad alone, and review_rank reaches different ones than relevance.
Cost control. maxItems is the cap to set first: the Actor stops saving once it is reached, and no further pages are fetched.
Understanding your data
Each row has 14 fields:
asin: Amazon's 10-character product id.title: the product name, with the brand joined on when printed separately.price,currency: current price, currency.listPrice: the crossed-out price, ornull; 11 of 22 captured results had one.discountPercentage: computed by the Actor from the two prices, rounded;nullunless the list price is higher. Captured range: 14 to 48 percent.rating: stars out of 5, ornull(2 of 22).reviewsCount: the exact count from Amazon's "N ratings" label; the India card shows "(1.6K)", the row 1,687.url,image:/dp/<ASIN>link, thumbnail.isPrime: true when the card shows a Prime badge or Amazon's "Join Prime to get FREE delivery" line; logged-out pages no longer show the badge. 8 of 22 captured amazon.com results had the line; amazon.in showed none on 2026-10-22. Read it as "labelled Prime on this visit".isSponsored: sponsored label (6 of 22).country,scrapedAt: marketplace, time.
Quality checks: weigh rating by reviewsCount (two captured ThinkPads had 5.0 from 2 and 3 reviews), and check listPrice is above price: on the amazon.in capture, 5 of 48 rows carried a per-unit price ("/100 ml") there.
Troubleshooting guide
- A run saved nothing (status message "0 results for ..."). If it ended FAILED, a page was blocked or unreadable; if it ended SUCCEEDED, the pages loaded and your filters removed every product. Read the log's summary line: it counts rejections as
duplicate,keyword_mismatch,price_bounds,rating_threshold,prime_requiredandsponsored_excluded. A highkeyword_mismatchmeans a keyword word is missing from titles; try fewer words. - Fewer rows than
maxItems. The keyword ran out of pages or your filters dropped the rest. The per-page log lines show parsed versus kept. primeOnlyreturns nothing on amazon.in. No Prime line was seen there; turn it off.- Repeated "Amazon fetch error" warnings. The page came back as a captcha or failed to load, and the Actor retried. If the run ends with fewer rows than you asked for, start it again later.
- Input refused. A
countryorsortByvalue outside the schema's list never starts a run; check the spelling against the lists in Step 2 and Step 3. - Help: use the Actor's Store page.
Best practices
- Start with the example input (one keyword, 20 rows) and read every field before scaling up.
- Use Amazon's sort to choose which products the 7 pages reach; use the Actor's filters to trim them.
- Keep
scrapedAtwhen you stack snapshots, and compare byasin, not by title. - Treat
isPrime: falseas "not labelled", not "not Prime". - One marketplace per run, several keywords per run.
- Set
maxItemsto what you will actually use; it caps the rows saved across all keywords. - When a run fails, read the log's summary line before changing anything: it says which filter removed the rows.
For current pricing and details, see the Store page.
Conclusion and next steps
You now have a repeatable way to scrape Amazon search results from Python: keywords and a marketplace in, rows with prices, list prices, discounts, ratings, review counts and flags out. From here, schedule the search, attach a webhook, or compare one keyword across marketplaces by joining on asin.
Try Amazon Product & Price Scraper yourself and let me know what you build!
About the author: reventadata builds and maintains data-extraction Actors on the Apify Store.
Resources
About the author
- Hi, I’m the engineer behind ReventaData. I build automated web scrapers, reverse-engineer undocumented APIs, and design data pipelines on Apify that turn complex, unstructured websites into clean, reliable feeds. Here on Hashnode, I share practical tutorials on modern web scraping with Python, bypassing aggressive anti-bot protections (Cloudflare, Akamai, PerimeterX), and data pipeline automation, reverse-engineering hidden endpoints, and automating data extraction. Explore our turnkey scrapers: https://apify.com/reventadata
Comments
Join the discussionNo comments yet. Be the first to comment.



