Python · Amazon
Monitorare i prezzi Amazon con Python
Su Amazon i prezzi cambiano di continuo e nessuno ha voglia di aprire ogni mattina la stessa pagina prodotto. In questa guida costruisci un piccolo script che lo fa al posto tuo: recupera il prezzo attuale dei prodotti che ti interessano, registra ogni controllo in un file che puoi aprire con un foglio di calcolo e ti avvisa quando un prezzo scende sotto la cifra che sei disposto a pagare.
Non devi occuparti della pagina Amazon. everydata.io carica per te la pagina prodotto live e restituisce dati puliti – titolo, prezzo, valuta, disponibilità – così lo script resta breve e non si rompe quando Amazon cambia layout.
Aggiornato il · di everydata.io
Cosa avrai alla fine
- Uno script che controlla un elenco di prodotti Amazon e aggiunge ogni prezzo a prices.csv.
- Un messaggio quando un prezzo scende o raggiunge il tuo obiettivo.
- Una pianificazione giornaliera, così lo script gira senza di te.
Cosa ti serve
- Python 3.10 o superiore e il pacchetto
requests(pip install requests). - Una chiave API gratuita di everydata.io – creala qui.
- L'ASIN di ogni prodotto: il codice di 10 caratteri dopo
/dp/nell'indirizzo Amazon.
01Tieni la chiave API fuori dal codice
Accedi, copia la chiave dalla dashboard e salvala in una variabile d'ambiente. Lo script la legge da lì, così la chiave non finisce mai in un file che potresti condividere.
export EVERYDATA_API_KEY="ds_your_key"02Recupera un prodotto
Inizia con una singola richiesta per vedere cosa restituisce. L'endpoint product-by-ASIN accetta l'ASIN e il marketplace (com per amazon.com, de per amazon.de e così via).
import os
import requests
API = "https://api.everydata.io"
KEY = os.environ["EVERYDATA_API_KEY"]
resp = requests.get(
f"{API}/amz/amazon-lookup-product-by-asin",
params={"asin": "B07ZPKN6YR", "domainCode": "com"},
headers={"x-api-key": KEY},
timeout=60,
)
resp.raise_for_status()
product = resp.json()
print(product["productTitle"])
print(product["price"], product["currency"], "-", product["warehouseAvailability"])La risposta è in JSON. Ogni risposta inizia con responseStatus e responseMessage, seguiti dal prodotto. Ecco una versione abbreviata dell'esempio documentato:
{
"responseStatus": "PRODUCT_FOUND_RESPONSE",
"responseMessage": "Product successfully found!",
"productTitle": "Apple iPhone 11, 64GB, Black - Unlocked (Renewed)",
"productRating": "4.2 out of 5 stars",
"countReview": 60024,
"asin": "B07ZPKN6YR",
"warehouseAvailability": "This item cannot be shipped to your selected delivery location. Please choose a different delivery location.",
"retailPrice": 0,
"price": 0,
"currency": "USD"
}Guarda price in questo esempio: vale 0. Succede quando la pagina non mostra un prezzo acquistabile – qui perché l'articolo non poteva essere spedito all'indirizzo di consegna. Il tuo script deve interpretare 0 come “nessun prezzo al momento”, non come un prodotto gratuito.
03Controlla un elenco di prodotti e salva ogni risultato
Ora trasforma la singola richiesta in un piccolo tracker. WATCHLIST contiene i prodotti e il prezzo che stai aspettando. A ogni esecuzione lo script recupera ogni prodotto una volta, aggiunge una riga a prices.csv e confronta il nuovo prezzo con l'ultimo salvato.
"""Check the price of a few Amazon products and append each check to prices.csv."""
import csv
import os
import re
import time
from datetime import datetime, timezone
from pathlib import Path
import requests
API = "https://api.everydata.io"
KEY = os.environ["EVERYDATA_API_KEY"]
CSV_FILE = Path("prices.csv")
DOMAIN = "com" # amazon.com – use "de", "co.uk", "fr" … for other marketplaces
# ASIN -> the price at which you want to hear about it
WATCHLIST = {
"B07ZPKN6YR": 30.00,
}
def api_get(path: str, params: dict) -> dict:
"""GET an everydata.io endpoint. Waits when rate limited (429) and retries a failed page load (5xx) once."""
retried = False
for _ in range(4):
resp = requests.get(f"{API}{path}", params=params, headers={"x-api-key": KEY}, timeout=60)
if resp.status_code == 429:
# Too many requests at once. The answer says how long to wait: "... Try again in 12 seconds."
wait = re.search(r"in (\d+) seconds", resp.text)
time.sleep(int(wait.group(1)) + 1 if wait else 60)
continue
if resp.status_code >= 500 and not retried:
retried = True # 5xx answers are not counted against your quota
time.sleep(10)
continue
resp.raise_for_status() # 4xx (wrong key, quota used up, bad parameter) or a second 5xx
return resp.json()
raise RuntimeError("still rate limited after several waits – try again later")
def last_price(asin: str) -> float | None:
"""The most recent price we saved for this ASIN, if any."""
if not CSV_FILE.exists():
return None
with CSV_FILE.open(newline="") as f:
rows = [r for r in csv.DictReader(f) if r["asin"] == asin and r["price"]]
return float(rows[-1]["price"]) if rows else None
def main() -> None:
previous = {asin: last_price(asin) for asin in WATCHLIST}
now = datetime.now(timezone.utc).isoformat(timespec="seconds")
new_file = not CSV_FILE.exists()
with CSV_FILE.open("a", newline="") as f:
writer = csv.writer(f)
if new_file:
writer.writerow(["checked_at", "asin", "title", "price", "retail_price", "currency", "availability"])
for asin, target in WATCHLIST.items():
try:
p = api_get("/amz/amazon-lookup-product-by-asin", {"asin": asin, "domainCode": DOMAIN})
except (requests.RequestException, RuntimeError) as exc:
print(f"{asin}: could not check this time ({exc}) – the next run tries again")
continue # one failed product does not stop the others
price = p.get("price") or None # 0 means the page showed no price
writer.writerow([
now, asin, p.get("productTitle"), price or "", p.get("retailPrice") or "",
p.get("currency") or "", p.get("warehouseAvailability") or "",
])
if price is None:
print(f"{asin}: no price on the page ({p.get('warehouseAvailability')})")
elif price <= target:
print(f"{asin}: {price} {p.get('currency')} – at or below your target of {target}")
elif previous[asin] is not None and price < previous[asin]:
print(f"{asin}: dropped from {previous[asin]} to {price} {p.get('currency')}")
if __name__ == "__main__":
main()Eseguilo con python3 track.py. La prima esecuzione crea il file; quelle successive aggiungono una riga per prodotto. Puoi aprire prices.csv con qualsiasi foglio di calcolo per disegnare un grafico dei prezzi.
api_get gestisce le due risposte che prima o poi incontrerai. Se una pagina non si carica, l'API risponde con uno stato 5xx come 502 o 503; queste risposte non vengono conteggiate nella tua quota, quindi lo script attende qualche secondo e riprova una volta. Se invii troppe richieste insieme, la risposta è 429 e indica quanti secondi attendere – lo script aspetta il tempo indicato e prosegue. Un prodotto che fallisce ancora viene segnalato e saltato, e l'esecuzione successiva lo riprende.
04Scegli come vuoi essere avvisato
Lo script stampa una riga in tre casi: la pagina non mostra alcun prezzo, il prezzo è pari o inferiore al tuo obiettivo, oppure è sceso rispetto all'ultimo controllo. Se leggi il log, la stampa basta. Se preferisci ricevere un messaggio, sostituisci le tre chiamate print con ciò che usi già – un'email con smtplib di Python, un webhook di chat o un servizio di notifiche push.
05Eseguilo ogni giorno
Su un Mac o una macchina Linux accesa, cron è lo scheduler più semplice. Questa riga esegue il tracker ogni mattina alle 7:00 e salva un log:
# Every day at 07:00 – edit with: crontab -e
0 7 * * * cd /home/you/price-tracker && EVERYDATA_API_KEY=ds_your_key /usr/bin/python3 track.py >> track.log 2>&1Su Windows, l'Utilità di pianificazione fa lo stesso lavoro. Va bene anche un piccolo server o un job CI pianificato.
Ogni controllo di un prodotto è una richiesta. Un esempio: tre prodotti controllati una volta al giorno fanno circa 90 richieste al mese, che rientrano nel piano gratuito da 100 richieste. Per più prodotti o più controlli al giorno, consulta i prezzi.
06Facoltativo: leggi lo storico prezzi che everydata.io ha già
Ogni lookup di prodotto effettuato tramite everydata.io salva anche il prezzo rilevato. L'endpoint dello storico prezzi restituisce queste osservazioni per gli ultimi days giorni. Conosce solo i prodotti che qualcuno ha già consultato, quindi per un prodotto mai controllato l'elenco è vuoto – il tuo file CSV resta lo storico affidabile.
resp = requests.get(
f"{API}/amz/amazon-price-history",
params={"asin": "B07ZPKN6YR", "domainCode": "com", "days": 90},
headers={"x-api-key": KEY},
timeout=60,
)
data = resp.json()
print(data["count"], "observations")
for point in data["history"]:
print(point["observedAt"], point["price"], point["inStock"]){
"responseStatus": "PRODUCT_FOUND_RESPONSE",
"responseMessage": "Product successfully found!",
"asin": "B07ZPKN6YR",
"domainCode": "com",
"days": 90,
"currency": "USD",
"count": 2,
"history": [
{
"observedAt": "2026-09-18T10:12:00Z",
"price": 39.99,
"retailPrice": 49.99,
"inStock": true
},
{
"observedAt": "2026-09-19T09:40:00Z",
"price": 34.99,
"retailPrice": 49.99,
"inStock": true
}
]
}Endpoint usati in questa guida
Product Details by ASIN · API Amazon
Price History (observations collected by this API) · API Amazon
Cos'altro puoi fare con questi dati
Amazon price tracker via API: prezzo buy box live, listino, disponibilità e storico prezzi per ASIN in JSON, 15+ marketplace. 100 chiamate gratis al mese.
Amazon Product API invece di uno scraper: titolo, marchio, prezzo, rating, immagini, punti elenco, specifiche, varianti e recensioni in JSON per URL o ASIN
Offerte del giorno e offerte lampo di Amazon in JSON: prezzo, prezzo di listino, sconto e stato per ASIN, filtrabili per reparto, sconto e valutazione.
Provalo con i tuoi dati
Il piano gratuito include 100 richieste al mese, utilizzabili su ogni piattaforma – abbastanza per seguire questa guida dall'inizio alla fine.