The Mine Works
← All posts
tutorial October 8, 2026 · 7 min read Updated October 8, 2026

Track Daily Rank Changes in an Amazon Best Sellers Category

Run Amazon Bestsellers Scraper every morning, diff each ASIN's rank against yesterday, and flag new entrants, drop outs and big movers in Python.

Try the scraper

The actor referenced in this article. Pay only for results delivered.

View the scraper →

If you sell in a category on Amazon, or source products for one, the Best Sellers list is the most public signal of what is moving. The list changes through the day and shows only the current order, so a product that jumped 50 places overnight leaves no trace unless you saved yesterday’s copy. Copying 100 ranks by hand every morning is not a job anyone keeps doing.

Try it live: Amazon Bestsellers Scraper: Top 100 Best Sellers, 10 Countries. Pay per result delivered. Failed and empty results are never charged.

The Amazon Bestsellers Scraper reads all 100 ranks of a Best Sellers list, including the items Amazon only loads as you scroll, and returns one row per ranked product. Run it daily, keep each day’s rows, and the diff is a few lines of Python.

What you get and who it is for

FieldUse in a daily diff
rankPosition in the list, 1 to 100
asinAmazon’s product id, the key you compare on
category_pathThe list the row belongs to, such as electronics
marketplaceThe Amazon site, such as amazon.com
titleProduct title, to tell variants apart
price, currencyPrice shown on the list
rating, review_countStar rating and number of ratings, when the list shows them
page1 for ranks 1 to 50, 2 for 51 to 100
scraped_atWhen the list was read, in UTC

This is for Amazon sellers watching their own category, brand teams tracking competitors, product researchers looking for items on the way up, and analysts who want a rank history that Amazon does not keep for them.

The input

{
  "categories": [
    "https://www.amazon.com/Best-Sellers-Electronics/zgbs/electronics/",
    "https://www.amazon.com/Best-Sellers-Electronics-Headphones/zgbs/electronics/172541/"
  ],
  "listType": "bestsellers",
  "maxItemsPerList": 100,
  "subcategoryDepth": 0
}
  • categories: Best Sellers links, one per list. A link keeps its own Amazon site, so marketplace does not matter here. Copy the link from the category page you care about.
  • maxItemsPerList: 100 reads the full list. At 50 you pay half, but anything moving between 51 and 100 then looks like an entry or an exit.
  • subcategoryDepth: 0 keeps the run to exactly these lists, so every day’s data covers the same ground.

What the output looks like

[
  {
    "marketplace": "amazon.com",
    "category_path": "electronics",
    "rank": 85,
    "asin": "B0HJ9ZXCSD",
    "title": "Apple Watch Series 12 GPS 42mm Smartwatch | Light Gold Aluminum Case, Sand Sport Band...",
    "price": 349.99,
    "currency": "USD",
    "rating": 4.7,
    "review_count": 94,
    "page": 2,
    "scraped_at": "2026-10-06T09:06:57.067Z"
  },
  {
    "marketplace": "amazon.com",
    "category_path": "electronics",
    "rank": 33,
    "asin": "B0HJ9ZXCSD",
    "title": "Apple Watch Series 12 GPS 42mm Smartwatch | Light Gold Aluminum Case, Sand Sport Band...",
    "price": 349.99,
    "currency": "USD",
    "rating": 4.7,
    "review_count": 105,
    "page": 1,
    "scraped_at": "2026-10-07T09:06:26.016Z"
  },
  {
    "marketplace": "amazon.com",
    "category_path": "electronics",
    "rank": 36,
    "asin": "B0BS1PRC4L",
    "title": "Sony WH-CH520 Wireless On-Ear Bluetooth Headphones with Microphone, Black...",
    "price": 30.03,
    "currency": "USD",
    "rating": 4.4,
    "review_count": 35674,
    "page": 1,
    "scraped_at": "2026-10-07T09:06:26.016Z"
  }
]

These rows come from two of our own runs on amazon.com Electronics, at 09:06 UTC on October 6 and October 7, 2026. The Apple Watch went from 85 to 33 overnight, a 52 place climb, while its ratings count went from 94 to 105. The Sony headphones were not in the October 6 list at all. Across the whole list, 7 ASINs entered, 7 dropped out, and 84 of the 93 that stayed changed rank, 23 of them by 10 places or more. A climb like the Apple Watch’s usually has a reason on the listing, and the product’s reviews can be read without the SP-API.

Run it in Apify Console

  1. Open https://apify.com/themineworks/amazon-bestsellers-scraper and click Try for free.
  2. In Categories (Best Sellers links or category paths), paste one Best Sellers link per line.
  3. Set List to Best Sellers, Items per list to 100 and Subcategory levels to 0.
  4. Click Start. The rows show up in the Output tab, ranked from 1.
  5. Click Export and download CSV, JSON or Excel. Keep one file per day.

Run it from Python

pip install apify-client
import csv
import glob
from datetime import date
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
CATEGORIES = [
    "https://www.amazon.com/Best-Sellers-Electronics/zgbs/electronics/",
    "https://www.amazon.com/Best-Sellers-Electronics-Headphones/zgbs/electronics/172541/",
]
BIG_MOVE = 10

run = client.actor("themineworks/amazon-bestsellers-scraper").call(run_input={
    "categories": CATEGORIES,
    "listType": "bestsellers",
    "maxItemsPerList": 100,
    "subcategoryDepth": 0,
})

today = []
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item.get("_type") == "info":
        continue  # the run summary row, never billed
    today.append(item)

# a short list would look like dozens of drop outs, so stop instead
per_list = {}
for r in today:
    per_list[r["category_path"]] = per_list.get(r["category_path"], 0) + 1
if len(per_list) < len(CATEGORIES) or min(per_list.values()) < 100:
    raise SystemExit(f"incomplete lists today: {per_list}; rerun before diffing")

out = f"bestsellers_{date.today()}.csv"
fields = ["marketplace", "category_path", "rank", "asin", "title",
          "price", "currency", "rating", "review_count", "scraped_at"]
with open(out, "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=fields, extrasaction="ignore")
    writer.writeheader()
    writer.writerows(today)

older = sorted(p for p in glob.glob("bestsellers_*.csv") if p != out)
if not older:
    raise SystemExit("first day saved; the diff starts tomorrow")
with open(older[-1], encoding="utf-8") as f:
    before = {(r["marketplace"], r["category_path"], r["asin"]): int(r["rank"])
              for r in csv.DictReader(f)}
now = {(r["marketplace"], r["category_path"], r["asin"]): r for r in today}

for key in sorted(now, key=lambda k: (k[1], now[k]["rank"])):
    r, old = now[key], before.get(key)
    if old is None:
        print(f"NEW   {key[1]} #{r['rank']} {r['asin']} {r['title'][:60]}")
    elif abs(old-r["rank"]) >= BIG_MOVE:
        print(f"MOVE  {key[1]} #{old} to #{r['rank']} {r['asin']} {r['title'][:60]}")
for key, old in sorted(before.items(), key=lambda kv: kv[1]):
    if key not in now:
        print(f"OUT   {key[1]} was #{old} {key[2]}")

The script saves today’s rows to a dated CSV, refuses to diff when a list came back short, then compares against the most recent earlier file. It prints new entrants, products that moved 10 places or more in either direction, and products that left the top 100. Change BIG_MOVE to suit your category: a list where 23 products move 10 places in a day needs a higher bar than a quiet one.

Run it every day

In Apify Console, save the input as a task, open Schedules, and create a schedule with the cron expression 0 7 * * * (every day at 07:00) for that task. Each run returns the full list again, which is what a diff needs; the actor has no “only new” option and does not need one here. Every row carries scraped_at, so you can stack the daily runs in one sheet with Apify’s Google Sheets integration, or have a webhook call your own script when the run succeeds and post the NEW and MOVE lines to Slack.

If you would rather run the Python script itself, schedule it with cron on a machine you control at the same hour. It keeps the dated CSV files it compares against.

What it costs

You pay per ranked product delivered: $3.49 per 1,000 on the Bronze plan, $2.99 on Silver, and $2.49 on Gold, Platinum and Diamond, plus a flat $0.005 per run start.

Two lists of 100, every day for 30 days, is 6,000 products: $20.94 on Bronze, plus $0.15 in start fees for 30 runs. On Silver the same month is $17.94, on Gold $14.94. One list alone is half that, $10.47 on Bronze. Refused pages, empty lists and wrong links are never charged.

Limits worth knowing

  • Only the top 100. Amazon shows 100 ranks per list. A product that drops below that is missing, not ranked 101.
  • A list can come back partial. Our run at 11:12 UTC on October 7, 2026 delivered 22 of 100 items for Electronics, two hours after a full read. The run’s OUTPUT record gives each list a status such as ok, partial or blocked. The script above stops rather than reporting 78 false drop outs.
  • Variants have their own ASINs. In the same two runs, the Soundcore P30i earbuds fell from 30 to 93 under one ASIN while the same title under a second ASIN entered at 81, and a Blink Outdoor 4 bundle with 2 cameras left at 73 as the 5 camera bundle entered at 69. Read the titles before you report a new product.
  • A price change may be a different seller. When Amazon shows a number of offers, price is the lowest offer and offer_count is the count. The Beats Studio Pro showed $119.00 on October 6 and $142.45 with 12 offers on October 7.
  • One snapshot a day. Amazon updates the lists frequently, so a daily run samples a list that also moves between runs.
Related Actor

Explore the scraper referenced in this article: inputs, outputs, and pricing, then run it on Apify.

Frequently asked questions

What time of day should the daily run start? +

Any time, as long as it is the same every day. Amazon updates the lists frequently, so each run is a snapshot at scraped_at, and a fixed start time makes every diff cover the same 24 hours.

What happens to a product that falls out of the top 100? +

It is simply missing from today's rows. Amazon only shows the top 100, so there is no rank 101 to record. The script below lists those products as OUT with yesterday's rank.

Why does a product show as new when it was on the list yesterday? +

Usually because it is a different variant. Colors and bundles often have their own ASIN, so one variant can drop while another enters. Check the title before you call it a new product.

Can I track the same category in several countries? +

Yes. Paste the Best Sellers link from each Amazon site into the same run. Links keep their own site, and the script keys every comparison on marketplace, category_path and asin.

Apify Store

Find a ready-made scraper for your job

Apify has over 80,000 scrapers and automations, ours included. Start free with $5 of platform credit every month.