Los raspadores de Amazon construidos con Selenium o Puppeteer se rompen constantemente. Las actualizaciones de detección de bots, los desafíos de CAPTCHA y los cambios de diseño significan que usted dedica más tiempo a mantener el raspador que a usar los datos. La API de Scavio proporciona datos estructurados de productos de Amazon a través de un punto final estable que maneja toda la complejidad de la extracción. Este tutorial migra una configuración típica de raspado de Amazon a llamadas API y muestra el antes y el después de la búsqueda de productos, la búsqueda de ASIN y la extracción de precios. Cada llamada API cuesta $0,005 sin costos de proxy.
Requisitos previos
- Python 3.9+ instalado
- solicita biblioteca instalada
- Una clave API de Scavio de scavio.dev
- Un raspador de Amazon existente para migrar (opcional)
Guia paso a paso
Paso 1: Compare el antiguo enfoque de raspador con el de API
Vea cómo se ve un raspador típico de Selenium Amazon en comparación con la llamada API equivalente. La versión API es más corta, más rápida y no se rompe.
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
URL = 'https://api.scavio.dev/api/v1/search'
# OLD: Selenium scraper (30+ lines, breaks monthly)
# from selenium import webdriver
# driver = webdriver.Chrome()
# driver.get(f'https://amazon.com/s?k={query}')
# time.sleep(3) # Wait for page load
# products = driver.find_elements(By.CSS_SELECTOR, '[data-component-type="s-search-result"]')
# ... parse each product, handle pagination, CAPTCHAs, etc.
# NEW: API call (5 lines, stable)
def search_amazon(query: str, num: int = 5) -> list:
resp = requests.post(URL, headers=H,
json={'platform': 'amazon', 'query': query, 'marketplace': 'US', 'num_results': num})
resp.raise_for_status()
return resp.json().get('products', resp.json().get('organic_results', []))
results = search_amazon('wireless earbuds')
print(f'Found {len(results)} products')
for r in results[:3]:
print(f' {r.get("title", "")[:60]}')
print(f' Price: {r.get("price", "N/A")} | Rating: {r.get("rating", "N/A")}')Paso 2: Migrar la búsqueda de ASIN a API
Reemplace el raspado directo de páginas ASIN con una llamada API. La API devuelve precios estructurados, calificaciones, recuento de reseñas y datos de disponibilidad.
def lookup_asin(asin: str) -> dict:
"""Look up a specific ASIN's product data."""
resp = requests.post(URL, headers=H,
json={'platform': 'amazon', 'query': asin, 'marketplace': 'US'})
resp.raise_for_status()
data = resp.json()
product = data.get('product', data)
return {
'asin': asin,
'title': product.get('title', ''),
'price': product.get('price', ''),
'rating': product.get('rating', ''),
'reviews': product.get('reviews_count', 0),
'availability': product.get('availability', ''),
}
product = lookup_asin('B09G9FPHY6')
for k, v in product.items():
print(f' {k}: {v}')Paso 3: Migrar por lotes varios ASIN
Migre una lista de ASIN de su cola de raspado a búsquedas de API. Agregue un límite de tasa para mantenerse dentro del presupuesto de crédito de su plan.
import time
def batch_lookup(asins: list, delay: float = 0.3) -> list:
results = []
for asin in asins:
try:
product = lookup_asin(asin)
results.append(product)
print(f'[OK] {asin}: {product["price"]} - {product["title"][:40]}')
except Exception as e:
print(f'[ERR] {asin}: {e}')
results.append({'asin': asin, 'error': str(e)})
time.sleep(delay)
success = sum(1 for r in results if 'error' not in r)
print(f'\nBatch complete: {success}/{len(asins)} succeeded')
print(f'Cost: ${len(asins) * 0.005:.3f}')
return results
asins = ['B09G9FPHY6', 'B07FZ8S74R', 'B08N5WRWNW']
batch_lookup(asins)Ejemplo en Python
import os, requests, time
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
def search_amazon(query, num=5):
resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'platform': 'amazon', 'query': query, 'marketplace': 'US', 'num_results': num})
return resp.json().get('products', resp.json().get('organic_results', []))
def lookup_asin(asin):
resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'platform': 'amazon', 'query': asin, 'marketplace': 'US'})
return resp.json().get('product', resp.json())
results = search_amazon('wireless earbuds')
print(f'{len(results)} products found')
for r in results[:3]:
print(f' {r.get("title", "")[:50]} | {r.get("price", "N/A")}')Ejemplo en JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
async function searchAmazon(query) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ platform: 'amazon', query, marketplace: 'US', num_results: 5 })
});
const data = await resp.json();
return data.products || data.organic_results || [];
}
async function lookupAsin(asin) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ platform: 'amazon', query: asin, marketplace: 'US' })
});
return (await resp.json()).product || {};
}
searchAmazon('wireless earbuds').then(r => {
r.slice(0, 3).forEach(p => console.log(`${p.title?.slice(0, 50)} | ${p.price}`));
});Salida esperada
Found 5 products
Sony WF-1000XM5 Truly Wireless Noise Cancelling Ea
Price: $248.00 | Rating: 4.6
Apple AirPods Pro 2nd Generation with USB-C
Price: $189.99 | Rating: 4.7
Samsung Galaxy Buds3 Pro
Price: $159.99 | Rating: 4.4
[OK] B09G9FPHY6: $29.99 - Echo Dot (5th Gen) | Smart speaker
[OK] B07FZ8S74R: $24.99 - Fire TV Stick 4K with Alexa Voice
[OK] B08N5WRWNW: $89.99 - Kindle Paperwhite (11th Generatio
Batch complete: 3/3 succeeded
Cost: $0.015