Las descripciones generales de IA de Google ahora aparecen en más del 40 % de las consultas informativas y citan marcas específicas. Si se cita a los competidores y usted no, perderá tráfico que no puede ver en las herramientas de SEO tradicionales. Este rastreador verifica diariamente las palabras clave objetivo, registra el estado de las citas y alerta cuando los competidores obtienen o pierden citas.
Requisitos previos
- Python 3.8+
- solicita biblioteca
- Una clave API de Scavio de scavio.dev
- Palabras clave de destino y dominio para monitorear
Guia paso a paso
Paso 1: Escanee palabras clave en busca de citas de descripción general de IA
Verifique cada palabra clave para conocer la presencia de AI Overview y el estado de citación de la marca.
import os, requests, json
from datetime import datetime
API_KEY = os.environ['SCAVIO_API_KEY']
SH = {'x-api-key': API_KEY, 'Content-Type': 'application/json'}
DOMAIN = 'yourbrand.com'
COMPETITORS = ['competitor1.com', 'competitor2.com']
KEYWORDS = [
'best project management tool',
'project management software comparison',
'agile vs waterfall tools',
'remote team project management',
'project management for startups',
]
def scan_citations(keyword):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': keyword, 'country_code': 'us'}).json()
aio = data.get('ai_overview', data.get('answer_box', {}))
aio_text = json.dumps(aio).lower() if aio else ''
result = {
'keyword': keyword,
'has_aio': bool(aio),
'brand_cited': DOMAIN.lower() in aio_text,
'competitors_cited': {c: c.lower() in aio_text for c in COMPETITORS}
}
return result
results = []
for kw in KEYWORDS:
r = scan_citations(kw)
results.append(r)
brand = 'CITED' if r['brand_cited'] else 'absent'
comps = sum(1 for v in r['competitors_cited'].values() if v)
print(f' [{brand:6}] {kw:45} | competitors: {comps}/{len(COMPETITORS)}')
print(f'\nCost: ${len(KEYWORDS) * 0.005:.3f}')Paso 2: Calcular métricas de citas y brechas
Calcule su porcentaje de citas frente a sus competidores e identifique las brechas.
def citation_report(results):
total = len(results)
with_aio = sum(1 for r in results if r['has_aio'])
brand_cited = sum(1 for r in results if r['brand_cited'])
print(f'\n=== AI Citation Report - {DOMAIN} ===')
print(f' Keywords: {total}')
print(f' AI Overviews present: {with_aio} ({with_aio/total*100:.0f}%)')
print(f' Your brand cited: {brand_cited} ({brand_cited/with_aio*100:.0f}% of AIO)' if with_aio else ' No AI Overviews found')
# Competitor comparison
print(f'\n Citation Share:')
comp_counts = {c: sum(1 for r in results if r['competitors_cited'].get(c)) for c in COMPETITORS}
all_brands = {DOMAIN: brand_cited, **comp_counts}
for brand, count in sorted(all_brands.items(), key=lambda x: x[1], reverse=True):
bar = '#' * count
print(f' {brand:25} | {count:2} citations | {bar}')
# Gaps: keywords where competitors are cited but you are not
gaps = [r for r in results if r['has_aio'] and not r['brand_cited'] and any(r['competitors_cited'].values())]
if gaps:
print(f'\n Citation Gaps ({len(gaps)} keywords where competitors beat you):')
for g in gaps:
cited_comps = [c for c, v in g['competitors_cited'].items() if v]
print(f' "{g["keyword"]}" -> cited: {", ".join(cited_comps)}')
citation_report(results)Paso 3: Almacenar historial y detectar cambios
Registre resultados diarios y avise cuando cambie el estado de la cita.
def track_changes(results, history_file='citation_history.json'):
try:
with open(history_file) as f:
history = json.load(f)
except FileNotFoundError:
history = []
today = {
'date': datetime.now().strftime('%Y-%m-%d'),
'total': len(results),
'aio_count': sum(1 for r in results if r['has_aio']),
'cited': sum(1 for r in results if r['brand_cited']),
'keywords': {r['keyword']: r['brand_cited'] for r in results}
}
changes = []
if history:
prev = history[-1]
prev_kws = prev.get('keywords', {})
for kw, cited in today['keywords'].items():
if kw in prev_kws and prev_kws[kw] != cited:
change = 'GAINED' if cited else 'LOST'
changes.append(f'{change}: "{kw}"')
history.append(today)
with open(history_file, 'w') as f:
json.dump(history, f, indent=2)
print(f'\n=== Citation Changes ===')
if changes:
for c in changes:
print(f' {c}')
else:
print(f' No changes since last scan.')
print(f' History: {len(history)} scans saved')
track_changes(results)Ejemplo en Python
import os, requests, json
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
def check_cited(keyword, domain):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': keyword, 'country_code': 'us'}).json()
aio = data.get('ai_overview', {})
cited = domain.lower() in json.dumps(aio).lower() if aio else False
print(f'{"CITED" if cited else "absent":6} | {keyword}')
for kw in ['best search api', 'serp api comparison']:
check_cited(kw, 'scavio.dev')
print('Cost: $0.010')Ejemplo en JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
async function checkCited(keyword, domain) {
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());
const aio = data.ai_overview || {};
const cited = JSON.stringify(aio).toLowerCase().includes(domain);
console.log(`${cited ? 'CITED' : 'absent'} | ${keyword}`);
}
await checkCited('best search api', 'scavio.dev');Salida esperada
[CITED ] best project management tool | competitors: 1/2
[absent] project management software comparison | competitors: 2/2
[CITED ] agile vs waterfall tools | competitors: 0/2
[absent] remote team project management | competitors: 1/2
[absent] project management for startups | competitors: 0/2
Cost: $0.025
=== AI Citation Report - yourbrand.com ===
Keywords: 5
AI Overviews present: 4 (80%)
Your brand cited: 2 (50% of AIO)
Citation Gaps (1 keywords where competitors beat you):
"project management software comparison" -> cited: competitor1.com, competitor2.com