20 % de descuento en todos los planes de pago con el código

Python · Amazon

Seguimiento de precios de Amazon con Python

Los precios de Amazon cambian constantemente y nadie quiere abrir la misma página de producto cada mañana. En esta guía crearás un pequeño script que lo hace por ti: consulta el precio actual de los productos que te interesan, anota cada consulta en un archivo que se abre en cualquier hoja de cálculo y te avisa cuando un precio baja de lo que estás dispuesto a pagar.

No tienes que lidiar con la propia página de Amazon. everydata.io carga por ti la página del producto en directo y te devuelve datos limpios (título, precio, moneda, disponibilidad), así que el script es corto y no se rompe cuando Amazon cambia su diseño.

Actualizado el · por everydata.io

Lo que tendrás al final

  • Un script que consulta una lista de productos de Amazon y añade cada precio a prices.csv.
  • Un mensaje cuando un precio baja o alcanza tu objetivo.
  • Una programación diaria, para que se ejecute sin ti.

Lo que necesitas

  • Python 3.10 o posterior y el paquete requests (pip install requests).
  • Una clave de API gratuita de everydata.io: créala aquí.
  • El ASIN de cada producto: el código de 10 caracteres que va después de /dp/ en la dirección de Amazon.

01Mantén tu clave de API fuera del código

Inicia sesión, copia tu clave desde el panel y guárdala en una variable de entorno. El script la lee de ahí, así que la clave nunca acaba en un archivo que podrías compartir.

terminal
export EVERYDATA_API_KEY="ds_your_key"

02Consulta un producto

Empieza con una sola solicitud para ver qué se devuelve. El endpoint de producto por ASIN recibe el ASIN y el marketplace (com para amazon.com, de para amazon.de, etc.).

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"])

La respuesta es JSON. Cada respuesta empieza con responseStatus y responseMessage, seguidos del producto. Esta es una versión reducida del ejemplo documentado:

Respuesta de ejemplo · 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"
}

Fíjate en price en este ejemplo: es 0. Eso ocurre cuando la página no muestra un precio de compra, en este caso porque el artículo no se podía enviar a la ubicación de entrega. Tu script debe tratar 0 como «ahora mismo no hay precio», no como un producto gratis.

03Consulta una lista de productos y guarda cada resultado

Ahora convierte esa solicitud en un pequeño rastreador. WATCHLIST contiene los productos y el precio que estás esperando. Cada ejecución consulta cada producto una vez, añade una fila a prices.csv y compara el nuevo precio con el último que guardó.

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()

Ejecútalo con python3 track.py. La primera ejecución crea el archivo; las siguientes añaden una fila por producto. Puedes abrir prices.csv en cualquier programa de hojas de cálculo para dibujar un gráfico de precios.

api_get gestiona las dos respuestas con las que te encontrarás tarde o temprano. Si una página no se puede cargar, la API responde con un estado 5xx como 502 o 503; esas respuestas no cuentan para tu cuota, así que el script espera unos segundos y lo intenta una vez más. Si envías demasiadas solicitudes a la vez, la respuesta es 429 e indica cuántos segundos esperar: el script espera ese tiempo y continúa. Un producto que sigue fallando se notifica y se omite, y la siguiente ejecución lo vuelve a intentar.

04Decide cómo quieres recibir los avisos

El script imprime una línea en tres casos: la página no muestra precio, el precio está en tu objetivo o por debajo, o ha bajado desde la última consulta. Imprimir basta si lees el log. Si prefieres recibir un mensaje, sustituye las tres llamadas a print por lo que ya uses: un e-mail con smtplib de Python, un webhook de chat o un servicio de notificaciones push.

05Ejecútalo cada día

En un Mac o un equipo Linux que esté encendido, cron es el programador más sencillo. Esta línea ejecuta el rastreador cada mañana a las 7:00 y guarda un 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

En Windows, el Programador de tareas hace lo mismo. También sirve cualquier servidor pequeño o una tarea programada de CI.

Cada consulta de producto es una solicitud. Por ejemplo, tres productos consultados una vez al día son unas 90 solicitudes al mes, que caben en el plan gratuito de 100 solicitudes. Para más productos o más consultas al día, consulta los precios.

06Opcional: lee el historial de precios que ya tiene everydata.io

Cada consulta de producto hecha a través de everydata.io guarda también el precio que vio. El endpoint de historial de precios devuelve esas observaciones de los últimos days días. Solo conoce los productos que alguien ha consultado antes, así que para un producto que nadie ha consultado aún la lista está vacía: tu propio archivo CSV sigue siendo el registro fiable.

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"])
Respuesta de ejemplo · 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
    }
  ]
}

Endpoints utilizados en esta guía

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

Product Details by ASIN · API de Amazon

GET/amz/amazon-price-history

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

Todos los parámetros en la referencia de la API

Pruébalo con tus propios datos

El plan gratuito incluye 100 solicitudes al mes, utilizables en todas las plataformas: suficiente para seguir esta guía de principio a fin.