# Amazon Best Sellers Scraper (`w3crawler/amazon-bestsellers-scraper`) Actor

Scrape Amazon Best Sellers rankings by category from Amazon.in (and other marketplaces). Extracts rank, title, ASIN, price, rating, reviews, and optionally full product details.

- **URL**: https://apify.com/w3crawler/amazon-bestsellers-scraper.md
- **Developed by:** [w3crawler](https://apify.com/w3crawler) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 1,000 best sellers

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Amazon Best Sellers Scraper

Amazon Best Sellers Scraper collects rich, publicly visible bestseller observations from Amazon category pages or direct product URLs. It supports India, US, UK, Germany, Japan, Canada, Australia, and Brazil marketplaces.

Pagination follows Amazon's public `Next page` link in source order and preserves the source URL's marketplace, category path, and non-pagination query parameters. Repeated marketplace/ASIN pairs are deduplicated by default, filters and sorting are applied before `maxItems`, and optional detail requests run with bounded concurrency. The dataset contains product rows only; run metrics and failures are stored separately in the key-value store.

`maxPages` is a per-category-source ceiling, not a promise that Amazon exposes that many pages. The crawler stops on the first applicable boundary: `maxItems` for unfiltered rank order, the configured page ceiling, no observed next link, a repeated URL, no new ASINs, or a blocked/failed response. During the current live inspection of `amazon.in/gp/bestsellers/electronics/`, Amazon exposed page 1 → page 2; page 2 began at rank 51 and exposed no further next link.

### Dataset fields

| Field | Description |
| --- | --- |
| `rank`, `rankOnPage`, `pageNumber` | Bestseller position and page context |
| `asin`, `title`, `url`, `canonicalUrl` | Product identity and canonical public product URL |
| `sourceUrl`, `listingUrl`, `categoryUrl`, `productUrl` | Reproducible listing/detail source context |
| `marketplace`, `country`, `userLocale`, `categoryName` | Marketplace and category context |
| `price`, `listPrice` | Public price objects with `value` and ISO `currency` |
| `stars`, `reviewsCount`, `reviewsLink`, `hasReviews` | Public rating and review signals |
| `isPrime`, `inStock`, `inStockText` | Public listing and product availability signals |
| `brand`, `manufacturer`, `model`, `modelNumber`, `description`, `breadCrumbs`, `features` | Public product information from detail pages |
| `sellerName`, `offerUrl`, `deliveryText`, `couponText`, `badges`, `dealBadge`, `discountPercentage` | Public offer and promotion signals when exposed |
| `attributes`, `productOverview` | Public specification rows when technical details are enabled |
| `imageUrl`, `thumbnailImage`, `imageAlt`, `imageUrls`, `galleryThumbnails`, `highResolutionImages`, `imageCount` | Product-scoped public media |
| `reviews` | Bounded public JSON-LD review summaries when enabled |
| `sourceStructuredData`, `structuredDataTypes`, `pageText`, `wordCount`, `htmlLength` | Public page evidence and bounded text context |
| `scrapedAt` | ISO timestamp for the observation |

The Actor does not put source labels, `fieldCoverage`, `dataQuality`, `recordId`, actor metadata, access flags, request counters, proxy metadata, or other debugging wrappers in dataset rows. Failed requests appear in run counts and logs only; they do not add dataset rows.

### Input examples

#### 1. Ordered multi-page category scrape

```json
{
  "mode": "category",
  "country": "in",
  "category": "electronics",
  "maxItems": 100,
  "maxPages": 3,
  "deduplicate": true,
  "sortBy": "rank_asc"
}
```

#### 2. Multiple category sources with filters and sorting

```json
{
  "mode": "categoryUrl",
  "categoryUrl": "https://www.amazon.in/gp/bestsellers/electronics/",
  "categoryUrls": [
    "https://www.amazon.in/gp/bestsellers/computers/",
    "https://www.amazon.in/gp/bestsellers/beauty/"
  ],
  "maxPages": 2,
  "filters": {
    "minRating": 4.5,
    "minReviewsCount": 50,
    "minPrice": 200,
    "maxPrice": 5000,
    "includePrimeOnly": true,
    "includeKeywords": ["wireless", "usb"],
    "excludeKeywords": ["refurbished"]
  },
  "sortBy": "rating_desc",
  "maxItems": 50
}
```

#### 3. Product detail enrichment and developer options

```json
{
  "mode": "category",
  "country": "com",
  "category": "electronics",
  "maxItems": 20,
  "maxPages": 1,
  "deepSearch": true,
  "extractReviews": true,
  "maxReviews": 5,
  "includeMedia": true,
  "includeTechnicalDetails": true,
  "requestDelayMs": 800,
  "maxConcurrency": 2,
  "maxRequestRetries": 3,
  "requestTimeoutSecs": 45,
  "maxResponseBytes": 20000000,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyCountry": "US"
  }
}
```

The aliases `requestTimeoutMs`, `timeoutSecs`, `timeoutMs`, `navigationTimeoutMs`, `minDelayMs`, `pageDelayMs`, `concurrency`, `detailConcurrency`, `maxRetries`, `maxBytes`, and `dedupe` are accepted for compatibility. Unsupported input keys are rejected.

#### 4. Direct product URLs

```json
{
  "mode": "productUrl",
  "productUrls": [
    "https://www.amazon.com/dp/B0EXAMPLE1",
    "https://www.amazon.com/dp/B0EXAMPLE2"
  ],
  "deepSearch": true,
  "extractReviews": true,
  "maxItems": 2
}
```

#### 5. Offline pagination and detail QA

```json
{
  "mode": "category",
  "category": "electronics",
  "maxPages": 2,
  "maxItems": 4,
  "requestDelayMs": 0
}
```

Local detail tests use checked-in product fixtures directly. Fixture data is not exposed as a public Actor input, and live runs request the public source.

### Example output

```json
{
  "rank": 1,
  "pageNumber": 1,
  "asin": "B0TEST1001",
  "title": "Aurora Wireless Earbuds",
  "url": "https://www.amazon.in/dp/B0TEST1001",
  "canonicalUrl": "https://www.amazon.in/dp/B0TEST1001",
  "sourceUrl": "https://www.amazon.in/gp/bestsellers/electronics/",
  "listingUrl": "https://www.amazon.in/gp/bestsellers/electronics/",
  "marketplace": "amazon.in",
  "country": "in",
  "categoryName": "electronics",
  "price": { "value": 1299, "currency": "INR" },
  "stars": 4.6,
  "reviewsCount": 1204,
  "isPrime": true,
  "thumbnailImage": "https://images.example.com/aurora-earbuds.jpg",
  "scrapedAt": "2026-09-07T00:00:00.000Z"
}
```

### Access boundary

Requests use transparent public HTTP with optional ordinary Apify Proxy or public proxy routing. The Actor does not log in, solve CAPTCHAs, spoof fingerprints, use stealth rotation, bypass access controls, or call private APIs. Amazon challenge pages, explicit HTTP blocks, redirects outside the requested marketplace, timeouts, oversized responses, and pages without public cards fail closed without adding non-product rows to the dataset.

### Local development and validation

```bash
npm install
apify validate-schema
apify run --purge --input-file .actor/input.json
npm run validate
```

Local dataset rows are written under `storage/datasets/default/`. `OUTPUT_SUMMARY` contains run counts and options, and failure details stay in the run logs. When at least one source-backed row was saved, later request or dataset-write errors leave the Actor run `SUCCEEDED` and set `dataStatus` to `PARTIAL`. A run with errors and no saved rows is marked `FAILED`.

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

Use only public pages and comply with Amazon's terms, robots guidance, rate limits, and applicable law.

Run summaries include the required `status`, `runStatus`, and `dataStatus` fields. `status` and `runStatus` are `SUCCEEDED` when source-backed rows were saved or a run completed cleanly with no matches; they are `FAILED` only when a real failure occurs before any rows are saved. `dataStatus` is `COMPLETE`, `PARTIAL`, `NO_RESULTS`, or `FAILED`. Failure details stay in the run logs; key-value summaries retain counts only.

# Changelog

This Actor's version history is a separate document: https://apify.com/w3crawler/amazon-bestsellers-scraper/changelog.md

# Actor input Schema

## `mode` (type: `string`):

Choose category pagination, one or more category URLs, or direct product details.

## `category` (type: `string`):

Marketplace-relative Best Sellers category slug, such as electronics or beauty.

## `categoryUrl` (type: `string`):

One public Amazon Best Sellers category URL when mode is categoryUrl.

## `categoryUrls` (type: `array`):

Additional public Amazon Best Sellers URLs. They are processed in the supplied order.

## `productUrls` (type: `array`):

Public Amazon product URLs when mode is productUrl.

## `country` (type: `string`):

Marketplace used for category slugs and default locale.

## `locale` (type: `string`):

Accept-Language value sent to public Amazon pages.

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

Maximum source-backed product rows emitted after filters and sorting.

## `maxPages` (type: `integer`):

Maximum observed Amazon Best Sellers pages visited per category source. The crawler follows Amazon's public next-page link and may stop earlier when no next page or no progress is exposed.

## `deepSearch` (type: `boolean`):

Fetch each selected product page for public description, offer, feature, specification, media, and JSON-LD fields.

## `extractReviews` (type: `boolean`):

Keep bounded review summaries found in public product JSON-LD when detail enrichment is enabled.

## `maxReviews` (type: `integer`):

Maximum public review summaries retained per product.

## `includeMedia` (type: `boolean`):

Include product-scoped public image arrays during detail enrichment. The listing thumbnail remains available.

## `includeTechnicalDetails` (type: `boolean`):

Include public attribute and product-overview rows during detail enrichment.

## `deduplicate` (type: `boolean`):

Keep one row per marketplace/ASIN across pages and category sources.

## `dedupe` (type: `boolean`):

Compatibility alias for deduplicate.

## `filters` (type: `object`):

Filters are applied to public listing signals before sorting and the maxItems limit.

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

Stable sort applied after filtering and deduplication.

## `requestTimeoutSecs` (type: `integer`):

Maximum duration of each public request.

## `timeoutSecs` (type: `integer`):

Compatibility alias for requestTimeoutSecs.

## `requestTimeoutMs` (type: `integer`):

Compatibility alias converted to seconds.

## `timeoutMs` (type: `integer`):

Compatibility alias converted to seconds.

## `navigationTimeoutMs` (type: `integer`):

Compatibility alias converted to seconds.

## `requestDelayMs` (type: `integer`):

Pacing delay before each live public request.

## `minDelayMs` (type: `integer`):

Compatibility alias for requestDelayMs.

## `pageDelayMs` (type: `integer`):

Compatibility alias for requestDelayMs.

## `maxConcurrency` (type: `integer`):

Maximum simultaneous detail requests. Pagination requests remain ordered.

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

Compatibility alias for maxConcurrency.

## `detailConcurrency` (type: `integer`):

Explicit detail worker limit.

## `maxRequestRetries` (type: `integer`):

Retries timeouts, transient failures, and rate limits; access challenges are not bypassed.

## `maxRetries` (type: `integer`):

Compatibility alias for maxRequestRetries.

## `maxResponseBytes` (type: `integer`):

Reject unusually large public responses before parsing.

## `maxBytes` (type: `integer`):

Compatibility alias for maxResponseBytes.

## `userAgent` (type: `string`):

Optional identifying user-agent string; no stealth rotation is performed.

## `proxyConfiguration` (type: `object`):

Optional ordinary Apify Proxy or public HTTP(S) routing. No CAPTCHA solving or access-control bypass is attempted.

## Actor input object example

```json
{
  "mode": "category",
  "category": "electronics",
  "country": "in",
  "locale": "en-IN",
  "maxItems": 50,
  "maxPages": 2,
  "deepSearch": false,
  "extractReviews": false,
  "maxReviews": 10,
  "includeMedia": true,
  "includeTechnicalDetails": true,
  "deduplicate": true,
  "sortBy": "rank_asc",
  "requestTimeoutSecs": 120,
  "requestDelayMs": 500,
  "maxConcurrency": 3,
  "maxRequestRetries": 2,
  "maxResponseBytes": 15000000
}
```

# Actor output Schema

## `dataset` (type: `string`):

Source-backed listing and product observations only.

## `runSummary` (type: `string`):

Counts, pagination metrics, and bounded options used by the run.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("w3crawler/amazon-bestsellers-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("w3crawler/amazon-bestsellers-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 '{}' |
apify call w3crawler/amazon-bestsellers-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,w3crawler/amazon-bestsellers-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/w1mxA4aaoFWmGXF4i/builds/tFZzpAaTwgQkUegzv/openapi.json
