El seguimiento manual de las clasificaciones de búsqueda de la competencia es insostenible. Este tutorial crea un rastreador automatizado que consulta diariamente las palabras clave objetivo a través del punto final de Google de Scavio, registra las posiciones de la competencia y señala cambios significativos en la clasificación. Cuesta una fracción de las herramientas SERP empresariales porque paga por consulta con precios basados en crédito en lugar de tarifas mensuales fijas.
Requisitos previos
- Python 3.8+ instalado
- solicita biblioteca instalada
- Una clave API de Scavio de scavio.dev
- Una lista de palabras clave objetivo y dominios de la competencia
Guia paso a paso
Paso 1: Definir palabras clave y competidores
Configure su configuración de seguimiento con palabras clave objetivo y dominios de la competencia.
import os
API_KEY = os.environ['SCAVIO_API_KEY']
KEYWORDS = ['best crm 2026', 'project management software', 'invoice tool small business']
COMPETITORS = ['competitor1.com', 'competitor2.com', 'competitor3.com']
MY_DOMAIN = 'mydomain.com'Paso 2: Consultar clasificaciones para cada palabra clave
Busque cada palabra clave y extraiga posiciones para su dominio y sus competidores.
import requests
def get_rankings(keyword: str) -> list:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'platform': 'google', 'query': keyword}, timeout=10)
rankings = []
for i, r in enumerate(resp.json().get('organic', [])[:20], 1):
domain = r.get('link', '').split('/')[2] if '//' in r.get('link', '') else ''
if domain == MY_DOMAIN or any(c in domain for c in COMPETITORS):
rankings.append({'position': i, 'domain': domain, 'title': r['title']})
return rankingsPaso 3: Comparar con el día anterior
Cargue los datos de ayer y marque los cambios de posición por encima de un umbral.
import json, datetime
def compare_rankings(today: dict, yesterday: dict, threshold: int = 3) -> list:
alerts = []
for kw in today:
for entry in today[kw]:
prev = next((e for e in yesterday.get(kw, []) if e['domain'] == entry['domain']), None)
if prev:
change = prev['position'] - entry['position']
if abs(change) >= threshold:
direction = 'up' if change > 0 else 'down'
alerts.append(f"{entry['domain']} moved {direction} {abs(change)} positions for '{kw}' (now #{entry['position']})")
else:
alerts.append(f"NEW: {entry['domain']} entered top 20 for '{kw}' at #{entry['position']}")
return alertsPaso 4: Ejecute el rastreador diario
Combine todo en una función de ejecución diaria que guarde los resultados e imprima alertas.
def daily_track():
today_data = {}
for kw in KEYWORDS:
today_data[kw] = get_rankings(kw)
date = datetime.date.today().isoformat()
filename = f'serp_rankings_{date}.json'
with open(filename, 'w') as f:
json.dump(today_data, f, indent=2)
yesterday_file = f'serp_rankings_{(datetime.date.today() - datetime.timedelta(1)).isoformat()}.json'
try:
with open(yesterday_file) as f:
yesterday_data = json.load(f)
alerts = compare_rankings(today_data, yesterday_data)
for a in alerts: print(f'ALERT: {a}')
except FileNotFoundError:
print('First run, no comparison data yet.')
daily_track()Ejemplo en Python
# Run as a cron job: 0 8 * * * python serp_tracker.py
import requests, os, json, datetime
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}
def track(keywords, competitors):
for kw in keywords:
data = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'platform': 'google', 'query': kw}, timeout=10).json()
for i, r in enumerate(data.get('organic', [])[:20], 1):
domain = r.get('link', '').split('/')[2] if '//' in r.get('link', '') else ''
if any(c in domain for c in competitors):
print(f'[{i:2d}] {domain:30s} | {kw}')Ejemplo en JavaScript
async function track(keywords, competitors) {
for (const kw of keywords) {
const data = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'},
body: JSON.stringify({platform: 'google', query: kw})
}).then(r => r.json());
(data.organic || []).forEach((r, i) => {
const domain = new URL(r.link).hostname;
if (competitors.some(c => domain.includes(c))) console.log(`[${i+1}] ${domain} | ${kw}`);
});
}
}Salida esperada
Daily SERP ranking reports with position change alerts. Tracks competitor and own-domain positions for target keywords.