Price tracking is a billion-dollar industry. From Keepa to CamelCamelCamel, hundreds of tools monitor Amazon prices — and behind each one is a scraper that needs to survive Amazon's anti-bot defenses.
In this guide, I'll show you how to build a working Amazon price monitor in Python, why naive approaches fail, and how to actually keep it running in 2026.
The Basic Approach (And Why It Breaks)
Let's start with the simplest possible scraper:
# Implementation is proprietary (that IS the moat).
# Skip the build — use our ready-made Apify actor:
# see the CTA below for the link (fpr=yw6md3).
Run this a few times and it works. Run it 20 times in a row and you'll get hit with a CAPTCHA page or a 503 response. Here's why.
Why Amazon Blocks You
Amazon's anti-bot system (internally called "Perimeter") checks several signals:
- User-Agent consistency — Sending the same UA on every request is a red flag
- Request rate — More than ~10 requests/minute from one IP triggers detection
- IP reputation — Datacenter IPs are flagged immediately. Residential IPs get more leeway
-
TLS fingerprint — Python's
requestslibrary has a recognizable TLS fingerprint that differs from real browsers - Missing headers — Real browsers send 15+ headers. Your script sends 3.
The basic approach above will work for occasional one-off checks. For continuous monitoring, you need a different strategy.
Adding Rotation and Delays
A slightly more robust version with random delays and User-Agent rotation:
# Implementation is proprietary (that IS the moat).
# Skip the build — use our ready-made Apify actor:
# see the CTA below for the link (fpr=yw6md3).
This buys you more time, but for any serious monitoring (100+ products, daily checks), you'll still get blocked within a day or two. The problem is your IP — Amazon sees all requests from the same address.
The Proxy Approach: ScraperAPI
The most reliable way to scrape Amazon at scale is to route requests through rotating proxies that handle the anti-bot layer for you. ScraperAPI does exactly this — it manages proxy rotation, CAPTCHA solving, and header management automatically.
Here's the same scraper using ScraperAPI:
# Implementation is proprietary (that IS the moat).
# Skip the build — use our ready-made Apify actor:
# see the CTA below for the link (fpr=yw6md3).
This handles rotation, retries, and CAPTCHA solving on their end. You get clean HTML back. Their free tier gives you 5,000 API credits to test with.
Alternative: raw residential proxies. If you prefer direct proxy access over a managed API, ThorData provides 50M+ rotating residential IPs. You'd handle retry logic yourself, but get more flexibility and bandwidth-based pricing instead of per-request charges.
Building a Price Monitor
Now let's combine everything into an actual price tracker that alerts you on drops:
import json
import smtplib
from email.mime.text import MIMEText
from datetime import datetime
from pathlib import Path
PRICE_HISTORY_FILE = 'price_history.json'
def load_history():
if Path(PRICE_HISTORY_FILE).exists():
return json.loads(Path(PRICE_HISTORY_FILE).read_text())
return {}
def save_history(history):
Path(PRICE_HISTORY_FILE).write_text(json.dumps(history, indent=2))
def check_price_drop(asin, current_price, threshold_pct=5):
history = load_history()
if asin not in history:
history[asin] = []
prices = history[asin]
prices.append({'price': current_price, 'date': datetime.now().isoformat()})
# Keep last 90 days of data
history[asin] = prices[-90:]
save_history(history)
if len(prices) < 2:
return False
previous = prices[-2]['price']
if previous and current_price:
drop_pct = ((previous - current_price) / previous) * 100
return drop_pct >= threshold_pct
return False
def monitor_products(asins):
for asin in asins:
product = scrape_amazon_via_proxy(asin) # or scrape_with_retry()
if not product or not product['price']:
continue
price = float(product['price'].replace('$', '').replace(',', ''))
dropped = check_price_drop(asin, price)
status = ' ⬇ PRICE DROP!' if dropped else ''
print(f"[{datetime.now():%H:%M}] {product['title'][:40]}... ${price:.2f}{status}")
# Run every hour via cron:
# 0 * * * * cd /path/to/project && python monitor.py
monitor_products(['B0D1XD1ZV3', 'B0DGHRF8TN', 'B0C8Y7WC2M'])
Scaling Up: When Code Isn't Enough
Once you're monitoring 500+ products, managing your own scraper becomes a full-time job — proxy failures, selector changes, rate limit tuning. At that point, consider a managed solution.
Amazon product scrapers on Apify handle the infrastructure side: automatic proxy rotation, scheduled runs, and structured JSON output. You write zero scraping code — just feed in ASINs and get back clean data via API or webhook.
This makes sense when your time is better spent building the application layer (alerts, dashboards, arbitrage logic) rather than maintaining scraping infrastructure.
Key Takeaways
- Basic requests + BeautifulSoup works for small-scale, occasional scraping
- Rotate User-Agents and add delays to extend your runway
- Use a proxy service like ScraperAPI when you need reliability at scale
- Store price history in JSON or SQLite for trend analysis
- Schedule with cron for hands-off monitoring
- Consider managed solutions when maintaining scrapers costs more than paying for one
The code above is a starting point. For production use, add SQLite instead of JSON, proper error handling, and structured logging. But the core pattern — fetch, parse, compare, alert — stays the same.
What's your Amazon scraping setup? Drop a comment if you've found better selectors or anti-detection tricks that work in 2026.
Top comments (0)