How to Scrape Amazon Product Data
Most people who search for a way to scrape Amazon want product titles, prices, availability and rankings. Amazon sells or grants that data through official APIs, and its Conditions of Use restrict collecting it any other way. This guide starts with the programs that exist in late 2026, then shows a tested parser for product pages you are entitled to process, what Amazon's block pages mean, and how to pace and target marketplaces.
Pick the source before the tool
- The Product Advertising API 5.0 has been deprecated and replaced by the Creators API, which requires an Associates account with at least 10 qualifying sales in the past 30 days.
- Sellers and vendors have the Selling Partner API: Catalog Items (version 2022-04-01) for product details and rankings, and Product Pricing (version 2022-05-01, sellers only) for competitive and featured-offer prices.
- Amazon's Conditions of Use, last updated August 14, 2026, exclude collecting product listings, descriptions or prices and using data mining or robots. Read them before collecting from product pages.
- A CAPTCHA page or a 503 from Amazon means stop. The fix is a slower, permitted workflow or an API, not a workaround.
Official APIs
Amazon has two families of product data APIs, and which one you can use depends on your relationship with Amazon.
For sellers and vendors: the Selling Partner API
Brands and merchants who sell on Amazon use the Selling Partner API (SP-API). Two of its sections replace most scraping use cases for them:
- The Catalog Items API, current version 2022-04-01, returns item attributes, browse classifications, dimensions, identifiers, images, sales rankings and relationships, and supports search by identifiers or keywords. It is available to sellers and vendors with the Product Listing role.
- The Product Pricing API, current version 2022-05-01, provides competitive pricing summaries and featured offer expected prices for up to 40 SKUs per batch request, plus notifications such as
ANY_OFFER_CHANGEDwhen prices move. Amazon describes it as the basis for repricers. It is available to sellers only.
If you sell on Amazon and want to watch competitors' prices on your own listings, the Product Pricing API and its notifications do that directly, inside the terms you already signed.
For affiliates: the Creators API
The Product Advertising API 5.0 served affiliates for years. Its documentation URL now redirects to a deprecation notice stating that PA-API 5 "has been deprecated and is being replaced by the Creators API". Old PA-API credentials do not carry over; new ones are created in Associates Central.
The Creators API introduction sets the eligibility: enrollment in the Amazon Associates program for the target marketplace, and at least 10 qualifying sales within the past 30 days. The sales requirement is the catch for new projects: the API is a tool for affiliates who already send buyers to Amazon, not a general data feed. If you are building an affiliate site, it is the route Amazon intends, and it returns structured data that a parser never could.
The Creators API's core operations are:
| Operation | Returns |
|---|---|
| SearchItems | Products matching keywords, filters and browse nodes |
| GetItems | Details for specific products by ASIN or other identifiers |
| GetVariations | All variations of a parent product |
| GetBrowseNodes | Category information and the browse node hierarchy |
Public product pages
Amazon's product pages are public in the sense that anyone can open them in a browser. That is different from permission to collect them. The Conditions of Use, last updated August 14, 2026, grant a limited license to use the site and state that the license does not include "any collection and use of any product listings, descriptions, or prices" or "any use of data mining, robots, or similar data gathering and extraction tools".
That clause is broad, and what it means in a given country is a legal question we cannot answer for you. Our overview of web scraping law covers the main frameworks. Practically, there are cases where processing an Amazon page is clearly fine and cases that need a lawyer:
- Fine: parsing a page a person saved while shopping, checking how your own listing renders, testing an affiliate site's links, archiving a page as evidence for a dispute.
- Ask first: monitoring competitors' prices at any volume, building a product database, feeding pages to a model for training.
For the second group, the APIs above or a licensed data provider are the routes that come with permission. The price monitoring page and our guide to Walmart catalog and price data show how other retailers handle the same need through APIs.
A tested parser
Whatever the source of the HTML (a saved page, a partner feed of rendered pages, your own listing), parsing it well is the same problem: Amazon's markup varies by marketplace, page type and test bucket, so a parser needs a fallback for every field and must report what it could not find rather than guess.
The script below reads a saved product page and extracts the title, the displayed price, the availability text and the rating text. We tested it on October 30, 2026 with Python 3.12, Beautiful Soup 4.15 and lxml 6.1, against a synthetic fixture page built with element IDs commonly seen on product pages. The fixture is ours, not a copy of an Amazon page, and real pages will differ.
"""Parse title, price and availability from a saved product page.
The selectors match the element IDs this fixture uses. Real marketplace markup
varies by region, page type and test bucket, so each field has its own fallback
and a missing field is reported, not guessed.
"""
import json
import re
import sys
from decimal import Decimal
from bs4 import BeautifulSoup
PRICE = re.compile(r"(\d[\d,]*\.\d{2})")
def first_text(soup, *selectors):
for selector in selectors:
node = soup.select_one(selector)
if node and node.get_text(strip=True):
return node.get_text(" ", strip=True)
return None
def parse(html):
soup = BeautifulSoup(html, "lxml")
raw_price = first_text(soup, "#corePrice_feature_div .a-offscreen", "#apex_desktop .a-offscreen", ".a-price .a-offscreen")
match = PRICE.search(raw_price or "")
record = {
"title": first_text(soup, "#productTitle", "h1"),
"price": str(Decimal(match.group(1).replace(",", ""))) if match else None,
"currency_text": raw_price,
"availability": first_text(soup, "#availability span", "#availability"),
"rating_text": first_text(soup, "#averageCustomerReviews .a-icon-alt"),
"ratings_count_text": first_text(soup, "#acrCustomerReviewText"),
}
record["missing"] = [key for key, value in record.items() if value is None]
return record
if __name__ == "__main__":
with open(sys.argv[1], encoding="utf-8") as handle:
print(json.dumps(parse(handle.read()), indent=2))
Run it as python product_parse.py saved-page.html. On the fixture it printed the title, a price of 34.99, the availability In Stock and an empty missing list.
Three details are worth copying into any parser:
- Prices go through
Decimal, neverfloat, so 34.99 stays 34.99. Keep the raw text too, because the currency symbol and format change by marketplace (a German page writes34,99 โฌ, which this simple pattern deliberately does not parse; add a locale-aware rule per marketplace you support). - Every field has an ordered list of selectors. When Amazon changes a layout, one selector fails and the next one often still works.
- The
missinglist turns silent breakage into a number you can alert on. A parser that returns empty strings without complaint corrupts a dataset for weeks before anyone notices.
For Python fundamentals behind this (requests, sessions, retries, Playwright), see our Python web scraping tutorial.
Blocks and CAPTCHAs
Amazon protects its pages against automated traffic, and it says so in the responses it sends. If you test a workflow and meet one of these, the right reaction is to stop and reconsider the source, not to escalate.
Changing addresses, rotating user agents or using solver services to keep a refused job running is exactly what the Conditions of Use exclude, and it tends to fail anyway: Amazon's systems look at far more than the IP. If a legitimate process (an affiliate link checker, a listing QA run) triggers these pages, the cause is usually volume or pattern. Slow it down, cache aggressively, and fetch only pages that changed.
| What you see | What it means | What to do |
|---|---|---|
| A page asking you to type characters from an image | Amazon suspects automated traffic from this client or address | Stop the job. Use an API, or a manual process at human pace |
| HTTP 503 with an apology page | Requests are being refused, often for automated clients | Back off for hours, not seconds; check whether the job is permitted at all |
| A normal page with missing price or "currently unavailable" for many items | Possibly a different page variant, a regional difference or reduced content for suspected bots | Compare with a normal browser session in the same marketplace |
| A redirect to a sign-in page | The content needs an account | Do not automate a logged-in account for collection |
Pacing and marketplace targeting
Two things decide whether a permitted workflow stays healthy: how fast it goes, and whether it asks the right marketplace.
Pace per host
A simple gate that allows one request per interval per host keeps a job predictable and polite. This one is thread-safe and tested:
"""A per-host pacing gate: at most one request every `interval` seconds per host."""
import threading
import time
from urllib.parse import urlsplit
class HostPacer:
def __init__(self, interval: float):
self.interval = interval
self.next_slot: dict[str, float] = {}
self.lock = threading.Lock()
def wait(self, url: str) -> float:
host = urlsplit(url).hostname or ""
with self.lock:
now = time.monotonic()
slot = max(now, self.next_slot.get(host, now))
self.next_slot[host] = slot + self.interval
delay = slot - now
if delay > 0:
time.sleep(delay)
return delay
Call pacer.wait(url) before every request. With an interval of 0.5 seconds, our test printed requests to one host at 0.0, 0.5 and 1.0 seconds while a second host went through immediately. The same discipline applies to API calls: the Creators API and SP-API each document their own request limits per operation, so read them for the operations you use and pace below them.
Target the marketplace you mean
Amazon runs separate marketplaces (amazon.com, amazon.de, amazon.co.uk, amazon.co.jp and more) with different catalogs, prices, currencies and languages. The APIs make this explicit: SP-API operations are served from regional endpoints (North America, Europe, Far East) and take marketplace IDs, and Associates accounts are per marketplace. Always record the marketplace with every price you store.
For checks that must happen in a browser, such as confirming how your listing looks to shoppers in Germany, location matters: Amazon shows delivery options, prices and sometimes content by the visitor's location. A local carrier line in that country shows what a local shopper on mobile sees. Current 24-hour price for a Coronium line in the United States: From $19. In Germany: From $7. Each page shows live stock by carrier. For marketplace work in general, the Amazon proxy page covers the account and session side, and Coronium mobile proxies lists every country.
Sources and review scope
Sources reviewed October 30, 2026. Platform terms, API documentation and prices were checked on that date. Code ran on Python 3.12 against local fixtures that mimic each API, against the quotes.toscrape.com practice site and, for the multi-language examples, through a local authenticated proxy. No platform credentials were used. Terms change; read them before you collect.
- Amazon: PA-API 5 deprecation notice
Checked October 30, 2026.
- Amazon: Creators API introduction
Eligibility and operations, checked October 30, 2026.
- Amazon SP-API: Catalog Items API
Version 2022-04-01, sellers and vendors.
- Amazon SP-API: Product Pricing API
Version 2022-05-01, sellers only.
- Amazon.com Conditions of Use
Last updated August 14, 2026.
Frequently asked questions
Collect data another way
Official APIs first, then tested code, with the terms and limits that apply to each source.
Related workflows
Sessions, accounts and live stock for marketplace work.
Network requirements for permitted price checks.
Requests, HTTPX and Playwright from first request to a polite crawler.
Carriers and live prices in the United States.
Where to get a dedicated line
A Coronium mobile proxy is one physical device with its own SIM, rented to one customer. It connects over HTTP or SOCKS5, the IP changes by dashboard button, API link or timer, and data is not metered on dedicated lines. Brazil lines are the exception: 20 GB of data a month and a new IP on request only, with no timer. Stock and prices differ by country and carrier.