La surveillance cross-platforme du e-commerce suit vos produits (ou ceux de vos concurrents) sur Amazon, Google Shopping et les résultats de recherche organique simultanément. Cela est essentiel pour le respect des prix imposés, la détection des violations de MAP et la veille concurrentielle. Au lieu de construire des scrappeurs séparés par plateforme, l'API Scavio gère Amazon et Google Shopping via un seul point d'accès. Ce tutoriel construit un pipeline de surveillance qui vérifie les produits sur plusieurs plateformes, détecte les écarts de prix et génère des alertes. Chaque vérification de plateforme coûte 0,005 $.
Prérequis
- Python 3.9+ installé
- Bibliothèque requests installée
- Une clé API Scavio depuis scavio.dev
- Noms de produits ou ASINs à surveiller
Parcours
Étape 1: Définir la liste de produits à surveiller
Créez une liste structurée de produits à surveiller avec des identifiants pour chaque plateforme. Incluez votre MAP (prix minimum annoncé) le cas échéant.
products = [
{
'name': 'Sony WH-1000XM5 Headphones',
'search_query': 'Sony WH-1000XM5',
'map_price': 299.99, # minimum advertised price
'brand': 'Sony'
},
{
'name': 'Apple AirPods Pro 2',
'search_query': 'Apple AirPods Pro 2nd generation',
'map_price': 249.00,
'brand': 'Apple'
},
{
'name': 'Bose QuietComfort Ultra',
'search_query': 'Bose QuietComfort Ultra headphones',
'map_price': 429.00,
'brand': 'Bose'
}
]
print(f'Monitoring {len(products)} products across 2 platforms')
print(f'Cost per full check: ${len(products) * 2 * 0.005:.2f}')Étape 2: Rechercher sur Amazon et Google Shopping pour chaque produit
Interrogez les deux plateformes pour chaque produit et normalisez les résultats dans un format commun avec le prix, le vendeur, la note et la disponibilité.
import requests, os, re
API_KEY = os.environ['SCAVIO_API_KEY']
ENDPOINT = 'https://api.scavio.dev/api/v1/search'
def parse_price(p) -> float:
if not p: return 0.0
try: return float(re.sub(r'[^0-9.]', '', str(p)))
except: return 0.0
def check_amazon(query: str) -> list:
resp = requests.post(ENDPOINT,
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'platform': 'amazon', 'query': query, 'marketplace': 'US'})
return [{'platform': 'amazon', 'title': p.get('title', ''),
'price': parse_price(p.get('price')), 'rating': p.get('rating', 0),
'reviews': p.get('reviews_count', 0), 'link': p.get('link', '')}
for p in resp.json().get('products', []) if parse_price(p.get('price')) > 0]
def check_google_shopping(query: str) -> list:
resp = requests.post(ENDPOINT,
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us', 'type': 'shopping'})
return [{'platform': 'google_shopping', 'title': p.get('title', ''),
'price': parse_price(p.get('price')), 'seller': p.get('source', ''),
'link': p.get('link', '')}
for p in resp.json().get('shopping_results', []) if parse_price(p.get('price')) > 0]Étape 3: Détecter les violations de MAP et les anomalies de prix
Comparez les prix par rapport au prix minimum annoncé. Signalez toute annonce qui vend en dessous du MAP ou qui présente un modèle de prix suspect.
def check_map_violations(listings: list, map_price: float) -> list:
violations = []
for listing in listings:
if listing['price'] < map_price:
discount_pct = ((map_price - listing['price']) / map_price) * 100
violations.append({
'platform': listing['platform'],
'title': listing['title'][:60],
'price': listing['price'],
'map_price': map_price,
'discount': round(discount_pct, 1),
'link': listing['link']
})
return violations
def find_price_range(listings: list) -> dict:
prices = [l['price'] for l in listings if l['price'] > 0]
if not prices:
return {'min': 0, 'max': 0, 'spread': 0}
return {
'min': min(prices),
'max': max(prices),
'spread': round(max(prices) - min(prices), 2),
'avg': round(sum(prices) / len(prices), 2)
}Étape 4: Générer le rapport cross-platforme
Combinez les données de toutes les plateformes en un rapport unifié de santé des produits avec comparaison des prix et alertes de violation de MAP.
import time
from datetime import date
def monitor_product(product: dict) -> dict:
query = product['search_query']
amazon = check_amazon(query)
google = check_google_shopping(query)
all_listings = amazon + google
violations = check_map_violations(all_listings, product['map_price'])
price_range = find_price_range(all_listings)
return {
'product': product['name'],
'map_price': product['map_price'],
'amazon_listings': len(amazon),
'google_listings': len(google),
'total_listings': len(all_listings),
'price_range': price_range,
'map_violations': violations,
'violation_count': len(violations)
}
def full_monitor(products: list) -> list:
reports = []
for product in products:
report = monitor_product(product)
reports.append(report)
status = 'VIOLATION' if report['violation_count'] > 0 else 'OK'
print(f'[{status}] {report["product"]}: '
f'${report["price_range"]["min"]}-${report["price_range"]["max"]} '
f'({report["total_listings"]} listings, {report["violation_count"]} violations)')
time.sleep(0.3)
cost = len(products) * 2 * 0.005
print(f'\nTotal cost: ${cost:.2f} ({len(products) * 2} credits)')
return reports
reports = full_monitor(products)Étape 5: Planifier et alerter en cas de violations
Exécutez le moniteur selon un planning et envoyez des alertes lorsque des violations de MAP ou des changements de prix significatifs sont détectés.
import json
def save_and_alert(reports: list) -> None:
# Save report
filename = f'ecommerce_monitor_{date.today()}.json'
with open(filename, 'w') as f:
json.dump({'date': date.today().isoformat(), 'reports': reports}, f, indent=2)
# Check for alerts
violations = [r for r in reports if r['violation_count'] > 0]
if violations:
print(f'\nALERT: {len(violations)} products with MAP violations:')
for r in violations:
for v in r['map_violations']:
print(f' {r["product"]} on {v["platform"]}: '
f'${v["price"]} (MAP: ${v["map_price"]}, -{v["discount"]}%)')
else:
print('\nNo MAP violations detected.')
# Schedule: add to crontab
# 0 9,15,21 * * * python ecommerce_monitor.py # 3x daily
# Cost: 3 products x 2 platforms x 3 checks x 30 days = 540 credits/mo = $2.70
save_and_alert(reports)Exemple Python
import os, requests, re, time
API_KEY = os.environ['SCAVIO_API_KEY']
EP = 'https://api.scavio.dev/api/v1/search'
def search(body):
return requests.post(EP, headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'}, json=body).json()
def parse_price(p):
try: return float(re.sub(r'[^0-9.]', '', str(p or '0')))
except: return 0.0
def monitor(name, query, map_price):
amazon = search({'platform': 'amazon', 'query': query, 'marketplace': 'US'})
google = search({'query': query, 'country_code': 'us', 'type': 'shopping'})
prices = [parse_price(p.get('price')) for p in amazon.get('products', [])]
prices += [parse_price(p.get('price')) for p in google.get('shopping_results', [])]
prices = [p for p in prices if p > 0]
violations = sum(1 for p in prices if p < map_price)
print(f'{name}: ${min(prices):.2f}-${max(prices):.2f} ({violations} MAP violations)')
monitor('Sony WH-1000XM5', 'Sony WH-1000XM5', 299.99)Exemple JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;
const EP = 'https://api.scavio.dev/api/v1/search';
async function search(body) {
const r = await fetch(EP, {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
return r.json();
}
async function monitor(name, query, mapPrice) {
const [amazon, google] = await Promise.all([
search({ platform: 'amazon', query, marketplace: 'US' }),
search({ query, country_code: 'us', type: 'shopping' })
]);
const prices = [
...(amazon.products || []).map(p => parseFloat(String(p.price || 0).replace(/[^0-9.]/g, ''))),
...(google.shopping_results || []).map(p => parseFloat(String(p.price || 0).replace(/[^0-9.]/g, '')))
].filter(p => p > 0);
const violations = prices.filter(p => p < mapPrice).length;
console.log(`${name}: $${Math.min(...prices)}-$${Math.max(...prices)} (${violations} MAP violations)`);
}
monitor('Sony WH-1000XM5', 'Sony WH-1000XM5', 299.99);Sortie attendue
[OK] Sony WH-1000XM5 Headphones: $289.99-$349.99 (8 listings, 0 violations)
[VIOLATION] Apple AirPods Pro 2: $219.00-$249.00 (6 listings, 2 violations)
[OK] Bose QuietComfort Ultra: $429.00-$449.99 (5 listings, 0 violations)
Total cost: $0.03 (6 credits)
ALERT: 1 products with MAP violations:
Apple AirPods Pro 2 on google_shopping: $219.00 (MAP: $249.00, -12.0%)
Apple AirPods Pro 2 on amazon: $229.99 (MAP: $249.00, -7.6%)