Ecommerce scraping for Amazon means collecting product-page data such as title, price, availability, seller, and ratings, keyed by ASIN. Amazon's Conditions of Use exclude data mining, robots, and similar extraction tools, so the safe order is an official API or approved feed first, then a small, rate-limited crawl of pages you are allowed to monitor, validated field by field before anything is stored.
The hard part is not downloading one product page. It is keeping product identity and the selected offer stable while layouts, sellers, locations, and page states change. Build the scraper as a measured data pipeline, not as a loop that requests URLs as fast as possible.
This guide targets one job: tracking public Amazon product data for research, catalog matching, and retail price or stock monitoring. Check the applicable terms, robots.txt, and legal requirements before collecting. If you are still choosing the collection stack, start with the ecommerce scraping tool guide. If your target is eBay instead, the eBay scraping workflow adapts the same pipeline around listing IDs, seller state, and item condition.
Is scraping Amazon allowed?
Three separate sources answer this, and they do not agree. This is a summary, not legal advice.
| Source | What it says (as of October 2026) |
|---|---|
| Amazon Conditions of Use | The license excludes data mining, robots, and similar data gathering and extraction tools, and the restriction covers collecting product listings, descriptions, or prices |
| robots.txt | Blocks specific paths such as /dp/shipping/ and /gp/product/product-availability, but does not block /dp/ product pages for User-agent: *. It fully blocks many AI crawlers, including GPTBot, ClaudeBot, and PerplexityBot |
| Official APIs | The Creators API is the supported route for product data for eligible Associates |
A permissive robots.txt is not permission. The Robots Exclusion Protocol (RFC 9309) is a crawler convention, and it does not replace the contract in the Conditions of Use.
I could not load the Conditions of Use page directly when preparing this update, so read the live clause before you scope a project. For commercial price monitoring, the conservative route is an official feed, a licensed data source, or data from your own seller account. Public-page monitoring should stay small, rate-limited, and free of personal data.
Ecommerce scraping workflow for Amazon
A production workflow should separate discovery, fetching, extraction, and validation. That separation lets you reparse a stored response after a selector changes without requesting the page again.
- Define the exact fields and marketplaces you need.
- Build a deduplicated queue keyed by marketplace and ASIN.
- Apply policy, scope, and rate checks before each fetch.
- Fetch one canonical product URL with a bounded timeout.
- Classify the response as a product page, challenge, unavailable item, or error.
- Extract fields into a versioned schema.
- Validate price, currency, availability, and product identity.
- Store the record with its source URL and observation time.
- Schedule the next check according to how quickly that item changes.

Do not combine all of these stages in one callback. If a page fails validation, you should know whether the fetch returned the wrong page, the parser missed a field, or the source showed a legitimate unavailable state.
Choose the data source before the scraper
The best source is the one that grants the access and fields you need with the least ambiguity.
| Source | Best fit | Main tradeoff |
|---|---|---|
| Official API or approved feed | Authorized integrations and stable structured data | Eligibility, quotas, field limits, and usage terms |
| Public product HTML | Research or monitoring of a small, permitted page set | Layouts and page states change |
| Browser-rendered page | Fields that appear only after client-side rendering | More CPU, bandwidth, and session complexity |
| Your own seller export | Inventory, listing, and operational reporting | Limited to data your account can access |
Amazon's Product Advertising API 5.0 is deprecated, and its deprecation notice says calls now return HTTP 403 with an AccessDeniedException. The replacement is the Creators API. Per Amazon's migration guide, it swaps AWS Signature Version 4 for OAuth 2.0 with new credentials, uses lowerCamelCase parameters, requires an x-marketplace header, and offers OffersV2 in place of Offers for price data. Old PA-API keys will not work. Sources disagree on the exact cutoff date (April 30 or May 15, 2026), so check the notice in your Associates account.
If an official program fits your use case, evaluate it before maintaining an HTML parser. Eligibility rules apply, so confirm them in Associates Central.
For HTML collection, review the target marketplace's current rules every time the scope changes. The Robots Exclusion Protocol defines how crawlers retrieve and interpret robots.txt, but robots directives are not a substitute for terms, permission, privacy review, or legal advice.
Define a stable product schema
Start with a schema before choosing selectors. A useful minimum record is:
{
"marketplace": "amazon.example",
"asin": "EXAMPLE123",
"canonical_url": "https://www.amazon.example/dp/EXAMPLE123",
"title": "Example product",
"price": {
"amount": 29.99,
"currency": "USD"
},
"availability": "in_stock",
"seller": "Example seller",
"rating": 4.4,
"review_count": 128,
"observed_at": "2026-06-29T12:00:00Z",
"parser_version": "amazon-product-v1"
}
Use the marketplace plus ASIN as the product identity. Do not use a title or a full tracking URL as the primary key. Titles can change, and several URLs can resolve to the same item.
Keep raw display text separate from normalized values. Store "$29.99" if it helps audits, but also parse it into decimal amount 29.99 and currency USD. Never infer a currency from a symbol alone when the marketplace or locale is unknown.
Treat price as a compound observation. A product page can contain a list price, current offer, coupon, subscription price, used offer, shipping charge, or range. Define which price your dataset represents, and record null rather than silently substituting a different offer.
Discover and canonicalize Amazon product URLs
Keep discovery bounded. Use an approved seed list, a catalog you are authorized to monitor, or identifiers already present in your system. Avoid turning search results, recommendations, and pagination into an unlimited crawler.
Canonicalize each URL before enqueueing it:
- Normalize the marketplace hostname.
- Extract and validate the ASIN.
- Build one canonical
/dp/{ASIN}URL. - Remove affiliate, referral, session, and tracking parameters.
- Deduplicate on marketplace plus ASIN.
- Reject URLs outside the approved hosts and path patterns.
This cuts repeat traffic and prevents query-string variants from creating duplicate products. It also makes retries safe because the queue has one identity for each item.
Fetch static HTML or use a browser?
Begin with one normal HTTP request. If the response contains the required public fields consistently, a client such as Python requests is easier to operate than a browser.
Use Playwright or Puppeteer only when a permitted field genuinely depends on browser rendering. A browser adds JavaScript execution, subresource requests, cookies, storage, and more failure modes. The Playwright proxy guide covers isolated browser contexts when browser rendering is necessary.

The decision rule is simple:
| Observation | Use |
|---|---|
| Required fields exist in the initial HTML | HTTP client |
| HTML is a challenge, consent page, or error | Stop and diagnose; do not parse it as a product |
| Required permitted fields appear only after rendering | Browser |
| An official API exposes the fields | API |
Do not add a browser merely because one selector broke. First save the response, check its status, identify the page type, and compare it with a known-good sample.
Extract fields without brittle selectors
Ecommerce layouts change through experiments, localization, device variants, and seller states. One long CSS selector tied to a specific nesting path will fail quietly.
Use a field adapter with ordered, evidence-based strategies:
import re
from dataclasses import dataclass
from decimal import Decimal, InvalidOperation
from bs4 import BeautifulSoup # pip install beautifulsoup4
@dataclass
class Product:
asin: str
title: str
price: Decimal | None
currency: str | None
availability: str
CURRENCIES = {"$": "USD", "£": "GBP", "€": "EUR"}
def first_text(soup: BeautifulSoup, selectors: list[str]) -> str | None:
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_money(text: str | None) -> tuple[Decimal | None, str | None]:
if not text:
return None, None
match = re.search(r"([$£€])\s?(\d[\d,]*(?:\.\d{1,2})?)", text)
if not match:
return None, None
try:
amount = Decimal(match.group(2).replace(",", ""))
except InvalidOperation:
return None, None
return amount, CURRENCIES[match.group(1)]
def classify_availability(soup: BeautifulSoup) -> str:
text = (first_text(soup, ["#availability", "[data-feature-name='availability']"]) or "").lower()
if "in stock" in text:
return "in_stock"
if "unavailable" in text or "out of stock" in text:
return "out_of_stock"
return "unknown"
def parse_product(html: str, asin: str) -> Product:
soup = BeautifulSoup(html, "html.parser")
title = first_text(soup, ["#productTitle", "[data-feature-name='title']", "h1"])
if not title:
raise ValueError("title not found; page may not be a product page")
price_text = first_text(soup, [
"[data-feature-name='corePrice'] .a-offscreen",
"[data-feature-name='corePrice']",
])
amount, currency = parse_money(price_text)
return Product(
asin=asin,
title=title,
price=amount,
currency=currency,
availability=classify_availability(soup),
)
The selectors are illustrative, not a promise about Amazon's current markup, and I did not test them against live pages. Inspect pages you are permitted to access, keep fixture samples, and version the adapter when the layout changes. The select_one and get_text calls follow the Beautiful Soup documentation.
Prefer semantic containers and structured data over presentation classes when both are available and permitted. Never use regex over the entire HTML to find the first currency-looking string; it may capture a recommendation, coupon, or unrelated offer.
Validate every record
Extraction success does not mean data success. A challenge page can return HTTP 200, and a parser can mistake its heading for a product title.
Apply these checks before accepting a record:
- The canonical page identity matches the queued marketplace and ASIN.
- The title is present and within reasonable length bounds.
- Currency matches the expected marketplace or is explicitly recognized.
- Price parses as a positive decimal when the selected offer is available.
- Availability comes from a known state, not arbitrary page text.
- A challenge, sign-in, consent, or error page is not classified as a product.
- The price change is within a review threshold or gets flagged as an outlier.
- The record includes observation time and parser version.
Track field completeness separately from request success. A run with 99% HTTP 200 responses and 40% missing prices is a failed data run.
Store a small, access-controlled sample of source responses for parser tests if your policy permits it. Redact cookies, tokens, personal data, and request headers before saving fixtures.
If those observations feed recurring competitor or catalog alerts, the price monitoring pipeline guide covers scheduling, comparable offers, change thresholds, and alert deduplication. For multi-source retail tracking, the competitor price scraping guide explains how to scope approved competitor pages and keep seller, market, and offer type comparable.
Track price and stock changes without noise
For retail price and stock monitoring, the useful signal is a change in the same offer, not a change in whatever number the page shows first. Decide up front which offer you track, and record enough context to compare like with like.
- Record the seller and fulfillment type with every price, so a switch from Amazon's own offer to a third-party seller reads as an offer change, not a price drop.
- Store a new row only when price, availability, or seller changes, and keep
observed_aton every check so a flat line is still auditable. - Treat "unavailable" and "currently out of stock" as different states from "no offer parsed".
- Compare prices only within one marketplace and currency. Convert later, not at scrape time.
- Flag moves beyond a threshold you set, such as a large percentage drop, for review before they trigger an alert.
Set check frequency from how fast the item changes. A volatile best-seller and a stable long-tail accessory should not share a schedule.
Handle 403, 429, timeouts, and retries
Classify failures before retrying:
| Result | Meaning | Action |
|---|---|---|
| 403 | Access or policy denial | Stop retries; check scope, permissions, request type, and target policy |
| 429 | Request rate is too high | Honor Retry-After, reduce concurrency, and cool down the identity |
| 5xx | Temporary server or upstream fault | Retry a small number of times with exponential backoff |
| Timeout | Network, proxy, browser, or target delay | Retry once after diagnosis; log the failing layer |
| 200 with wrong page | Challenge, consent, redirect, or parser mismatch | Classify the page and quarantine the record |
The HTTP definition of 429 Too Many Requests notes that a response may include Retry-After. Treat that value as a minimum delay. The local HTTP 429 guide covers backoff and concurrency in more detail, while the HTTP 403 guide helps distinguish rate problems from access denials.
Use bounded retries with jitter:
import random
import time
def backoff_seconds(attempt: int, retry_after: int | None = None) -> float:
exponential = min(60, 2 ** attempt)
delay = exponential + random.uniform(0, 1.5)
return max(delay, retry_after or 0)
Do not retry 403 responses in a tight loop or switch identities repeatedly to force access. That creates more traffic while hiding the actual policy, authentication, or page-state problem.
When proxies fit Amazon scraping
Proxies are routing infrastructure, not permission. They can support legitimate ecommerce scraping when you need regional price checks, localized availability testing, independent public-page jobs, or stable outbound routing from cloud workers.
Choose the proxy behavior to match the job:
- Use a sticky or static route while one browser session loads a product page and its subresources.
- Rotate between independent public-page tasks, not midway through one page.
- Keep country targeting aligned with the marketplace being measured.
- Record the proxy session, region, response class, and latency for debugging.
- Reduce concurrency and add pacing before increasing pool size.
Rotating residential proxies can help distribute independent, permitted checks across consumer-style networks and test prices by country. Static ISP proxies fit repeated monitoring of a fixed product list, where a consistent identity and steady latency make failures easier to trace. The best proxy for web scraping guide compares those options. See ISP proxy plans for dedicated static routes and residential proxy plans when rotation and regional targeting match the workload.
If every route receives the same denial, stop. The issue is probably scope, policy, request behavior, session state, or parser assumptions rather than the number of IPs.
Monitor the scraper as a data product
Operational metrics should reveal whether the web request and the resulting data are healthy.
Track:
- Fetches by HTTP status and classified page type.
- Accepted records and quarantined records.
- Field completeness by marketplace and parser version.
- Median and high-percentile latency.
- 403 and 429 rates per worker and route.
- Price outliers and unexpected currency changes.
- Duplicate ASINs and canonicalization failures.
- Bytes and proxy bandwidth consumed per accepted record.
Alert on changes in ratios, not only total failures. A sudden rise in successful responses with missing titles often means the page layout or response type changed.
Keep a small canary set of stable products. Run it before a large batch, compare the parsed schema with expected ranges, and pause the queue when the canary fails.
FAQ
Does Amazon allow web scraping?
Not under its Conditions of Use, which exclude data mining, robots, and similar extraction tools. Amazon's robots.txt leaves most product pages crawlable, but that is a crawler convention, not permission. Use an official API or licensed data where you can.
Is scraping Amazon legal?
It depends on the data, jurisdiction, access method, contract terms, and use. Public visibility alone does not settle it, and contract and privacy claims exist separately from hacking statutes. Avoid personal data and get legal advice for consequential projects.
Does Amazon provide an API for product data?
Yes. The Creators API replaced the Product Advertising API 5.0, which now returns 403 errors. It uses OAuth 2.0 and new credentials, and eligibility rules apply, so check Associates Central before you plan around it.
Should I use Requests, Playwright, or Puppeteer?
Use an HTTP client when the required public fields are in the initial HTML. Use a browser only for permitted fields that need rendering. Fixture-tested extraction matters more than which browser library you pick.
How often should prices be checked?
Set frequency from the business need and the request rate you are permitted to use. Check volatile items more often than long-tail ones, store only changes, and avoid synchronized batches.
Will rotating proxies stop Amazon blocks?
No. Rotation can spread independent, authorized tasks, but it does not fix excessive request rates, prohibited access, invalid sessions, or bad parsing.
Final thoughts
Reliable Amazon data collection is a controlled pipeline: pick an authorized source, canonicalize ASINs, fetch conservatively, classify every page state, and validate records before storage. Start with a small canary set and expand only when both request health and field completeness hold steady. If regional price checks need distributed routing, match the proxy session to the job and keep delays conservative. The delay calculator helps size pacing before you add workers or proxy capacity.
