Scrape Amazon search results with Python: give a keyword (or a filtered Amazon search URL) and get back the ranked product list as JSON, with ASIN, title, price, list price, rating, ratings count, "bought in past month", sponsored flag, Best Seller and Amazon's Choice badges. Works on amazon.com, .co.uk, .de, .fr, .co.jp, .in, .ca, .com.au and the other Amazon marketplaces. Optional product-page details: brand, bullet points, Best Sellers Rank, seller, specs.
This repo is a tutorial and a runnable example for the Amazon Search Scraper actor on Apify. Disclosure: I built this actor; it's a paid tool on Apify ($2.00 per 1,000 products, and Apify's free plan includes $5 of monthly credit).
- No headless browser: plain HTTP + residential proxies in the marketplace's country, so a 50-product search takes seconds.
- Captchas, AWS WAF and bot-manager pages are detected and retried on a fresh IP automatically.
- One flat row per product, sponsored results flagged (
isSponsored,organicPosition) so rank tracking is honest.
pip install apify-clientfrom apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("rel8ble/amazon-search-scraper").call(run_input={
"keywords": ["wireless earbuds"],
"domain": "amazon.com", # or amazon.co.uk, amazon.de, amazon.co.jp ...
"department": "electronics", # optional
"sort": "relevance", # price-asc, price-desc, reviews, newest, bestsellers
"minPrice": 20, "maxPrice": 250, # optional, whole units of the local currency
"maxItemsPerSearch": 50,
"includeSponsored": False, # organic results only
})
for p in client.dataset(run["defaultDatasetId"]).iterate_items():
print(p["organicPosition"], p["asin"], p["price"], p["rating"], p["ratingsCount"], p["title"][:60])Get your token at console.apify.com/settings/integrations.
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('rel8ble/amazon-search-scraper').call({
searchUrls: ['https://www.amazon.de/s?k=kopfh%C3%B6rer&i=electronics&rh=p_36%3A2000-5000'],
maxItemsPerSearch: 30,
includeDetails: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((p) => [p.asin, p.price, p.details?.bestSellersRank]));example.py searches one or more keywords on amazon.com and prints, per keyword:
- how many sponsored slots sit above the first organic result,
- the median price, rating and ratings count of the organic top 20,
- "open niches": products selling 1,000+ a month with fewer than 500 ratings,
and writes every product to amazon_search.csv.
pip install -r requirements.txt
export APIFY_TOKEN=<YOUR_APIFY_TOKEN> # Windows: set APIFY_TOKEN=...
python example.py "standing desk" "desk lamp"A real row from an amazon.com "wireless earbuds" search (8 Oct 2026), trimmed:
{
"position": 3,
"organicPosition": 1,
"asin": "B0FQFB8FMG",
"title": "Apple AirPods Pro 3 Wireless Earbuds with Active Noise Cancellation Live Translation, Heart Rate Sensing, ...",
"brand": "Apple",
"price": 199,
"listPrice": 249,
"currency": "USD",
"offersText": "7+ used & new offers",
"rating": 4.4,
"ratingsCount": 16100,
"boughtLastMonth": 10000,
"boughtLastMonthText": "10K+ bought in past month",
"isSponsored": false,
"isBestSeller": true,
"isAmazonChoice": false,
"url": "https://www.amazon.com/dp/B0FQFB8FMG",
"page": 1
}With includeDetails: true the same product also carries a details object (trimmed):
{
"details": {
"brand": "Apple",
"availability": "In Stock",
"shipsFrom": "Amazon.com",
"bestSellersRank": [{ "rank": 200, "category": "Electronics" }, { "rank": 8, "category": "Sleep Earbuds" }],
"categories": ["Electronics", "Headphones, Earbuds & Accessories", "Headphones & Earbuds"],
"overview": { "Brand": "Apple", "Color": "White", "Ear Placement": "In Ear" },
"modelNumber": "MFHP4LL/A",
"dateFirstAvailable": "September 8, 2025"
}
}| Field | Default | Notes |
|---|---|---|
keywords |
["wireless earbuds"] |
One search per keyword |
searchUrls |
- | Full Amazon search/category URLs with filters already applied (any marketplace) |
domain |
amazon.com |
Marketplace for keywords |
department |
aps (all) |
electronics, beauty, kitchen, stripbooks, ... |
sort |
relevance |
price-asc, price-desc, reviews, newest, bestsellers |
minPrice / maxPrice |
- | Whole units of the local currency |
maxItemsPerSearch |
50 | 1-500 |
includeSponsored |
true | Keep ads (flagged) or drop them |
includeDetails |
false | Opens every product page (slower, same price per result) |
Pay per result: $2.00 per 1,000 products, with or without details. One keyword x 50 products = $0.10; 100 keywords x 100 products = $20. Failed requests are never charged. Residential proxy traffic is billed by Apify separately (about 0.4 MB per search page).
- About 300 products per search: Amazon stops paginating after ~7 pages. Narrow by department or price band to see more.
- Search cards show the default offer only; variations are summarised in
variantsText(details givevariantCount). - Prices are what Amazon shows a visitor in the marketplace's country.
- Sponsored slots rotate on every request; use
scrapedAt+positionfor time series. - Review text is not included (Amazon puts it behind a login); ratings and counts are.
- Actor on the Apify Store: https://apify.com/rel8ble/amazon-search-scraper
- Sister repo, Amazon Best Sellers: https://github.com/Rel8ble/amazon-best-sellers-scraper-python
Collect only public product data and use it in line with Amazon's terms and your local law.
MIT (this example code). The actor itself is a paid service on Apify.