Si has seguido algún tutorial de scraping de Amazon y aun así te has chocado con una pared de CAPTCHAs, errores 503 o resultados completamente vacíos, bienvenido al club. La mayoría de las guías de Python para extraer datos de Amazon que circulan por internet se escribieron en 2022 o 2023, y usan selectores y técnicas que Amazon ya corrigió hace rato.
Llevo años construyendo herramientas de extracción de datos en Thunderbit, y hay algo que puedo decirte por experiencia: Amazon es uno de los sitios más difíciles de extraer de forma fiable. La plataforma cambia su estructura HTML constantemente, despliega una defensa antbots de seis capas e incluso muestra diseños de página diferentes a distintos usuarios mediante pruebas A/B. En esta guía te voy a mostrar un scraper de Amazon en Python que sí funciona en 2025: con selectores CSS verificados, una estrategia de bloqueo en capas y recomendaciones de programación y exportación que la mayoría de los tutoriales ni siquiera mencionan. Y para quienes solo necesitan los datos sin pelearse con Python, también te enseñaré cómo puede hacer lo mismo en apenas un par de clics.
¿Qué es el scraping de productos de Amazon?
El scraping de productos de Amazon consiste en extraer de forma programática datos públicos —nombres de productos, precios, valoraciones, número de reseñas, imágenes, disponibilidad y más— de las páginas de producto y de resultados de búsqueda de Amazon. En vez de copiar a mano información de cientos de fichas, un scraper visita cada página, lee el HTML y recoge los datos que le indiques en un formato estructurado como CSV, Excel o una base de datos.
Piénsalo como contratar a un becario incansable que puede visitar mil páginas de producto en el tiempo que tú tardas en tomarte un café. Solo que este becario nunca mete la pata con las faltas de ortografía y no necesita pausa para comer.
¿Por qué extraer productos de Amazon con Python?
Amazon alberga aproximadamente en más de 30 categorías, impulsadas por unos . Los vendedores de terceros ya representan el 69 % del GMV total. Supervisar manualmente ni siquiera una fracción de ese catálogo es imposible. Estas son algunas razones por las que los equipos extraen datos de Amazon:
| Caso de uso | Quién se beneficia | Qué extraen |
|---|---|---|
| Monitorización de precios y repricing | Operaciones ecommerce, vendedores de marketplace | Precios, disponibilidad, información del vendedor |
| Análisis de la competencia | Product managers, equipos de marca | Características del producto, valoraciones, número de reseñas |
| Investigación de mercado | Analistas, equipos de nuevos productos | Tendencias de categoría, distribución de precios |
| Generación de leads | Equipos de ventas | Nombres de vendedores, información de marca, datos de contacto |
| Marketing de afiliación | Creadores de contenido, sitios de ofertas | Precios, promociones, detalles del producto |
| Control de inventario | Cadena de suministro, compras | Estado del stock, estimaciones de entrega |
La escala de los cambios de precio en Amazon por sí sola ya hace indispensable la automatización: Amazon modifica los precios , y el precio medio de un producto cambia aproximadamente cada 10 minutos. En comparación, competidores como Best Buy y Walmart actualizan sus precios solo unas 50.000 veces al mes. Ningún equipo humano puede seguir ese ritmo.

Python te da control total sobre el proceso de scraping: tú decides qué extraer, cómo manejar los errores y dónde guardar los datos. Pero también significa que tú te encargas del mantenimiento, de las medidas anti-bloqueo y de seguir el ritmo de los frecuentes cambios HTML de Amazon.
Qué puedes extraer de Amazon y qué no
Desde páginas de producto públicas, normalmente puedes extraer:
- Título del producto (nombre, marca)
- Precio (actual, original, precio de oferta)
- Valoración (media de estrellas)
- Número de reseñas
- Imágenes del producto (URL de la imagen principal)
- Disponibilidad / estado de stock
- ASIN (Amazon Standard Identification Number)
- Descripción del producto y viñetas
- Información del vendedor
- Variaciones del producto (talla, color, etc.)
Lo que deberías evitar:
- Datos detrás de inicio de sesión: páginas de reseñas ampliadas, datos de cuentas personales, historial de pedidos
- Información personal: nombres de compradores, direcciones, datos de pago
- Contenido con copyright para republicación: las descripciones e imágenes del producto sirven para análisis, pero no las publiques como si fueran tuyas
El de Amazon bloquea más de 50 bots identificados por nombre (incluidos GPTBot, Scrapy y ClaudeBot) y prohíbe rutas como cuentas de usuario, carritos y listas de deseos. Las páginas de detalle de producto no están prohibidas explícitamente, pero los Términos de Servicio de Amazon sí vetan el acceso automatizado. Los tribunales suelen distinguir entre infracciones de los ToS (asunto civil) y violaciones penales bajo la CFAA; más sobre la legalidad al final de esta guía.
Herramientas y librerías que necesitarás
Este es el stack de Python para este tutorial:
| Librería | Propósito | Por qué la usamos |
|---|---|---|
requests | Peticiones HTTP | Sencilla y ampliamente compatible |
beautifulsoup4 | Análisis de HTML | Extracción fácil mediante selectores CSS |
lxml | Analizador HTML rápido | Backend de análisis para BeautifulSoup |
curl_cffi | Impersonación de huella TLS | Fundamental para evitar la detección de Amazon |
pandas | Estructuración y exportación de datos | DataFrames, exportación a CSV/Excel |
Opcionalmente, para contenido renderizado con JavaScript:
seleniumoplaywright— automatización de navegador sin interfaz
Configuración de tu entorno Python
Abre la terminal y ejecuta:
1mkdir amazon-scraper && cd amazon-scraper
2python -m venv venv
3source venv/bin/activate # En Windows: venv\Scripts\activate
4pip install requests beautifulsoup4 lxml curl_cffi pandas
Verifica que todo se instaló correctamente:
1import requests, bs4, curl_cffi, pandas
2print("All good!")
Si ves "All good!" sin errores, ya estás listo.

Por qué fallan la mayoría de los tutoriales de scraping de Amazon y en qué se diferencia este
Esta es la parte que la mayoría de las guías se salta, y precisamente por eso probablemente estás leyendo este artículo.
Amazon actualiza con frecuencia su estructura HTML, los nombres de clase y los IDs de los elementos. La comunidad de scraping informa que entre de los crawlers necesitan correcciones semanales por cambios en el DOM y en las huellas de navegador. ¿La víctima más famosa? El selector #priceblock_ourprice, presente en cientos de tutoriales de 2018 a 2023. Ese ID ya no existe en las páginas de producto de Amazon.
Una comparación rápida entre lo que está roto y lo que funciona ahora:
| Dato | Selector roto (antes de 2024) | Selector que funciona en 2025 |
|---|---|---|
| Precio | #priceblock_ourprice | div#corePriceDisplay_desktop_feature_div span.a-price .a-offscreen |
| Título | #productTitle | span#productTitle (sigue funcionando) |
| Valoración | span.a-icon-alt (a veces con contexto incorrecto) | #acrPopover span.a-icon-alt |
| Número de reseñas | #acrCustomerReviewCount | span#acrCustomerReviewText |
| Disponibilidad | #availability span | div#availability span.a-size-medium |
Cada fragmento de código de esta guía fue probado contra páginas reales de Amazon en 2025. Te mostraré los selectores CSS exactos junto con el resultado esperado, sin copiar y pegar nada de 2022.
Antes de empezar
- Nivel: Intermedio (se asumen conocimientos básicos de Python)
- Tiempo necesario: ~30–45 minutos para el tutorial completo; ~10 minutos para el scraper básico
- Lo que necesitarás: Python 3.9+, navegador Chrome (para inspeccionar páginas de Amazon), una terminal y, opcionalmente, la si quieres comparar el enfoque sin código
Paso 1: envía tu primera petición a Amazon
Abre cualquier página de producto de Amazon en tu navegador y copia la URL. Empezaremos con un simple requests.get():
1import requests
2url = "https://www.amazon.com/dp/B0DGNFM9YJ"
3response = requests.get(url)
4print(response.status_code)
5print(response.text[:500])
Ejecuta esto y casi con total seguridad obtendrás un código de estado 503 o una página que diga "To discuss automated access to Amazon data please contact…". Eso es el WAF (Web Application Firewall) de Amazon detectando tu script de Python. Un requests.get() básico sin encabezados adecuados logra aproximadamente una contra Amazon.
Deberías ver algo como 503 y una página de bloqueo en el HTML. Es lo esperado; lo arreglaremos en el siguiente paso.
Paso 2: configura encabezados personalizados e impersonación TLS
Añadir solo un encabezado User-Agent ya no es suficiente. Amazon compara tus encabezados HTTP con tu huella TLS. Si dices ser Chrome 120 pero el handshake TLS revela la biblioteca requests de Python, te marcarán .
El enfoque más fiable en 2025 es usar curl_cffi con impersonación de navegador:
1from curl_cffi import requests as cfreq
2headers = {
3 "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
4 "Accept-Language": "en-US,en;q=0.9",
5 "Accept-Encoding": "gzip, deflate, br",
6 "Referer": "https://www.google.com/",
7 "DNT": "1",
8 "Connection": "keep-alive",
9 "Upgrade-Insecure-Requests": "1",
10}
11url = "https://www.amazon.com/dp/B0DGNFM9YJ"
12response = cfreq.get(url, headers=headers, impersonate="chrome124")
13print(response.status_code)
14print(len(response.text))
Con curl_cffi impersonando Chrome 124, la tasa de éxito sube aproximadamente al , lo que supone una mejora de 47 veces frente a requests puro. Ahora deberías ver un código de estado 200 y una respuesta HTML mucho más larga (más de 100.000 caracteres).
Si todavía obtienes un 503, prueba otro valor de impersonate (por ejemplo, "chrome131") o añade una pequeña pausa antes de reintentar.
Paso 3: analiza el HTML y extrae los datos del producto
Ahora que tenemos el HTML completo, vamos a extraer los datos con BeautifulSoup usando selectores 2025 verificados:
1from bs4 import BeautifulSoup
2soup = BeautifulSoup(response.text, "lxml")
3# Título del producto
4title_el = soup.select_one("span#productTitle")
5title = title_el.get_text(strip=True) if title_el else None
6# Precio
7price_el = soup.select_one(
8 "div#corePriceDisplay_desktop_feature_div span.a-price .a-offscreen"
9)
10if not price_el:
11 price_el = soup.select_one("span.priceToPay .a-offscreen")
12if not price_el:
13 price_el = soup.select_one(".apexPriceToPay .a-offscreen")
14price = price_el.get_text(strip=True) if price_el else None
15# Valoración
16rating_el = soup.select_one("#acrPopover span.a-icon-alt")
17rating = rating_el.get_text(strip=True) if rating_el else None
18# Número de reseñas
19reviews_el = soup.select_one("span#acrCustomerReviewText")
20reviews = reviews_el.get_text(strip=True) if reviews_el else None
21# Disponibilidad
22avail_el = soup.select_one("div#availability span")
23availability = avail_el.get_text(strip=True) if avail_el else None
24# URL de la imagen principal
25img_el = soup.select_one("#landingImage")
26image_url = img_el.get("src") if img_el else None
27print(f"Title: {title}")
28print(f"Price: {price}")
29print(f"Rating: {rating}")
30print(f"Reviews: {reviews}")
31print(f"Availability: {availability}")
32print(f"Image: {image_url}")
Resultado esperado (ejemplo):
1Title: Apple AirPods Pro (2nd Generation) with USB-C
2Price: $189.99
3Rating: 4.7 out of 5 stars
4Reviews: 98,432 ratings
5Availability: In Stock
6Image: https://m.media-amazon.com/images/I/61SUj2...
Fíjate en los múltiples selectores alternativos para el precio: Amazon usa contenedores distintos según el tipo de producto, si hay oferta y la variante de prueba A/B. Envolver cada extracción en una comprobación condicional evita que tu scraper se rompa cuando un selector no coincida.
Paso 4: extrae varios productos desde los resultados de búsqueda
Para crear un conjunto de datos real, conviene empezar desde una página de resultados de búsqueda de Amazon, recopilar ASIN y luego extraer cada página de detalle del producto.
1import time
2import random
3def get_search_asins(keyword, max_pages=1):
4 """Recopila ASIN de los resultados de búsqueda de Amazon."""
5 asins = []
6 for page in range(1, max_pages + 1):
7 search_url = f"https://www.amazon.com/s?k={keyword}&page={page}"
8 resp = cfreq.get(search_url, headers=headers, impersonate="chrome124")
9 if resp.status_code != 200:
10 print(f"La página de búsqueda {page} devolvió {resp.status_code}")
11 break
12 search_soup = BeautifulSoup(resp.text, "lxml")
13 results = search_soup.select('div[data-component-type="s-search-result"]')
14 for r in results:
15 asin = r.get("data-asin")
16 if asin:
17 asins.append(asin)
18 print(f"Página {page}: se encontraron {len(results)} productos")
19 time.sleep(random.uniform(2, 5)) # Pausa prudente
20 return asins
21asins = get_search_asins("wireless+earbuds", max_pages=2)
22print(f"Se recopilaron {len(asins)} ASIN")
Cada ASIN corresponde a una URL de producto limpia: https://www.amazon.com/dp/{ASIN}. Esto es más fiable que usar las URL completas de resultados de búsqueda, que pueden incluir parámetros específicos de sesión.
Paso 5: gestiona la paginación y extrae a escala
Ahora combinemos la recopilación de búsqueda y el scraping de las páginas de detalle en un flujo completo:
1import pandas as pd
2def scrape_product(asin):
3 """Extrae una sola página de detalle de producto de Amazon."""
4 url = f"https://www.amazon.com/dp/{asin}"
5 try:
6 resp = cfreq.get(url, headers=headers, impersonate="chrome124")
7 if resp.status_code != 200:
8 return None
9 soup = BeautifulSoup(resp.text, "lxml")
10 title_el = soup.select_one("span#productTitle")
11 price_el = (
12 soup.select_one("div#corePriceDisplay_desktop_feature_div span.a-price .a-offscreen")
13 or soup.select_one("span.priceToPay .a-offscreen")
14 or soup.select_one(".apexPriceToPay .a-offscreen")
15 )
16 rating_el = soup.select_one("#acrPopover span.a-icon-alt")
17 reviews_el = soup.select_one("span#acrCustomerReviewText")
18 avail_el = soup.select_one("div#availability span")
19 img_el = soup.select_one("#landingImage")
20 return {
21 "asin": asin,
22 "title": title_el.get_text(strip=True) if title_el else None,
23 "price": price_el.get_text(strip=True) if price_el else None,
24 "rating": rating_el.get_text(strip=True) if rating_el else None,
25 "reviews": reviews_el.get_text(strip=True) if reviews_el else None,
26 "availability": avail_el.get_text(strip=True) if avail_el else None,
27 "image_url": img_el.get("src") if img_el else None,
28 "url": url,
29 }
30 except Exception as e:
31 print(f"Error al extraer {asin}: {e}")
32 return None
33# Extraer todos los ASIN recopilados
34products = []
35for i, asin in enumerate(asins):
36 print(f"Extrayendo {i+1}/{len(asins)}: {asin}")
37 product = scrape_product(asin)
38 if product:
39 products.append(product)
40 time.sleep(random.uniform(2, 5)) # Pausa aleatoria entre peticiones
41df = pd.DataFrame(products)
42print(f"\nSe extrajeron correctamente {len(df)} productos")
43print(df.head())
La pausa aleatoria entre 2 y 5 segundos es crucial. Un tiempo perfectamente regular (por ejemplo, exactamente 3 segundos siempre) resulta sospechoso para el análisis de comportamiento de Amazon. Los intervalos aleatorios imitan patrones de navegación humana.
Paso 6: guarda los datos extraídos de Amazon en CSV
1df.to_csv("amazon_products.csv", index=False, encoding="utf-8-sig")
2print("Guardado en amazon_products.csv")
Ahora deberías tener un CSV limpio con columnas para ASIN, título, precio, valoración, reseñas, disponibilidad, URL de imagen y URL del producto. Aquí es donde la mayoría de los tutoriales se detienen, pero si estás construyendo un flujo de trabajo real, el CSV es solo el principio.
Profundización en el anti-bloqueo: cómo mantener tu scraper en funcionamiento
Ser bloqueado es el para cualquiera que intente extraer productos de Amazon con Python. La defensa de seis capas de Amazon incluye análisis de reputación de IP, fingerprinting TLS, comprobaciones del entorno del navegador, biometría del comportamiento, CAPTCHAs y detección de anomalías impulsada por ML. Abajo tienes una estrategia por capas para afrontar cada una.
Rota User-Agents y encabezados completos
Un único User-Agent estático se detecta enseguida. Rota entre una lista de cadenas de navegador actuales:
1import random
2USER_AGENTS = [
3 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
4 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
5 "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
6 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15",
7]
8def get_headers():
9 return {
10 "User-Agent": random.choice(USER_AGENTS),
11 "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
12 "Accept-Language": "en-US,en;q=0.9",
13 "Accept-Encoding": "gzip, deflate, br",
14 "Referer": "https://www.google.com/",
15 "DNT": "1",
16 "Connection": "keep-alive",
17 }
Un detalle que suele pasar desapercibido: tu Accept-Language debe coincidir con la ubicación geográfica sugerida por tu IP. Enviar Accept-Language: en-US desde una IP alemana es una señal de alerta.
Impersonación de huella TLS con curl_cffi
Ya lo vimos en el Paso 2, pero conviene insistir: esta técnica por sí sola aporta la mayor mejora en la tasa de éxito. La librería estándar de Python requests logra solo alrededor del 2 % de éxito contra Amazon. Con la impersonación de curl_cffi, subes a aproximadamente un 94 %. Esa es la diferencia entre un scraper funcional y uno roto.
1from curl_cffi import requests as cfreq
2# También rota los objetivos de impersonación
3BROWSERS = ["chrome120", "chrome124", "chrome131"]
4response = cfreq.get(
5 url,
6 headers=get_headers(),
7 impersonate=random.choice(BROWSERS),
8)
Rotación de proxies
Si vas a extraer más que unas pocas páginas, necesitarás rotación de proxies. Amazon rastrea las direcciones IP y bloqueará cualquier IP que envíe demasiadas solicitudes.
1PROXIES = [
2 "http://user:pass@proxy1.example.com:8080",
3 "http://user:pass@proxy2.example.com:8080",
4 "http://user:pass@proxy3.example.com:8080",
5]
6proxy = random.choice(PROXIES)
7response = cfreq.get(
8 url,
9 headers=get_headers(),
10 impersonate="chrome124",
11 proxies={"http": proxy, "https": proxy},
12)
Los proxies residenciales son más eficaces que los de centros de datos (Amazon bloquea de forma preventiva rangos de IP de datacenter), pero también son más caros. Para un proyecto pequeño, puedes empezar con un y escalar según necesites.
Limitación de ritmo y backoff exponencial
Ningún artículo de la competencia que he encontrado cubre esto, pero es esencial. Cuando recibas un 503 o una respuesta de CAPTCHA, no vuelvas a intentarlo de inmediato: ese es el camino rápido hacia un bloqueo permanente.
1import time
2import random
3def fetch_with_backoff(url, max_retries=3):
4 """Obtiene una URL con backoff exponencial si falla."""
5 for attempt in range(max_retries):
6 response = cfreq.get(
7 url,
8 headers=get_headers(),
9 impersonate=random.choice(BROWSERS),
10 )
11 if response.status_code == 200:
12 return response
13 # Backoff exponencial con jitter
14 wait = min(2 ** attempt + random.uniform(0, 1), 30)
15 print(f"El intento {attempt+1} falló ({response.status_code}). Esperando {wait:.1f}s...")
16 time.sleep(wait)
17 return None # Se agotaron todos los reintentos
La fórmula wait = min(2^attempt + jitter, max_delay) hace que tus pausas crezcan (2s, 4s, 8s...) pero sin superar un límite razonable. El jitter aleatorio evita que tu patrón de reintentos sea identificado por fingerprinting.
Fallback con Selenium o Playwright para contenido renderizado con JS
Algunas páginas de Amazon —especialmente las que tienen widgets dinámicos de precios o selectores de variantes— necesitan JavaScript para renderizarse por completo. Cuando curl_cffi devuelve HTML incompleto, un navegador sin interfaz es tu plan B:
1from playwright.sync_api import sync_playwright
2def scrape_with_browser(url):
3 with sync_playwright() as p:
4 browser = p.chromium.launch(headless=True)
5 page = browser.new_page()
6 page.goto(url, wait_until="domcontentloaded")
7 page.wait_for_timeout(3000) # Deja que JS termine de renderizar
8 html = page.content()
9 browser.close()
10 return html
Esto es más lento: 3–5 segundos por página frente a menos de 1 segundo con curl_cffi. Úsalo solo cuando sea necesario.
En mi experiencia, curl_cffi cubre más del 90 % de las páginas de producto de Amazon sin navegador.
Resumen anti-bloqueo
| Técnica | Dificultad | Eficacia | ¿La cubren la mayoría de los tutoriales? |
|---|---|---|---|
| User-Agent personalizado | Fácil | Baja (Amazon detecta patrones) | Sí |
| Rotación completa de encabezados | Fácil | Media | Rara vez |
| Impersonación TLS (curl_cffi) | Media | Alta (~94 % de éxito) | Casi nunca |
| Rotación de proxies | Media | Alta | Apenas, si acaso |
| Limitación de ritmo + backoff exponencial | Fácil | Media | No |
| Fallback con Selenium/Playwright | Media | Alta (para contenido JS) | Se menciona, pero no se demuestra |
Más allá del CSV: exporta datos de Amazon a Google Sheets, Airtable y más
Todos los tutoriales que revisé se detienen en la exportación a CSV. Pero los flujos de trabajo empresariales reales necesitan los datos en Google Sheets, bases de datos o herramientas como Airtable y Notion.
Exportar a Google Sheets con gspread
Primero, configura una cuenta de servicio de Google (solo una vez):
- Ve a → APIs & Services → Credentials
- Crea una cuenta de servicio y descarga el archivo JSON de clave
- Guárdalo en
~/.config/gspread/service_account.json - Comparte la hoja de cálculo destino con el
client_emaildel archivo JSON
Después:
1import gspread
2from gspread_dataframe import set_with_dataframe
3gc = gspread.service_account()
4sh = gc.open("Amazon Scrape Data")
5worksheet = sh.sheet1
6set_with_dataframe(worksheet, df)
7print("Datos exportados a Google Sheets!")
Esto escribe todo tu DataFrame directamente en una hoja de Google: en vivo, compartible y listo para paneles de control.
Guardar en SQLite para análisis local
Para conjuntos de datos más grandes o seguimiento histórico, SQLite es perfecto: sin configuración de servidor, solo un archivo:
1import sqlite3
2conn = sqlite3.connect("amazon_products.db")
3df.to_sql("products", conn, if_exists="append", index=False)
4print(f"Se almacenaron {len(df)} productos en SQLite")
5# Consultar más tarde:
6historical = pd.read_sql_query(
7 "SELECT * FROM products WHERE price IS NOT NULL ORDER BY rowid DESC LIMIT 100",
8 conn,
9)
La alternativa sin código
Si no quieres mantener scripts de exportación en Python, ofrece exportación gratuita a Google Sheets, Airtable, Notion, Excel, CSV y JSON, incluidos campos de imagen que se renderizan directamente en Airtable y Notion. Sin configurar gspread, sin credenciales de API, sin escribir código. Para equipos que necesitan que los datos fluyan hacia sus herramientas habituales, supone un ahorro de tiempo considerable.
Programar extracciones automáticas de Amazon: el capítulo que faltaba
La monitorización de precios y el control de inventario requieren extracciones recurrentes, no ejecuciones puntuales. Sin embargo, no he encontrado ni un solo artículo de la competencia que cubra la programación. Aquí te explico cómo automatizar tu scraper en Python.
Cron Jobs (Linux/macOS)
Abre tu crontab:
1crontab -e
Añade una línea para ejecutar tu scraper a diario a las 6 AM:
10 6 * * * cd /path/to/amazon-scraper && /path/to/venv/bin/python scraper.py >> ~/scraper.log 2>&1
O cada 6 horas:
10 */6 * * * cd /path/to/amazon-scraper && /path/to/venv/bin/python scraper.py >> ~/scraper.log 2>&1
Programador de tareas de Windows
Crea un archivo batch run_scraper.bat:
1@echo off
2cd /d "C:\path\to\amazon-scraper"
3call venv\Scripts\activate
4python scraper.py
5deactivate
Después abre Task Scheduler → Create Basic Task → define el desencadenador (Daily, Hourly) → Action: "Start a program" → busca run_scraper.bat.
GitHub Actions (gratis)
Para una programación en la nube sin infraestructura:
1name: Amazon Scraper
2on:
3 schedule:
4 - cron: "0 6 * * *" # Diario a las 6 AM UTC
5 workflow_dispatch: # Ejecución manual
6jobs:
7 scrape:
8 runs-on: ubuntu-latest
9 steps:
10 - uses: actions/checkout@v3
11 - name: Set up Python
12 uses: actions/setup-python@v4
13 with:
14 python-version: "3.11"
15 - name: Install dependencies
16 run: pip install -r requirements.txt
17 - name: Run scraper
18 run: python scraper.py
19 - name: Commit results
20 run: |
21 git config user.name 'GitHub Actions'
22 git config user.email 'actions@github.com'
23 git add data/
24 git diff --staged --quiet || git commit -m "Update scraped data"
25 git push
Guarda las credenciales de los proxies en GitHub Secrets y tendrás un flujo de scraping automático y gratuito.
Alternativa sin código: Scheduled Scraper de Thunderbit
Para equipos que no quieren gestionar la sintaxis de cron ni infraestructuras en la nube, Thunderbit ofrece un integrado. Describes el horario en lenguaje natural (por ejemplo, "cada día a las 8 AM" o "todos los lunes"), añades las URL de Amazon y haces clic en "Schedule". Sin terminal, sin archivos YAML, sin pipeline de despliegue. Es especialmente útil para equipos de ecommerce que realizan monitorización continua de precios o inventario.
Python por tu cuenta vs. API de scraping vs. sin código: ¿qué enfoque deberías usar?
Esta es una pregunta que veo constantemente en foros, y ningún artículo bien posicionado ofrece una respuesta estructurada. Así que aquí va mi opinión honesta:
| Criterio | Python + BS4/curl_cffi | API de scraping (ScraperAPI, Oxylabs) | Sin código (Thunderbit) |
|---|---|---|---|
| Tiempo de configuración | 30–60 min | 10–20 min | ~2 minutos |
| Requiere programar | Sí (Python) | Sí (llamadas API) | No |
| Anti-bloqueo integrado | No (hecho por ti) | Sí | Sí |
| Gestiona renderizado JS | Solo con Selenium/Playwright | Depende del proveedor | Sí (modo navegador o nube) |
| Programación | Hecho por ti (cron/nube) | Algunos lo ofrecen | Integrado |
| Coste | Gratis (+ costes de proxy) | 30–100 USD+/mes | Hay plan gratuito |
| Mantenimiento | Alto (se rompen los selectores) | Bajo | Ninguno (la IA se adapta) |
| Ideal para | Desarrolladores que quieren control total | Escala y fiabilidad a gran volumen | Rapidez, usuarios no técnicos, equipos de negocio |
Python es la mejor opción si quieres aprender, personalizar cada detalle y no te importa el mantenimiento continuo. Las APIs de scraping resuelven el anti-bloqueo por ti, pero sigues necesitando código. Y Thunderbit es la vía más rápida para ventas, operaciones ecommerce o cualquiera que solo necesite los datos: sin selectores, sin código y sin mantenimiento cuando Amazon cambie su HTML.
Cómo Thunderbit extrae productos de Amazon en 2 clics
Soy parcial, claro: mi equipo construyó esto. Pero el flujo de trabajo realmente es así de simple:
- Instala la
- Abre una página de resultados de búsqueda o una página de producto de Amazon
- Haz clic en "AI Suggest Fields" (o usa la plantilla instantánea de Amazon)
- Haz clic en "Scrape"
La IA de Thunderbit lee la página, identifica la estructura de datos y extrae todo en una tabla limpia. Puedes exportar a Excel, Google Sheets, Airtable o Notion gratis. La verdadera ventaja: cuando Amazon cambie su HTML la semana que viene (y lo hará), la IA de Thunderbit se adapta automáticamente. Sin scripts rotos, sin actualizar selectores.
Para enriquecer listas de productos con datos de páginas de detalle, la función Subpage Scraping de Thunderbit sigue automáticamente los enlaces a las páginas de producto y extrae campos adicionales como imágenes, descripciones y variaciones, algo que en Python requiere bastante código extra.
Consejos para que tu scraper de Amazon en Python funcione a largo plazo
Si te inclinas por Python, aquí tienes cómo reducir al mínimo los dolores de mantenimiento:
- Revisa los selectores con regularidad. Amazon los cambia a menudo. Guarda esta guía en favoritos: actualizaré la tabla de selectores a medida que cambien las cosas.
- Supervisa tu tasa de éxito. Controla la proporción de respuestas 200 frente a 503/CAPTCHAs. Configura una alerta (aunque sea un correo simple) cuando tu tasa de éxito baje del 80 %.
- Almacena el HTML original. Guarda la respuesta HTML completa junto con los datos analizados. Si cambian los selectores, podrás volver a procesar los datos históricos sin extraerlos otra vez.
- Rota proxies y User-Agents con frecuencia. Las huellas estáticas se detectan en cuestión de horas cuando trabajas a escala.
- Usa backoff exponencial. Nunca reintentes inmediatamente después de un bloqueo.
- Conteneriza con Docker. Empaqueta tu scraper en un contenedor Docker para facilitar el despliegue y la portabilidad.
- Añade validación de datos. Comprueba que los precios sean numéricos, que las valoraciones estén entre 1 y 5 y que los títulos no estén vacíos. Un equipo informó de una tras añadir capas de validación.
O, si todo eso te parece más trabajo del que querías asumir, valora si una herramienta sin código como Thunderbit encaja mejor con tu caso. No hay nada de malo en elegir el camino más rápido: he pasado suficientes años depurando scrapers como para saber que, a veces, el mejor código es el que no tienes que escribir.
Consideraciones legales y éticas al extraer datos de Amazon
Como este tema aparece en todas las conversaciones sobre scraping de Amazon, aquí va una nota rápida sobre el panorama legal:
- El scraping de datos públicos suele ser legal en EE. UU. La histórica sentencia (2022) estableció que acceder a datos públicos no viola la CFAA. Más recientemente, (2024) y (2024) reforzaron este principio.
- Los ToS de Amazon prohíben el acceso automatizado. Esto es un asunto civil (incumplimiento de contrato), no penal. Los tribunales suelen diferenciar entre ambos.
- Amazon v. Perplexity (2025) es un caso activo relacionado con scraping con IA de páginas de Amazon. En marzo de 2026 se emitió una orden judicial preliminar. Conviene seguirlo de cerca.
- Quédate en páginas públicas. No extraigas contenido protegido por inicio de sesión, datos personales ni nada que requiera autenticación.
- Respeta los límites de frecuencia. No bombardees los servidores de Amazon. Un retraso de 2 a 5 segundos entre peticiones es razonable.
- Usa los datos de forma responsable. Extrae para análisis, no para republicar contenido protegido por copyright.
- Consulta a un asesor legal para usos comerciales a gran escala, especialmente si estás en la UE (el RGPD aplica a los datos personales).
Para una visión más profunda, consulta nuestra guía sobre .
Conclusión
Ahora ya tienes un scraper de Amazon en Python que funciona, con selectores 2025 verificados, una estrategia anti-bloqueo en capas que va mucho más allá de "añadir un User-Agent", opciones prácticas de programación para monitorización continua y métodos de exportación que llevan tus datos a Google Sheets, bases de datos o cualquier herramienta que use tu equipo.
Resumen rápido:
- Python + curl_cffi + BeautifulSoup te da control total y una tasa de éxito cercana al 94 % cuando se combina con impersonación TLS
- El anti-bloqueo requiere varias capas: rotación de encabezados, impersonación TLS, rotación de proxies, limitación de ritmo y backoff exponencial
- La programación convierte un script puntual en un pipeline de monitorización continua (cron, GitHub Actions o el programador integrado de Thunderbit)
- Exportar más allá de CSV —Google Sheets, SQLite, Airtable, Notion— es donde realmente está el valor para el negocio
- Thunderbit ofrece una alternativa en 2 clics para quienes no programan o para cualquiera que prefiera dedicar su tiempo a analizar datos en lugar de depurar selectores
Si quieres probar el código, todo lo que aparece en esta guía está listo para copiar y ejecutar. Y si prefieres evitar la parte de programación por completo, el te permite probar de inmediato el enfoque sin código en Amazon.
Para más información, consulta nuestras guías sobre , y . También puedes ver tutoriales paso a paso en el .
Feliz scraping, y que tus selectores sobrevivan hasta la próxima actualización de Amazon.
Preguntas frecuentes
1. ¿Por qué mi scraper de Amazon en Python se bloquea después de unas pocas peticiones?
Amazon utiliza un sistema de defensa de seis capas: análisis de reputación de IP, fingerprinting TLS (JA3/JA4), detección del entorno del navegador, biometría del comportamiento, desafíos CAPTCHA y detección de anomalías mediante ML. Un script básico con requests y solo un encabezado User-Agent consigue apenas alrededor de un de éxito. Necesitas impersonación TLS (curl_cffi), rotación completa de encabezados, rotación de proxies y limitación de ritmo con jitter aleatorio para mantener un acceso fiable.
2. ¿Qué librerías de Python son mejores para extraer productos de Amazon en 2025?
curl_cffi para peticiones HTTP con impersonación TLS (la mayor mejora individual), BeautifulSoup4 con lxml para análisis de HTML, pandas para estructurar y exportar datos, y Selenium o Playwright como respaldo para contenido renderizado con JavaScript. Python lo usa el de los desarrolladores de scraping.
3. ¿Es legal extraer datos de productos de Amazon?
Extraer datos públicos suele ser legal en EE. UU., respaldado por fallos como hiQ v. LinkedIn y Meta v. Bright Data. Los Términos de Servicio de Amazon prohíben el acceso automatizado, pero los tribunales distinguen entre infracciones de los ToS (civiles) y violaciones penales. Evita siempre el contenido protegido por inicio de sesión, respeta los límites de frecuencia y consulta a un abogado si vas a hacer uso comercial a gran escala.
4. ¿Puedo extraer datos de Amazon sin escribir código?
Sí. Herramientas como te permiten extraer productos de Amazon en 2 clics con una extensión de Chrome. Su detección de campos con IA estructura automáticamente los datos, y puedes exportarlos gratis a Excel, Google Sheets, Airtable o Notion. Cuando Amazon cambie su HTML, la IA de Thunderbit se adaptará sin que tengas que actualizar nada manualmente.
5. ¿Con qué frecuencia cambia Amazon sus selectores HTML y cómo mantengo actualizado mi scraper?
Con frecuencia y sin aviso. La comunidad de scraping informa que de los crawlers necesitan correcciones semanales por cambios en el DOM. Para ir por delante, supervisa la tasa de éxito de tu scraper, guarda el HTML original para reprocesarlo y comprueba los selectores contra páginas reales con regularidad. Como alternativa, las herramientas impulsadas por IA como Thunderbit se adaptan automáticamente, eliminando esa carga de mantenimiento.
Más información