Les scrapers Amazon construits avec Selenium ou Puppeteer tombent constamment en panne. Les mises à jour de détection des bots, les défis CAPTCHA et les changements de mise en page signifient que vous passez plus de temps à maintenir le scraper qu'à utiliser les données. L'API Scavio fournit des données structurées sur les produits Amazon via un endpoint stable qui gère toute la complexité de l'extraction. Ce tutoriel migre une configuration typique de scraping Amazon vers des appels API, montrant l'avant-après pour la recherche de produits, la recherche ASIN et l'extraction de prix. Chaque appel API coûte 0,005 $ sans frais de proxy.
Prérequis
- Python 3.9+ installé
- bibliothèque requests installée
- Une clé API Scavio provenant de scavio.dev
- Un scraper Amazon existant à migrer (facultatif)
Parcours
Étape 1: Comparez l'ancien scraper avec l'approche API
Voyez à quoi ressemble un scraper Amazon Selenium typique par rapport à l'appel API équivalent. La version API est plus courte, plus rapide et ne tombe pas en panne.
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")}')Étape 2: Migrez la recherche ASIN vers l'API
Remplacez le scraping direct de la page ASIN par un appel API. L'API renvoie des données structurées sur le prix, la note, le nombre d'avis et la disponibilité.
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}')Étape 3: Migrez par lots plusieurs ASIN
Migrez une liste d'ASIN de votre file d'attente de scraper vers des recherches API. Ajoutez une limitation de débit pour rester dans le budget de crédits de votre forfait.
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)Exemple 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")}')Exemple 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}`));
});Sortie attendue
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