20 % Rabatt auf alle kostenpflichtigen Tarife mit dem Code

Python · Amazon

Amazon-Preise mit Python verfolgen

Preise auf Amazon ändern sich ständig, und niemand möchte jeden Morgen dieselbe Produktseite öffnen. In dieser Anleitung bauen Sie ein kleines Skript, das das für Sie übernimmt: Es fragt den aktuellen Preis der Produkte ab, die Sie interessieren, schreibt jede Prüfung in eine tabellentaugliche Datei und meldet sich, wenn ein Preis unter den Betrag fällt, den Sie zu zahlen bereit sind.

Mit der Amazon-Seite selbst müssen Sie sich nicht befassen. everydata.io lädt die Live-Produktseite für Sie und schickt saubere Daten zurück – Titel, Preis, Währung, Verfügbarkeit –, sodass das Skript kurz bleibt und nicht kaputtgeht, wenn Amazon sein Layout ändert.

Aktualisiert am · von everydata.io

Was Sie am Ende haben

  • Ein Skript, das eine Liste von Amazon-Produkten prüft und jeden Preis an prices.csv anhängt.
  • Eine Meldung, wenn ein Preis fällt oder Ihren Zielpreis erreicht.
  • Ein täglicher Zeitplan, damit es ohne Ihr Zutun läuft.

Was Sie brauchen

  • Python 3.10 oder neuer und das Paket requests (pip install requests).
  • Ein kostenloser everydata.io-API-Schlüssel – hier anlegen.
  • Die ASIN jedes Produkts: der 10-stellige Code nach /dp/ in der Amazon-Adresse.

01Den API-Schlüssel aus dem Code heraushalten

Melden Sie sich an, kopieren Sie Ihren Schlüssel aus dem Dashboard und legen Sie ihn in einer Umgebungsvariablen ab. Das Skript liest ihn von dort, sodass der Schlüssel nie in einer Datei landet, die Sie vielleicht weitergeben.

terminal
export EVERYDATA_API_KEY="ds_your_key"

02Ein Produkt abfragen

Beginnen Sie mit einer einzelnen Anfrage, damit Sie sehen, was zurückkommt. Der Product-by-ASIN-Endpoint nimmt die ASIN und den Marktplatz entgegen (com für amazon.com, de für amazon.de und so weiter).

first_request.py
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"])

Die Antwort ist JSON. Jede Antwort beginnt mit responseStatus und responseMessage, gefolgt vom Produkt. Hier eine gekürzte Fassung des dokumentierten Beispiels:

Beispielantwort · GET /amz/amazon-lookup-product-by-asin
{
  "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"
}

Sehen Sie sich price in diesem Beispiel an: Der Wert ist 0. Das passiert, wenn die Seite keinen kaufbaren Preis zeigt – hier, weil der Artikel nicht an den Lieferort versendet werden konnte. Ihr Skript sollte 0 als „derzeit kein Preis“ werten, nicht als kostenloses Produkt.

03Eine Produktliste prüfen und jedes Ergebnis speichern

Machen Sie jetzt aus der einzelnen Anfrage einen kleinen Tracker. WATCHLIST enthält die Produkte und den Preis, auf den Sie warten. Jeder Lauf fragt jedes Produkt einmal ab, hängt eine Zeile an prices.csv an und vergleicht den neuen Preis mit dem zuletzt gespeicherten.

track.py
"""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()

Starten Sie es mit python3 track.py. Der erste Lauf legt die Datei an; spätere Läufe ergänzen eine Zeile pro Produkt. Sie können prices.csv in jedem Tabellenprogramm öffnen und einen Preisverlauf zeichnen.

api_get behandelt die zwei Antworten, auf die Sie früher oder später stoßen. Kann eine Seite nicht geladen werden, antwortet die API mit einem 5xx-Status wie 502 oder 503; diese Antworten werden nicht auf Ihr Kontingent angerechnet, daher wartet das Skript ein paar Sekunden und versucht es noch einmal. Senden Sie zu viele Anfragen auf einmal, lautet die Antwort 429 und nennt die Wartezeit in Sekunden – das Skript wartet so lange und macht weiter. Ein Produkt, das weiterhin fehlschlägt, wird gemeldet und übersprungen, und der nächste Lauf fragt es erneut ab.

04Festlegen, wie Sie benachrichtigt werden

Das Skript gibt in drei Fällen eine Zeile aus: Die Seite zeigt keinen Preis, der Preis liegt bei oder unter Ihrem Zielpreis, oder er ist seit der letzten Prüfung gefallen. Die Ausgabe genügt, wenn Sie das Log lesen. Möchten Sie lieber eine Nachricht erhalten, ersetzen Sie die drei print-Aufrufe durch das, was Sie ohnehin nutzen – eine E-Mail über Pythons smtplib, einen Chat-Webhook oder einen Push-Dienst.

05Täglich ausführen

Auf einem eingeschalteten Mac- oder Linux-Rechner ist cron der einfachste Scheduler. Diese Zeile startet den Tracker jeden Morgen um 7:00 Uhr und schreibt ein Log:

crontab
# 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>&1

Unter Windows übernimmt die Aufgabenplanung dieselbe Aufgabe. Jeder kleine Server oder ein zeitgesteuerter CI-Job funktioniert ebenfalls.

Jede Produktprüfung ist eine Anfrage. Ein Beispiel: Drei Produkte, einmal täglich geprüft, ergeben rund 90 Anfragen im Monat – das passt in den kostenlosen Tarif mit 100 Anfragen. Für mehr Produkte oder mehr Prüfungen pro Tag siehe Preise.

06Optional: den Preisverlauf lesen, den everydata.io bereits hat

Jede Produktabfrage über everydata.io speichert auch den gesehenen Preis. Der Preisverlaufs-Endpoint liefert diese Beobachtungen für die letzten days Tage. Er kennt nur Produkte, die schon einmal jemand abgefragt hat; für ein Produkt, das noch niemand geprüft hat, ist die Liste leer – Ihre eigene CSV-Datei bleibt die verlässliche Aufzeichnung.

history.py
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"])
Beispielantwort · GET /amz/amazon-price-history
{
  "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
    }
  ]
}

In dieser Anleitung verwendete Endpoints

GET/amz/amazon-lookup-product-by-asin

Product Details by ASIN · Amazon API

GET/amz/amazon-price-history

Price History (observations collected by this API) · Amazon API

Alle Parameter in der API-Referenz

Probieren Sie es mit Ihren eigenen Daten

Der kostenlose Tarif enthält 100 Anfragen pro Monat, nutzbar auf jeder Plattform – genug, um diese Anleitung vollständig durchzuspielen.