Las herramientas de seguimiento de rango cobran entre 50 y 300 dólares al mes y, en el mejor de los casos, se actualizan una vez al día. Un monitor SERP competitivo personalizado verifica exactamente las palabras clave que le interesan, con su propia frecuencia, y alerta sobre los cambios que son importantes para su negocio. Este tutorial crea un monitor que rastrea múltiples competidores a través de conjuntos de palabras clave a $0.005/cheque, con Slack o alertas por correo electrónico sobre cambios de posición.
Requisitos previos
- Python 3.8+
- solicita biblioteca
- Una clave API de Scavio de scavio.dev
- Dominios de la competencia y palabras clave objetivo
Guia paso a paso
Paso 1: Definir competidores y palabras clave
Configure la configuración de monitoreo.
import os, requests, json, sqlite3
from datetime import datetime
API_KEY = os.environ['SCAVIO_API_KEY']
SH = {'x-api-key': API_KEY, 'Content-Type': 'application/json'}
CONFIG = {
'competitors': ['serpapi.com', 'dataforseo.com', 'serper.dev', 'exa.ai', 'tavily.com'],
'keywords': [
'serp api', 'search api for developers', 'google search api python',
'web scraping api 2026', 'ai agent search api'
]
}
db = sqlite3.connect('serp_monitor.db')
db.execute('''CREATE TABLE IF NOT EXISTS rankings (
keyword TEXT, domain TEXT, position INTEGER,
checked_at TEXT, title TEXT
)''')
db.commit()
print(f'Monitoring {len(CONFIG["competitors"])} competitors across {len(CONFIG["keywords"])} keywords')
print(f'Daily cost: ${len(CONFIG["keywords"]) * 0.005:.3f}')Paso 2: Verifique las clasificaciones de todas las palabras clave
Ejecute una verificación SERP para cada palabra clave y registre las posiciones de la competencia.
def check_rankings(keywords, competitors):
results = []
for kw in keywords:
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': kw, 'country_code': 'us'}).json()
organic = data.get('organic_results', [])
now = datetime.now().isoformat()
for r in organic[:20]:
domain = r.get('link', '').split('/')[2] if r.get('link') else ''
domain = domain.replace('www.', '')
if domain in competitors:
pos = r.get('position', 99)
db.execute('INSERT INTO rankings VALUES (?,?,?,?,?)',
(kw, domain, pos, now, r.get('title', '')[:80]))
results.append({'keyword': kw, 'domain': domain, 'position': pos})
db.commit()
print(f'Checked {len(keywords)} keywords. Cost: ${len(keywords) * 0.005:.3f}')
return results
ranks = check_rankings(CONFIG['keywords'], CONFIG['competitors'])
for r in ranks[:10]:
print(f' {r["keyword"]:30} | {r["domain"]:20} | #{r["position"]}')Paso 3: Detectar cambios de posición
Compare el cheque actual con el anterior para encontrar empresas de mudanzas.
def detect_changes(keyword, domain, threshold=3):
rows = db.execute(
'SELECT position, checked_at FROM rankings WHERE keyword=? AND domain=? ORDER BY checked_at DESC LIMIT 2',
(keyword, domain)).fetchall()
if len(rows) < 2: return None
current, previous = rows[0][0], rows[1][0]
change = previous - current # positive = improved
if abs(change) >= threshold:
return {'keyword': keyword, 'domain': domain,
'previous': previous, 'current': current, 'change': change}
return None
def alert_changes(keywords, competitors, threshold=3):
alerts = []
for kw in keywords:
for comp in competitors:
change = detect_changes(kw, comp, threshold)
if change: alerts.append(change)
if alerts:
print(f'\n{len(alerts)} position changes detected:')
for a in alerts:
direction = 'UP' if a['change'] > 0 else 'DOWN'
print(f' {a["domain"]:20} | {a["keyword"]:25} | #{a["previous"]} -> #{a["current"]} ({direction} {abs(a["change"])})')
else:
print('No significant position changes.')
return alerts
alert_changes(CONFIG['keywords'], CONFIG['competitors'])Paso 4: Generar datos de tablero competitivos
Cree una visión resumida del panorama competitivo.
def dashboard(competitors, keywords):
print(f'\n{"Keyword":30} | ', end='')
for c in competitors[:5]: print(f'{c[:12]:12} | ', end='')
print()
print('-' * (32 + 15 * len(competitors[:5])))
for kw in keywords:
print(f'{kw[:30]:30} | ', end='')
for comp in competitors[:5]:
row = db.execute(
'SELECT position FROM rankings WHERE keyword=? AND domain=? ORDER BY checked_at DESC LIMIT 1',
(kw, comp)).fetchone()
pos = f'#{row[0]}' if row else '-'
print(f'{pos:12} | ', end='')
print()
total_checks = len(keywords)
print(f'\nMonthly cost estimate: ${total_checks * 0.005 * 30:.2f} (daily) or ${total_checks * 0.005 * 7:.2f} (weekly)')
# Run a check first, then display
check_rankings(CONFIG['keywords'], CONFIG['competitors'])
dashboard(CONFIG['competitors'], CONFIG['keywords'])Ejemplo en Python
import os, requests
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
def check(keyword, competitors):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': keyword, 'country_code': 'us'}).json()
for r in data.get('organic_results', [])[:20]:
domain = r.get('link', '').split('/')[2].replace('www.', '')
if domain in competitors:
print(f'{keyword}: {domain} at #{r["position"]}')
check('serp api', ['serpapi.com', 'dataforseo.com', 'serper.dev'])Ejemplo en JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
async function check(keyword, competitors) {
const data = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: SH,
body: JSON.stringify({ query: keyword, country_code: 'us' })
}).then(r => r.json());
for (const r of (data.organic_results || []).slice(0, 20)) {
const domain = new URL(r.link).hostname.replace('www.', '');
if (competitors.includes(domain))
console.log(`${keyword}: ${domain} at #${r.position}`);
}
}
check('serp api', ['serpapi.com', 'dataforseo.com', 'serper.dev']).catch(console.error);Salida esperada
Monitoring 5 competitors across 5 keywords
Daily cost: $0.025
Checked 5 keywords. Cost: $0.025
Keyword | serpapi.com | dataforseo.c | serper.dev | exa.ai | tavily.com |
-----------------------------------------------------------------------------------------------
serp api | #3 | #7 | #5 | #12 | #15 |
search api for developers | #4 | #8 | #6 | #9 | - |
google search api python | #2 | #5 | #4 | - | - |
web scraping api 2026 | #6 | #3 | #8 | - | - |
ai agent search api | #5 | - | #7 | #4 | #11 |
Monthly cost estimate: $3.75 (daily) or $0.88 (weekly)