Un outil d'audit SEO examine comment un site et ses concurrents se comportent dans les résultats de recherche pour un ensemble de mots-clés cibles. Il vérifie quelles fonctionnalités SERP sont présentes (extraits optimisés, aperçus IA, boîtes PAA), où se classent les concurrents et quels écarts de contenu existent. Les outils SEO d'entreprise coûtent des milliers d'euros par mois. Ce tutoriel construit un outil d'audit léger utilisant l'API Scavio qui produit un rapport actionnable mot-clé par mot-clé gratuitement, au-delà des coûts d'utilisation de l'API.
Prérequis
- Python 3.10 ou supérieur
- bibliothèque requests installée
- Une clé API Scavio
- Un domaine cible et une liste de mots-clés à auditer
Parcours
Étape 1: Définir les cibles d'audit
Configurez votre domaine cible, les domaines concurrents et la liste de mots-clés à auditer.
TARGET = "mysite.com"
COMPETITORS = ["competitor-a.com", "competitor-b.com"]
KEYWORDS = ["python api tutorial", "rest api guide", "api authentication best practices"]Étape 2: Récupérer les données SERP complètes pour chaque mot-clé
Récupérez la réponse SERP complète incluant les résultats organiques, l'extrait optimisé, l'aperçu IA et la PAA.
def audit_keyword(keyword: str) -> dict:
r = requests.post(ENDPOINT, headers={"x-api-key": API_KEY},
json={"query": keyword, "country_code": "us"})
r.raise_for_status()
return r.json()Étape 3: Analyser les fonctionnalités et positions SERP
Pour chaque mot-clé, vérifiez quelles fonctionnalités SERP sont présentes et où se classent le domaine cible et les concurrents.
def analyze(keyword: str, data: dict) -> dict:
organic = data.get("organic_results", [])
target_pos = next((r["position"] for r in organic if TARGET in r.get("link", "")), None)
competitor_pos = {}
for c in COMPETITORS:
pos = next((r["position"] for r in organic if c in r.get("link", "")), None)
competitor_pos[c] = pos
return {
"keyword": keyword,
"target_position": target_pos,
"competitors": competitor_pos,
"has_featured_snippet": bool(data.get("featured_snippet")),
"has_ai_overview": bool(data.get("ai_overview")),
"paa_count": len(data.get("people_also_ask", [])),
}Étape 4: Générer le rapport d'audit
Exécutez l'audit pour tous les mots-clés et affichez un rapport récapitulatif formaté.
def run_audit() -> None:
print(f"SEO Audit for {TARGET}\n" + "=" * 40)
for kw in KEYWORDS:
data = audit_keyword(kw)
result = analyze(kw, data)
pos = result["target_position"]
print(f"\n{kw}")
print(f" Your rank: {'#' + str(pos) if pos else 'not ranked'}")
print(f" AI Overview: {result['has_ai_overview']}, PAA: {result['paa_count']}")Exemple Python
import os
import requests
API_KEY = os.environ.get("SCAVIO_API_KEY", "your_scavio_api_key")
ENDPOINT = "https://api.scavio.dev/api/v1/search"
TARGET = "mysite.com"
KEYWORDS = ["python api tutorial", "rest api guide"]
def fetch(q):
r = requests.post(ENDPOINT, headers={"x-api-key": API_KEY},
json={"query": q, "country_code": "us"})
r.raise_for_status()
return r.json()
def analyze(kw, data):
organic = data.get("organic_results", [])
pos = next((r["position"] for r in organic if TARGET in r.get("link", "")), None)
return {"keyword": kw, "position": pos, "ai_overview": bool(data.get("ai_overview")), "paa": len(data.get("people_also_ask", []))}
if __name__ == "__main__":
for kw in KEYWORDS:
result = analyze(kw, fetch(kw))
print(f"{kw}: {'#' + str(result['position']) if result['position'] else 'not ranked'} | AI: {result['ai_overview']} | PAA: {result['paa']}")Exemple JavaScript
const API_KEY = process.env.SCAVIO_API_KEY || "your_scavio_api_key";
const ENDPOINT = "https://api.scavio.dev/api/v1/search";
const TARGET = "mysite.com";
const KEYWORDS = ["python api tutorial", "rest api guide"];
async function fetch_(q) {
const res = await fetch(ENDPOINT, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ query: q, country_code: "us" })
});
return res.json();
}
function analyze(kw, data) {
const organic = data.organic_results || [];
const match = organic.find(r => r.link.includes(TARGET));
return { keyword: kw, position: match?.position || null, aiOverview: !!data.ai_overview, paa: (data.people_also_ask || []).length };
}
async function main() {
for (const kw of KEYWORDS) {
const data = await fetch_(kw);
const r = analyze(kw, data);
console.log(`${r.keyword}: ${r.position ? "#" + r.position : "not ranked"} | AI: ${r.aiOverview} | PAA: ${r.paa}`);
}
}
main().catch(console.error);Sortie attendue
SEO Audit for mysite.com
========================================
python api tutorial
Your rank: #6
AI Overview: true, PAA: 4
rest api guide
Your rank: not ranked
AI Overview: false, PAA: 3