Le succès de l'optimisation des moteurs génératifs (GEO) dépend du fait que les AI Overviews citent ou non votre marque. Ce scanner interroge les mots-clés cibles, vérifie si les AI Overviews apparaissent et enregistre si votre domaine est cité. Exécutez-le quotidiennement pour suivre la part de citations dans le temps. Chaque requête coûte 0,005 $.
Prérequis
- Python 3.8+
- requests library
- Une clé API Scavio de scavio.dev
- Domaine cible et liste de mots-clés
Parcours
Étape 1: Interroger les mots-clés cibles pour les AI Overviews
Rechercher chaque mot-clé et vérifier si un AI Overview est présent dans les SERP.
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'
KEYWORDS = [
'best project management tool 2026',
'project management software comparison',
'how to choose project management app',
'project management for small teams',
'agile project management tools',
]
def scan_keyword(query):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': query, 'country_code': 'us'}).json()
ai_overview = data.get('ai_overview', data.get('answer_box', {}))
has_aio = bool(ai_overview)
cited = False
if has_aio:
aio_text = json.dumps(ai_overview).lower()
cited = DOMAIN.lower() in aio_text
organic = data.get('organic_results', [])
org_position = None
for i, r in enumerate(organic):
if DOMAIN in r.get('link', ''):
org_position = i + 1
break
return {'query': query, 'has_aio': has_aio, 'cited': cited, 'organic_pos': org_position}
results = []
for kw in KEYWORDS:
r = scan_keyword(kw)
results.append(r)
status = 'CITED' if r['cited'] else ('AIO present' if r['has_aio'] else 'No AIO')
print(f' [{status:12}] {kw[:50]:50} | org: #{r["organic_pos"] or "-"}')
print(f'\nCost: ${len(KEYWORDS) * 0.005:.3f}')Étape 2: Calculer les métriques de part de citations
Calculer les métriques GEO : taux de citation, fréquence des AIO et corrélation organique.
def geo_metrics(results):
total = len(results)
aio_count = sum(1 for r in results if r['has_aio'])
cited_count = sum(1 for r in results if r['cited'])
aio_rate = aio_count / total * 100 if total else 0
citation_rate = cited_count / aio_count * 100 if aio_count else 0
overall_rate = cited_count / total * 100 if total else 0
organic_when_cited = [r['organic_pos'] for r in results if r['cited'] and r['organic_pos']]
avg_org = sum(organic_when_cited) / len(organic_when_cited) if organic_when_cited else 0
print(f'\n=== GEO Citation Report - {DOMAIN} ===')
print(f' Keywords scanned: {total}')
print(f' AI Overviews present: {aio_count} ({aio_rate:.0f}%)')
print(f' Your brand cited: {cited_count} ({overall_rate:.0f}% of all, {citation_rate:.0f}% of AIO)')
if avg_org:
print(f' Avg organic position when cited: #{avg_org:.1f}')
print(f'\n Not cited but AIO present:')
for r in results:
if r['has_aio'] and not r['cited']:
print(f' - {r["query"][:50]}')
return {'aio_rate': aio_rate, 'citation_rate': citation_rate}
geo_metrics(results)Étape 3: Suivre les changements de citations dans le temps
Stocker les résultats de scan quotidiens et les comparer aux scans précédents.
def track_citations(results, history_file='geo_citations.json'):
try:
with open(history_file) as f:
history = json.load(f)
except FileNotFoundError:
history = []
today = {
'date': datetime.now().strftime('%Y-%m-%d'),
'domain': DOMAIN,
'total': len(results),
'aio_present': sum(1 for r in results if r['has_aio']),
'cited': sum(1 for r in results if r['cited']),
'details': results
}
history.append(today)
with open(history_file, 'w') as f:
json.dump(history, f, indent=2)
print(f'\nSaved scan to {history_file}')
if len(history) >= 2:
prev = history[-2]
delta_aio = today['aio_present'] - prev['aio_present']
delta_cited = today['cited'] - prev['cited']
print(f' vs {prev["date"]}: AIO {delta_aio:+d}, Citations {delta_cited:+d}')
print(f' Run daily to build citation trend data')
track_citations(results)Exemple Python
import os, requests, json
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
def scan_geo(query, domain):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': query, '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 "not cited":10} | {query[:50]}')
for q in ['best project management tool 2026', 'agile tools comparison']:
scan_geo(q, 'yourbrand.com')
print('Cost: $0.010')Exemple JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
async function scanGeo(query, domain) {
const data = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: SH,
body: JSON.stringify({ query, country_code: 'us' })
}).then(r => r.json());
const aio = data.ai_overview || {};
const cited = JSON.stringify(aio).toLowerCase().includes(domain.toLowerCase());
console.log(`${cited ? 'CITED' : 'not cited'} | ${query}`);
}
await scanGeo('best project management tool 2026', 'yourbrand.com');Sortie attendue
[CITED ] best project management tool 2026 | org: #3
[AIO present ] project management software comparison | org: #5
[CITED ] how to choose project management app | org: #2
[No AIO ] project management for small teams | org: #4
[AIO present ] agile project management tools | org: #7
Cost: $0.025
=== GEO Citation Report - yourbrand.com ===
Keywords scanned: 5
AI Overviews present: 4 (80%)
Your brand cited: 2 (40% of all, 50% of AIO)
Avg organic position when cited: #2.5