El seguimiento de los productos de comercio electrónico en todas las plataformas revela diferencias de precios, períodos de agotamiento de existencias y posicionamiento de la competencia que las herramientas de plataforma única pasan por alto. Los vendedores, las marcas y los equipos de inteligencia de precios necesitan una vista unificada de cómo aparece un producto en Google Shopping, Amazon y otros mercados. La API de búsqueda de Scavio admite múltiples objetivos de plataforma en una única integración, devolviendo datos estructurados de precio, título, vendedor y disponibilidad. Este tutorial crea un monitor de productos multiplataforma que sondea cada plataforma, normaliza los resultados en una única tabla de comparación y marca los cambios entre ejecuciones.
Requisitos previos
- Python 3.8 o superior instalado
- solicita biblioteca instalada (solicitudes de instalación de pip)
- Una clave API de Scavio de scavio.dev
- Nombres de productos o ASIN de los que desea realizar un seguimiento
Guia paso a paso
Paso 1: Definir la lista de seguimiento de productos con consultas de plataforma
Cree una lista de productos, cada uno con un nombre y consultas de búsqueda específicas de la plataforma. Esto permite rastrear el mismo producto en Google Shopping y Amazon con la consulta más relevante para cada uno.
PRODUCTS = [
{
'name': 'Sony WH-1000XM5',
'queries': {
'google_shopping': 'Sony WH-1000XM5 headphones',
'amazon': 'B09XS7JWHH'
}
},
{
'name': 'Apple AirPods Pro 2',
'queries': {
'google_shopping': 'Apple AirPods Pro 2nd generation',
'amazon': 'B0D1XD1ZV3'
}
}
]Paso 2: Obtener datos de productos de cada plataforma
Escriba una función que llame a la API de Scavio con el parámetro de plataforma apropiado. Los resultados de Google Shopping provienen de la clave shopping_results, mientras que los resultados de Amazon provienen de product o organic_results.
import requests
import os
API_KEY = os.environ.get('SCAVIO_API_KEY', 'your_scavio_api_key')
ENDPOINT = 'https://api.scavio.dev/api/v1/search'
def fetch_platform(query: str, platform: str) -> dict:
payload = {'query': query, 'country_code': 'us'}
if platform == 'google_shopping':
payload['search_type'] = 'shopping'
elif platform == 'amazon':
payload['platform'] = 'amazon'
response = requests.post(
ENDPOINT,
headers={'x-api-key': API_KEY},
json=payload
)
response.raise_for_status()
return response.json()Paso 3: Normalizar resultados en un formato común
Extraiga el precio, el título, el vendedor y la disponibilidad de cada respuesta de la plataforma en un dictado uniforme. Esto facilita la comparación entre plataformas.
def normalize_google_shopping(data: dict) -> list[dict]:
results = []
for item in data.get('shopping_results', [])[:5]:
results.append({
'platform': 'google_shopping',
'title': item.get('title', ''),
'price': item.get('price', ''),
'seller': item.get('source', ''),
'link': item.get('link', '')
})
return results
def normalize_amazon(data: dict) -> list[dict]:
product = data.get('product', {})
if product:
return [{
'platform': 'amazon',
'title': product.get('title', ''),
'price': product.get('price', ''),
'seller': 'Amazon',
'link': product.get('link', '')
}]
return []Paso 4: Comparar con ejecuciones anteriores e informar cambios
Cargue los últimos precios guardados desde un archivo JSON, compárelos con los resultados actuales e imprima cualquier cambio de precio o disponibilidad. Guarde los datos actualizados para la siguiente ejecución.
import json
from pathlib import Path
HISTORY_FILE = Path('product_monitor_history.json')
def detect_changes(product_name: str, current: list[dict], history: dict) -> None:
prev = history.get(product_name, [])
prev_map = {(r['platform'], r['seller']): r['price'] for r in prev}
for item in current:
key = (item['platform'], item['seller'])
old_price = prev_map.get(key)
if old_price and old_price != item['price']:
print(f' PRICE CHANGE [{item["platform"]}] {item["seller"]}: {old_price} -> {item["price"]}')
elif not old_price:
print(f' NEW LISTING [{item["platform"]}] {item["seller"]}: {item["price"]}')Paso 5: Ejecute el monitor completo y guarde los resultados
Recorra todos los productos, obtenga de cada plataforma, normalice, compare y persista. Ejecute este script en una programación cron para un monitoreo continuo.
def run_monitor():
history = json.loads(HISTORY_FILE.read_text()) if HISTORY_FILE.exists() else {}
new_history = {}
for product in PRODUCTS:
print(f'Checking: {product["name"]}')
all_results = []
for platform, query in product['queries'].items():
data = fetch_platform(query, platform)
if platform == 'google_shopping':
all_results.extend(normalize_google_shopping(data))
elif platform == 'amazon':
all_results.extend(normalize_amazon(data))
detect_changes(product['name'], all_results, history)
new_history[product['name']] = all_results
HISTORY_FILE.write_text(json.dumps(new_history, indent=2))
print(f'Saved {len(new_history)} products to history')
run_monitor()Ejemplo en Python
import os
import json
import requests
from pathlib import Path
API_KEY = os.environ.get('SCAVIO_API_KEY', 'your_scavio_api_key')
ENDPOINT = 'https://api.scavio.dev/api/v1/search'
HISTORY_FILE = Path('product_monitor_history.json')
PRODUCTS = [
{
'name': 'Sony WH-1000XM5',
'queries': {
'google_shopping': 'Sony WH-1000XM5 headphones',
'amazon': 'B09XS7JWHH'
}
},
{
'name': 'Apple AirPods Pro 2',
'queries': {
'google_shopping': 'Apple AirPods Pro 2nd generation',
'amazon': 'B0D1XD1ZV3'
}
}
]
def fetch_platform(query: str, platform: str) -> dict:
payload = {'query': query, 'country_code': 'us'}
if platform == 'google_shopping':
payload['search_type'] = 'shopping'
elif platform == 'amazon':
payload['platform'] = 'amazon'
response = requests.post(
ENDPOINT,
headers={'x-api-key': API_KEY},
json=payload
)
response.raise_for_status()
return response.json()
def normalize_google_shopping(data: dict) -> list[dict]:
results = []
for item in data.get('shopping_results', [])[:5]:
results.append({
'platform': 'google_shopping',
'title': item.get('title', ''),
'price': item.get('price', ''),
'seller': item.get('source', ''),
'link': item.get('link', '')
})
return results
def normalize_amazon(data: dict) -> list[dict]:
product = data.get('product', {})
if product:
return [{
'platform': 'amazon',
'title': product.get('title', ''),
'price': product.get('price', ''),
'seller': 'Amazon',
'link': product.get('link', '')
}]
return []
def detect_changes(name: str, current: list[dict], history: dict) -> None:
prev = history.get(name, [])
prev_map = {(r['platform'], r['seller']): r['price'] for r in prev}
for item in current:
key = (item['platform'], item['seller'])
old_price = prev_map.get(key)
if old_price and old_price != item['price']:
print(f' PRICE CHANGE [{item["platform"]}] {item["seller"]}: {old_price} -> {item["price"]}')
elif not old_price:
print(f' NEW LISTING [{item["platform"]}] {item["seller"]}: {item["price"]}')
def run_monitor():
history = json.loads(HISTORY_FILE.read_text()) if HISTORY_FILE.exists() else {}
new_history = {}
for product in PRODUCTS:
print(f'Checking: {product["name"]}')
all_results = []
for platform, query in product['queries'].items():
data = fetch_platform(query, platform)
if platform == 'google_shopping':
all_results.extend(normalize_google_shopping(data))
elif platform == 'amazon':
all_results.extend(normalize_amazon(data))
detect_changes(product['name'], all_results, history)
new_history[product['name']] = all_results
HISTORY_FILE.write_text(json.dumps(new_history, indent=2))
print(f'Saved {len(new_history)} products to history')
if __name__ == '__main__':
run_monitor()Ejemplo en JavaScript
const API_KEY = process.env.SCAVIO_API_KEY || 'your_scavio_api_key';
const ENDPOINT = 'https://api.scavio.dev/api/v1/search';
const fs = require('fs');
const HISTORY_FILE = 'product_monitor_history.json';
const PRODUCTS = [
{
name: 'Sony WH-1000XM5',
queries: { google_shopping: 'Sony WH-1000XM5 headphones', amazon: 'B09XS7JWHH' }
},
{
name: 'Apple AirPods Pro 2',
queries: { google_shopping: 'Apple AirPods Pro 2nd generation', amazon: 'B0D1XD1ZV3' }
}
];
async function fetchPlatform(query, platform) {
const payload = { query, country_code: 'us' };
if (platform === 'google_shopping') payload.search_type = 'shopping';
else if (platform === 'amazon') payload.platform = 'amazon';
const response = await fetch(ENDPOINT, {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (!response.ok) throw new Error('HTTP ' + response.status);
return response.json();
}
function normalizeGoogleShopping(data) {
return (data.shopping_results || []).slice(0, 5).map(item => ({
platform: 'google_shopping',
title: item.title || '',
price: item.price || '',
seller: item.source || '',
link: item.link || ''
}));
}
function normalizeAmazon(data) {
const product = data.product || {};
if (product.title) {
return [{ platform: 'amazon', title: product.title, price: product.price || '', seller: 'Amazon', link: product.link || '' }];
}
return [];
}
async function main() {
const history = fs.existsSync(HISTORY_FILE) ? JSON.parse(fs.readFileSync(HISTORY_FILE, 'utf-8')) : {};
const newHistory = {};
for (const product of PRODUCTS) {
console.log('Checking: ' + product.name);
const allResults = [];
for (const [platform, query] of Object.entries(product.queries)) {
const data = await fetchPlatform(query, platform);
if (platform === 'google_shopping') allResults.push(...normalizeGoogleShopping(data));
else if (platform === 'amazon') allResults.push(...normalizeAmazon(data));
}
const prev = history[product.name] || [];
const prevMap = Object.fromEntries(prev.map(r => [r.platform + '|' + r.seller, r.price]));
allResults.forEach(item => {
const key = item.platform + '|' + item.seller;
const oldPrice = prevMap[key];
if (oldPrice && oldPrice !== item.price) console.log(' PRICE CHANGE [' + item.platform + '] ' + item.seller + ': ' + oldPrice + ' -> ' + item.price);
else if (!oldPrice) console.log(' NEW LISTING [' + item.platform + '] ' + item.seller + ': ' + item.price);
});
newHistory[product.name] = allResults;
}
fs.writeFileSync(HISTORY_FILE, JSON.stringify(newHistory, null, 2));
console.log('Saved ' + Object.keys(newHistory).length + ' products to history');
}
main().catch(console.error);Salida esperada
Checking: Sony WH-1000XM5
NEW LISTING [google_shopping] Best Buy: $348.00
NEW LISTING [google_shopping] Amazon.com: $328.00
NEW LISTING [amazon] Amazon: $328.00
Checking: Apple AirPods Pro 2
NEW LISTING [google_shopping] Apple: $249.00
NEW LISTING [amazon] Amazon: $189.99
Saved 2 products to history