# Amazon Product Scraper — Prices, Deals & Monitoring (`memo23/amazon-product-scraper`) Actor

Scrape Amazon search results across 18 marketplaces into clean product rows — numeric prices, list prices, discounts, ratings, review counts, monthly-bought signals, sponsored flags, badges, Prime and ASINs. Monitor mode returns only new or changed products on scheduled runs. Pure HTTP, JSON/CSV.

- **URL**: https://apify.com/memo23/amazon-product-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** E-commerce, AI, Agents
- **Stats:** 12 total users, 12 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 product scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Amazon Product Scraper — Prices, Deals & Price Monitoring

Scrape Amazon search results into clean, analysis-ready product rows — numeric prices, real list prices, discounts, ratings, review counts, monthly-bought signals, sponsored flags, badges and Prime status — across 18 marketplaces. Point the scheduler at the same input and monitor mode returns **only new or changed products**, so a price watch costs nothing on quiet days.

No Amazon account, no Product Advertising API key, no browser runtime.

![How it works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-amazon-products.png)

### Why use this Amazon scraper?

- **18 marketplaces** — US, UK, Germany, France, Italy, Spain, Canada, Australia, Japan, India, Netherlands, Sweden, Poland, Belgium, UAE, Mexico, Turkey, Singapore. Prices come back in the marketplace currency with the ISO code attached.
- **Numbers, not strings** — `priceValue`, `listPriceValue`, `discountPercentage`, `ratingValue`, `reviewsCount` are parsed numerics; no spreadsheet cleanup.
- **Real list prices** — the parser distinguishes a genuine "List:"/"Typical:" strike-through price from Amazon's per-unit price ("$4.50/count"), so `discountPercentage` and `onSale` are trustworthy.
- **Organic vs paid** — `isSponsored` flags ad placements; `page` and `position` preserve rank for search-ranking analysis.
- **Demand signals** — the public "10K+ bought in past month" figure, both raw and normalized.
- **Incremental monitoring** — schedule the same input and receive only new ASINs and price/rating/review movements, with previous values and deltas attached. Runs that find no changes publish **no billable rows**.
- **Cheap by construction** — one HTTP fetch returns 20–48 products; there is no per-product page fetch and no browser.

### Overview

Built for e-commerce analysts, sellers, arbitrage hunters and price-tracking teams. Feed it keywords, ASINs, category/best-seller URLs or ready-made search URLs; each dataset row is one product card from the search results, attributed to the query, marketplace, result page and position that produced it.

### Supported inputs

- **Keywords** — `"usb c cable"` — runs a paginated search on every selected marketplace.
- **Bare ASINs** — `"B082Z1YYRK"` — searched directly; the matching card is returned.
- **Search URLs** — `https://www.amazon.com/s?k=gaming+mouse&rh=...` — any filters/sort the URL carries are kept.
- **Best-seller lists** — `https://www.amazon.com/gp/bestsellers/electronics/172282`.
- **Category browse pages** — `https://www.amazon.de/b?node=3468301`.
- **Product URLs** — `https://www.amazon.com/dp/B082Z1YYRK` — re-searched by ASIN.

Not supported: seller storefront profile pages (use the [Amazon Seller Contact Scraper](https://apify.com/memo23/amazon-sellers-scraper)), review threads, and product-detail-only data (variants, BSR, offer lists, A+ content — see FAQ).

### Use cases

| Who | What |
|---|---|
| E-commerce sellers | competitor & MAP price monitoring, repricing inputs |
| Arbitrage / deal hunters | discount discovery with real list-price math |
| Marketers & agencies | sponsored-vs-organic share of shelf, badge tracking |
| Product researchers | niche validation via monthly-bought + review velocity |
| Data teams | cross-marketplace price comparison feeds |

### How it works

1. Each query/URL is classified and normalized into a marketplace-pinned search crawl.
2. Listing pages are fetched in parallel over residential exit IPs matching the marketplace country (a `.de` page from a DE exit, etc. — this is what makes prices reliable).
3. Every product card is parsed into a typed row: prices, rating, reviews, badges, flags, rank.
4. Rows are deduped by ASIN per marketplace and capped by your `maxItems`.
5. In monitor mode, rows are diffed against the named baseline and only changes are published; the baseline advances only after a fully clean scrape (fail-closed).

### Input configuration

| Field | Type | Description |
|---|---|---|
| `queries` | array | Keywords or bare ASINs. Each entry crawls every selected marketplace. |
| `marketplaces` | array | Marketplace TLDs: `"com"`, `"co.uk"`, `"de"`, … Default `["com"]`. |
| `startUrls` | array | Direct Amazon URLs (search / best-sellers / category / product), any marketplace. |
| `sortBy` | string | `relevance` (default), `price-asc`, `price-desc`, `rating`, `newest`, `bestSellers`. |
| `minPrice` / `maxPrice` | integer | Price bounds in the marketplace currency (keyword queries). |
| `maxItems` | integer | Hard ceiling of product rows for the whole run. |
| `maxItemsPerQuery` | integer | Per-query/per-URL row cap. One page yields ~20–48 rows. |
| `monitorMode` | string | `off` (default), `price-changes`, `all-changes`. |
| `monitorName` | string | Stable baseline name for a scheduled watch (e.g. `"competitor-asins-us"`). |
| `concurrency` | integer | Parallel page fetches (1–20, default 6). |
| `proxy` | object | Optional override; leave unset for the built-in residential setup. |

#### Search products

```json
{
  "queries": ["usb c charger", "portable monitor"],
  "marketplaces": ["com", "de"],
  "sortBy": "bestSellers",
  "minPrice": 10,
  "maxPrice": 250,
  "maxItems": 200
}
```

#### Monitor prices on a schedule

Use the same `monitorName` (and same queries/marketplaces/filters) on every scheduled run. The first run publishes the full baseline; later runs publish only new ASINs and price moves.

```json
{
  "queries": ["B0C3HCD34R", "B082Z1YYRK"],
  "marketplaces": ["com"],
  "maxItems": 40,
  "monitorMode": "price-changes",
  "monitorName": "competitor-asin-prices-us"
}
```

`all-changes` additionally emits rating and review-count movement. The baseline is stored per `monitorName` in a named key-value store; a blocked or partial scrape never overwrites healthy state, and rows are published before the baseline advances, so a retry can duplicate an alert but never lose one.

### Output overview

One dataset row per product card. Display strings (`price`, `listPrice`, `monthlyBought`) are kept alongside normalized numerics (`priceValue`, `listPriceValue`, `monthlyBoughtValue`). Fields Amazon omits from a card (typical for some variants or unavailable offers) are `null`, never fabricated.

### Output sample

Keyword search `"usb c cable"` on amazon.com (trimmed):

```json
{
  "asin": "B0CG1LGWR6",
  "title": "LISEN USB C to USB C Cable, 240W Fast Charging Type C Charger Cord (6.6FT, 2Pack)",
  "url": "https://www.amazon.com/dp/B0CG1LGWR6",
  "price": "$8.99",
  "priceValue": 8.99,
  "listPrice": "$9.99",
  "listPriceValue": 9.99,
  "pricePerUnit": "$4.50",
  "discountPercentage": 10.01,
  "onSale": true,
  "currencyCode": "USD",
  "ratingValue": 4.6,
  "reviewsCount": 10214,
  "monthlyBought": "10K+",
  "monthlyBoughtValue": 10000,
  "isPrime": false,
  "isSponsored": false,
  "badge": "Best Seller",
  "page": 1,
  "position": 3,
  "imageUrl": "https://m.media-amazon.com/images/I/81afg0W0O8L._AC_UY218_.jpg",
  "query": "usb c cable",
  "marketplace": "amazon.com",
  "scrapedAt": "2026-07-22T21:07:50.376Z"
}
```

In monitor mode, changed rows additionally carry `changeType`, `changedFields`, `previousPriceValue`, `priceDelta`, `priceDeltaPercentage`, `previousRatingValue` and `previousReviewsCount`.

### Key output fields

- **Identity** — `asin`, `title`, `url`, `imageUrl`, `marketplace`, `query`, `sourceUrl`, `scrapedAt`
- **Pricing** — `price` / `priceValue`, `listPrice` / `listPriceValue`, `pricePerUnit`, `discountPercentage`, `onSale`, `currencyCode`, `couponText`
- **Social proof** — `ratingValue`, `reviewsCount`, `monthlyBought` / `monthlyBoughtValue`, `badge`
- **Placement** — `page`, `position`, `isSponsored`, `isPrime`, `deliveryText`
- **Monitoring** — `changeType`, `changedFields`, `previousPriceValue`, `priceDelta`, `priceDeltaPercentage`, `previousRatingValue`, `previousReviewsCount`

### FAQ

**Which URLs work?** Search results, best-seller lists, category browse pages and product URLs on any of the 18 supported marketplaces. Seller storefront profiles are out of scope.

**Does it fetch product-detail pages?** No — this is a search-results scraper by design (that's what keeps it fast and cheap). It does not return variants, seller/Buy Box ownership, inventory, Best Sellers Rank, offer lists, A+ content or full descriptions.

**Why is a price sometimes `null`?** Amazon omits the price from some search cards — typically products with variants ("Options" cards), no featured offer, or offers unavailable in the marketplace region. The row still carries everything else.

**Are monthly-bought numbers exact?** No — Amazon publishes thresholds ("1K+", "10K+"). Both the raw string and the normalized floor value are returned.

**How current is monitor-mode data?** As current as your schedule. Each run re-scrapes live search pages and diffs against the stored baseline.

**Do I need proxies?** No — residential routing per marketplace country is built in. The optional `proxy` input exists only if you want to route through your own Apify proxy groups instead.

### Support

- **Issues tab** of this actor for bugs and feature requests — response usually within 24h.
- Custom fields, exports or private variants: message via the actor's contact options.

### Additional services

Need seller contact data behind these products, review threads, or a tailored feed (custom fields, delivery to S3/webhook/DB)? Open an issue or reach out — custom versions are a routine request.

### Explore more scrapers

More e-commerce and lead-gen actors: [apify.com/memo23](https://apify.com/memo23) — including the [Amazon Seller Contact Scraper](https://apify.com/memo23/amazon-sellers-scraper) (the sellers behind these products, with emails/VAT/ratings).

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/amazon-product-scraper`).

**Purpose:** turn Amazon searches (keywords, ASINs, category/best-seller URLs) into typed product rows with numeric prices, discounts, ratings and rank across 18 marketplaces; optional stateful monitor mode emits only changes between scheduled runs.

**Minimal input:**

```json
{ "queries": ["usb c cable"], "marketplaces": ["com"], "maxItems": 30 }
```

**Output:** one dataset row per product — `asin`, `title`, `url`, `price`, `priceValue`, `listPrice`, `listPriceValue`, `pricePerUnit`, `discountPercentage`, `onSale`, `currencyCode`, `ratingValue`, `reviewsCount`, `monthlyBought`, `monthlyBoughtValue`, `isPrime`, `isSponsored`, `badge`, `couponText`, `deliveryText`, `page`, `position`, `imageUrl`, `query`, `marketplace`, `sourceUrl`, `scrapedAt` (+ `changeType`, `changedFields`, `previousPriceValue`, `priceDelta`, `priceDeltaPercentage` in monitor mode).

**Behaviors an agent should know:**

- Always set `maxItems`; an uncapped multi-query, multi-marketplace run can return thousands of rows.
- `queries` and `startUrls` are additive — both run if both are set. Bare 10-char alphanumerics in `queries` are treated as ASINs.
- `monitorMode` ≠ `off` keeps a baseline keyed by `monitorName`; the first run returns everything (`changeType: "new"`), later runs return only changes. Reuse the exact same `monitorName` + input for a watch.
- Billing: one `apify-default-dataset-item` event per published row; monitor runs with no changes publish nothing. Small actor-start fee per run.
- `priceValue` can be `null` on variant/optionless cards — handle it.

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Amazon.com, Inc. or any of its subsidiaries. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available Amazon search-results pages — no authenticated endpoints, paid features, or content behind the Amazon login wall. Users are responsible for ensuring their use complies with Amazon's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization.

***

### SEO Keywords

amazon product scraper, scrape amazon products, amazon price scraper, amazon price monitoring, amazon search results scraper, amazon scraper without api, amazon product data extraction, amazon asin scraper, amazon deals scraper, amazon discount tracker, amazon price tracker, competitor price monitoring amazon, amazon best sellers scraper, amazon sponsored products data, amazon marketplace scraper, amazon de scraper, amazon uk scraper, e-commerce price intelligence, MAP monitoring amazon, amazon product research tool

# Actor input Schema

## `queries` (type: `array`):

Keywords or bare ASINs to search on Amazon. Each entry runs its own paginated crawl on every selected marketplace. Example: "usb c cable", "yoga mat", "B082Z1YYRK".

## `marketplaces` (type: `array`):

Which Amazon marketplaces the queries run on. Prices come back in the marketplace currency with the ISO code attached. Start URLs ignore this and use the domain in the URL.

## `startUrls` (type: `array`):

Direct Amazon URLs, mixed freely: search results (amazon.com/s?k=…), best-seller lists (/gp/bestsellers/…), category pages (/b?node=…) or product pages (/dp/ASIN). Any supported marketplace — the domain in the URL wins. Runs in addition to queries.

## `sortBy` (type: `string`):

Result ordering for keyword queries (start URLs keep whatever sort their URL carries).

## `minPrice` (type: `integer`):

Lower price bound in the marketplace currency (applies to keyword queries).

## `maxPrice` (type: `integer`):

Upper price bound in the marketplace currency (applies to keyword queries).

## `maxItems` (type: `integer`):

Hard ceiling of product rows across the whole run. Also capped by your plan and charge limit.

## `maxItemsPerQuery` (type: `integer`):

Upper bound of product rows per search query or start URL. One search page yields ~20–48 products.

## `monitorMode` (type: `string`):

Schedule the same input to receive only what changed. "Price changes" emits new products and price moves; "All changes" also emits rating and review-count moves. The first run builds the baseline and returns all products. Runs that find no changes publish no billable rows.

## `monitorName` (type: `string`):

Stable name for the monitoring baseline — use the same name (with the same queries/marketplaces) on every scheduled run of the same watch. Example: "competitor-asins-us".

## `concurrency` (type: `integer`):

How many listing pages to fetch in parallel (1–20). The default is safe for any memory size.

## `proxy` (type: `object`):

Leave unset for the built-in residential setup (recommended — Amazon blocks datacenter IPs). Set only to route traffic through your own Apify proxy groups instead.

## Actor input object example

```json
{
  "queries": [
    "usb c cable"
  ],
  "marketplaces": [
    "com"
  ],
  "startUrls": [],
  "sortBy": "relevance",
  "maxItems": 100,
  "maxItemsPerQuery": 100,
  "monitorMode": "off",
  "concurrency": 6
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "usb c cable"
    ],
    "marketplaces": [
        "com"
    ],
    "startUrls": [],
    "maxItems": 100,
    "maxItemsPerQuery": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/amazon-product-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": ["usb c cable"],
    "marketplaces": ["com"],
    "startUrls": [],
    "maxItems": 100,
    "maxItemsPerQuery": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/amazon-product-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "usb c cable"
  ],
  "marketplaces": [
    "com"
  ],
  "startUrls": [],
  "maxItems": 100,
  "maxItemsPerQuery": 100
}' |
apify call memo23/amazon-product-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/amazon-product-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/7gA1xBQyhaBJ3sjbA/builds/heNZgdLPuIkeTQTlw/openapi.json
