Automatiser les audits SEO à grande échelle
Automatisez les audits SEO de milliers de pages programmatiques, gagnez des heures chaque mois et détectez plus vite les problèmes critiques.

Sur un site programmatique, auditez les gabarits et les données, et laissez un planning se charger du crawl. Un gabarit défectueux reproduit la même erreur sur chaque page qu’il génère : un audit automatisé a donc une seule mission, vous dire vite quel gabarit a cassé, sur combien de pages, et qui doit corriger.
Voici le système que je mettrais en place, dans l’ordre où je le ferais. Pour rester concret, disons que vous gérez un site d’emploi de 40 000 URL avec trois gabarits : /jobs/{role}-in-{city}, /companies/{company} et /salaries/{role}.
Pourquoi les contrôles ponctuels ne suffisent plus au-delà de quelques milliers de pages
Un contrôle manuel est un échantillonnage. Vous regardez les pages qui ont du trafic et vous laissez de côté la longue traîne, qui est pourtant la raison d’être du site. Il est aussi périodique : un problème livré lundi attend que quelqu’un tombe dessus. Et un export de crawl lu page par page affiche 3 000 problèmes là où il n’y a qu’un bug dans un gabarit.
La capacité de crawl est l’autre enjeu. La documentation de Google indique que le budget de crawl concerne surtout les sites très volumineux ou qui changent vite, et un lancement programmatique peut vous faire entrer dans cette catégorie du jour au lendemain. Les chaînes de redirections, les soft 404 et les réponses lentes consomment du crawl sur des URL qui ne vous rapportent rien.
Choisir un crawler capable de tourner sans vous
Tous les outils de cette liste peuvent convenir. Choisissez selon le volume, la possibilité d’exporter les données brutes et celle de planifier. Les paliers sont approximatifs, et je ne donne pas de prix parce qu’ils changent souvent.
| Taille du site | Options | Point d’attention |
|---|---|---|
| Jusqu’à quelques dizaines de milliers d’URL | Screaming Frog, Sitebulb, Ahrefs Site Audit | La licence payante de Screaming Frog ajoute la planification et la ligne de commande, ce qui en fait le plus scriptable |
| Centaines de milliers | Semrush Site Audit, Sitebulb Cloud | Limites de crawl de votre offre et coût à mesure que le site grandit |
| Très grands sites | Botify, Conductor Website Monitoring (ex-ContentKing), ou un système sur mesure | Analyse de logs et surveillance continue |
Dimensionnez votre choix selon la trajectoire du site. Changer d’outil d’audit en plein déploiement, c’est perdre votre historique.
Planifier les crawls par gabarit
Commencez par un crawl complet hebdomadaire, puis ajoutez un crawl quotidien pour les sections que vous venez de déployer. Une semaine, c’est trop long pour découvrir qu’une nouvelle version a rendu des milliers de pages non indexables. Sur le site d’emploi, je lancerais /jobs/ chaque jour pendant le déploiement et le reste chaque semaine.
Avec Screaming Frog sur un serveur Linux, une tâche cron peut exécuter ceci :
screamingfrogseospider \
--crawl https://www.example-jobs.com/ \
--headless \
--config /srv/audits/programmatic.seospiderconfig \
--output-folder /srv/audits/crawls \
--timestamped-output \
--save-crawl \
--export-tabs "Internal:All"
Quel que soit l’outil, certains réglages comptent : un user agent smartphone pour correspondre à l’indexation mobile, le rendu JavaScript si vos pages dépendent de code côté client, une cadence que votre serveur supporte, et le respect du robots.txt pour voir ce que voit Googlebot. Conservez chaque export, car les tendances et les comparaisons avant/après ont besoin d’historique.
Lire les résultats par gabarit
Le rapport le plus utile regroupe les problèmes par schéma d’URL : « title trop long sur 3 000 pages » devient une ligne et un ticket. La plupart des outils proposent cette segmentation. Avec un export brut, DuckDB le fait en une requête :
SELECT
regexp_extract("Address", 'https?://[^/]+/([^/]+)/', 1) AS template,
count(*) AS pages,
count(*) FILTER (WHERE "Status Code" <> 200) AS not_200,
count(*) FILTER (WHERE "Indexability" <> 'Indexable') AS not_indexable,
count(*) FILTER (WHERE "Title 1" IS NULL) AS no_title,
count("Title 1") - count(DISTINCT "Title 1") AS duplicate_titles
FROM read_csv_auto('internal_all.csv')
WHERE "Content Type" LIKE 'text/html%'
GROUP BY template
ORDER BY not_indexable DESC;
Les outils donnent aussi un score de santé de 0 à 100 et classent les problèmes en erreurs, avertissements et remarques. C’est un bon point de départ pour le tri. Je ne piloterais pas pour autant sur ce score, qui met un attribut alt manquant et un noindex sur tout un gabarit sur la même échelle.
Décider ce qui mérite une alerte
Classez les problèmes selon les pages touchées, le préjudice pour l’utilisateur, l’effet sur l’indexation et la valeur du gabarit. Trop d’alertes et plus personne ne les lit : commencez large et resserrez une fois le stock résorbé. Voici mes valeurs de départ pour l’exemple du site d’emploi, à ajuster après un mois de bruit réel :
| Problème | Pourquoi c’est important ici | Règle de départ |
|---|---|---|
| Baisse des pages indexables | Un gabarit a livré un noindex, ou une règle robots.txt est trop large | Alerte immédiate si un gabarit perd 10 % entre deux crawls |
| Title ou canonical manquants | En général une variable qui ne se résout plus | Alerte immédiate au-delà de 100 pages |
| Hausse des titles dupliqués | Un changement de gabarit a fait sauter la ville ou le métier | Alerte immédiate au-delà de 100 nouveaux doublons |
| Liens cassés dans un bloc du gabarit | Répétés sur chaque page générée | Alerte immédiate |
| Erreurs de schema | Uniquement si le balisage est central pour le gabarit | Correction sous deux semaines |
| Hausse des chaînes de redirections, 4xx, soft 404 | Crawl dépensé sur des URL inutiles | Synthèse hebdomadaire |
| Core Web Vitals en baisse | Souvent un changement de gabarit ou de ressource | Synthèse hebdomadaire |
| Titles longs, attributs alt, ordre des titres | Mineur, mais peu coûteux au niveau du gabarit | Backlog |
Transformer les alertes en travail
Envoyez les alertes immédiates sur Slack ou par e-mail, et faites-leur créer un ticket dans Jira, Asana ou Linear avec le schéma d’URL, le nombre de pages, une URL d’exemple et la correction proposée. Le reste va dans une synthèse hebdomadaire des problèmes nouveaux et résolus. Aux décideurs, une vue mensuelle par gabarit suffit.
Rédigez une courte procédure pour chaque problème fréquent, afin qu’un ticket puisse être pris sans réunion. Par exemple :
Canonical manquante sur les pages programmatiques. Sans elle, les moteurs peuvent traiter des pages proches comme des doublons et disperser les signaux. Ajoutez une balise autoréférente au gabarit :
<link rel="canonical" href="{{ page.url }}" />. Responsable : équipe frontend. Vérification : recrawler le gabarit et confirmer que chaque balise pointe vers la bonne URL.
Bloquer les mauvais déploiements avant la mise en ligne
Le bug le moins cher est celui qui n’atteint jamais la production. C’est ici que l’audit se branche sur votre processus de déploiement. Exécutez un script en CI sur la préproduction, avec un échantillon d’URL par gabarit, et faites échouer le build au-delà d’un seuil. En plus des balises habituelles, il cherche les variables non résolues, l’erreur la plus typique des pages programmatiques.
// check-templates.mjs, à lancer en CI sur la préproduction, exit 1 bloque le déploiement
import { readFile } from "node:fs/promises";
const BASE = process.env.STAGING_URL;
const MAX_FAILURE_RATE = 0.05;
// samples.json contient { "jobs": ["/jobs/nurse-in-lille", ...], "salaries": [...] }
const samples = JSON.parse(await readFile("samples.json", "utf8"));
async function check(path) {
const res = await fetch(BASE + path, { redirect: "manual" });
const html = await res.text();
const visible = html.replace(/<script[\s\S]*?<\/script>/gi, "");
const errors = [];
if (res.status !== 200) errors.push(`status ${res.status}`);
if (!/<title>[^<]{10,}<\/title>/i.test(html)) errors.push("title");
if (!/<link[^>]+rel="canonical"/i.test(html)) errors.push("canonical");
if (/\{\{|\bundefined\b|\bNaN\b/.test(visible)) errors.push("unresolved variable");
return errors;
}
let blocked = false;
for (const [template, paths] of Object.entries(samples)) {
const failures = [];
for (const path of paths) {
const errors = await check(path);
if (errors.length) failures.push(`${path}: ${errors.join(", ")}`);
}
console.log(`${template}: ${failures.length}/${paths.length} failing`);
failures.slice(0, 5).forEach((line) => console.log(` ${line}`));
if (failures.length / paths.length > MAX_FAILURE_RATE) blocked = true;
}
process.exit(blocked ? 1 : 0);
Après chaque version, lancez sous 24 heures un crawl ciblé des sections déployées et comparez-le à la référence précédente. Le chapitre sur la mise en production traite du déploiement lui-même.
Ajouter ce qu’un crawler ne voit pas
Un crawler vous dit ce que votre serveur renvoie. La réaction de Google, elle, se lit dans la Search Console, et si vous soumettez un sitemap par gabarit, le rapport d’indexation des pages se filtre gabarit par gabarit. Une concentration d’URL « Explorée, actuellement non indexée » sur un gabarit signifie souvent que Google voit peu de valeur dans ces pages. Le rapport Statistiques sur l’exploration ajoute le total des requêtes, la taille de téléchargement et le temps de réponse moyen, et les logs serveur montrent la même activité URL par URL. Le chapitre sur le suivi explique comment les lire dans le temps.
L’utilité demande aussi ses propres contrôles, car la politique de Google sur l’abus de contenu à grande échelle, introduite en mars 2024, vise les pages produites en masse et de faible valeur, et une page peut réussir tous les tests techniques sans rien dire. Mesurez combien de champs de données chaque page remplit réellement, et signalez celles sous votre minimum pour un noindex ou une suppression. Lancez une détection de quasi-doublons par gabarit. Sur le projet Deux.io, un outil de détection de contenu dupliqué et un détecteur de contenu IA faisaient partie de la boîte à outils. Lisez ensuite un échantillon aléatoire à la main, car aucune métrique ne remplace cela.
Les réponses générées par IA consomment aussi ces pages : vérifiez que votre robots.txt reflète un choix délibéré concernant des robots comme GPTBot, OAI-SearchBot, ClaudeBot et PerplexityBot, et cherchez-les dans vos logs. Google-Extended est un réglage distinct qui ne change pas votre présence dans la recherche Google.
Vérifier les corrections et revoir le système
Fermer un ticket ne prouve rien. Après une correction, recrawlez les pages concernées, comparez l’avant et l’après, et cherchez de nouveaux problèmes sur ces mêmes URL. Vérifiez ensuite quelques pages à l’œil.
Une fois par mois, cherchez où le système a échoué : un problème arrivé en production aurait-il dû être détecté, quelles alertes ont été ignorées, quel gabarit continue de générer des incidents ? Le chiffre à suivre est le délai entre détection et correction, par gabarit. En parallèle, surveillez les pages indexées et le trafic organique par gabarit pour confirmer que le travail porte ses fruits.
Votre prochaine étape : notez vos schémas d’URL, mettez en place un crawl hebdomadaire planifié et lancez la requête par gabarit sur le premier export. Corrigez ce qui arrive en tête, puis ajoutez les alertes et le contrôle en CI.