Aller au contenu principal
Site en cours de refonte — quelques pages peuvent bouger ou évoluer.
17 mars 2026

Cloudflare sort un endpoint « /crawl » : pratique pour auditer un site… ou pas

Un crawl complet en « un appel API », c’est tentant. Mais si tu le branches naïvement, tu fabriques un crawler qui te DDoS (ou qui te sort des données inutiles).

11 min de lecture
6 vues
réactions
Partager :
Cloudflare sort un endpoint « /crawl » : pratique pour auditer un site… ou parfait pour se tirer une balle

Un endpoint qui « crawl tout un site » via Browser Rendering, en gros un appel API et tu récupères du HTML ou du Markdown. Sur le papier, c’est le rêve de toutes les équipes qui ont déjà vécu une refonte qui casse le SEO, un rendu JS qui part en vrille, ou une base de connaissances interne qui finit en wiki zombie.

Dans la vraie vie, c’est aussi un très bon moyen de te créer un crawler qui met ton origin à genoux, qui coûte cher, et qui te sort un volume de données ingérable. La feature est bonne. Mais il faut la traiter comme une brique de prod, pas comme un gadget de scraping.

« /crawl » dans Cloudflare Browser Rendering : ce que ça apporte vraiment

Cloudflare a ajouté un endpoint /crawl (en bêta) dans Browser Rendering pour lancer un crawl de site « à partir d’une URL » et laisser le système découvrir les pages tout seul. La promesse, c’est de pouvoir récupérer des résultats exploitables (HTML, Markdown, JSON) en s’appuyant sur un navigateur headless, donc avec un rendu proche d’un vrai navigateur, y compris sur des sites blindés de JavaScript.

Le point important, c’est que ce n’est pas un appel synchrone qui va te renvoyer 20 000 pages dans la réponse. C’est du job asynchrone. Tu envoies une requête, tu récupères un identifiant, puis tu viens chercher l’état et les résultats plus tard. Si tu as déjà fait du « long running » propre, tu vois le genre. Si tu ne l’as jamais fait, c’est exactement le moment où tu peux transformer un truc simple en générateur d’incidents.

Cloudflare annonce aussi des garde-fous par défaut côté respect de robots.txt et de leur AI Crawl Control. Très bien. Mais ça ne remplace pas ton cerveau, ni le fait de cadrer ton crawl.

Les usages où ça devient une arme (dans le bon sens)

Audit post-refonte : prouver ce que tu as cassé, pas « ressentir »

Après une refonte, le piège classique, c’est de passer deux semaines à débattre sur « Google va revenir » ou « c’est normal ». La seule approche saine, c’est d’aller regarder ce que ton site renvoie réellement, à l’échelle. Un crawl te permet de vérifier des choses bêtes mais vitales : des 301 qui tournent en rond, des noindex accidentels, des canonicals qui pointent ailleurs, des pages money qui ont perdu leur contenu, ou des gabarits qui ont soudain 12 balises h1.

L’intérêt de passer par du rendu navigateur, c’est que tu n’es pas limité à « fetch HTML brut ». Tu peux attraper le contenu tel qu’il se stabilise après exécution JS. C’est particulièrement utile quand une refonte a déplacé le rendu côté client et que tu veux savoir si une page est réellement « lisible » sans être dépendant de ton Chrome local, de tes cookies, ou de ton réseau.

QA de rendu JS : attraper les pages « vides mais pas en erreur »

Le genre de bug qui tue, ce n’est pas le 500 visible. C’est la page qui renvoie 200, qui a l’air « ok » en local, mais qui affiche un squelette en prod parce qu’une API bloque, parce qu’un bundle ne se charge pas, ou parce que le rendu dépend d’un truc présent uniquement quand tu es loggé.

Un crawl headless te donne un signal systématique. Tu peux comparer le DOM final, détecter des pages qui n’ont plus de contenu principal, ou qui affichent une erreur applicative dans le rendu, sans attendre qu’un humain tombe dessus.

Extraction de contenu pour un RAG : utile, à condition de rester sobre

Cloudflare met en avant la sortie Markdown et JSON, avec une partie « IA » pour structurer. Pour un pipeline RAG, c’est tentant : tu crawls, tu obtiens un format plus digeste que du HTML, tu chunkes, tu indexes.

Mais tu ne veux pas « tout indexer ». Tu veux indexer ce qui a un intérêt produit. Les pages de navigation, les listings infinis, les filtres, les pages de tag qui dupliquent tout, ça te pollue un moteur et ça dégrade les réponses. Donc même si l’outil sait tout aspirer, ton job reste de définir un périmètre (paths, profondeur, pages canoniques) et une stratégie de nettoyage.

Monitoring de pages « qui payent » : simple, rentable, peu risqué

Le cas le plus sous-coté, c’est le monitoring. Tu choisis 50 ou 200 URLs importantes (landing pages, pricing, docs, formulaires), tu les crawls régulièrement, et tu alertes dès qu’il se passe un truc anormal. Un noindex qui apparaît, un canonical qui change, un rendu qui devient vide, une redirection qui débarque. Ce n’est pas glamour, mais ça évite des semaines de dégâts silencieux.

Le piège : « crawl tout » veut dire « charge tout »

Un crawl, c’est une attaque de charge déguisée en outil de QA. Tu fais ouvrir des pages, exécuter du JS, charger des assets, appeler des APIs internes. Et tu fais ça de manière automatisée, donc sans la retenue naturelle d’un humain. Si tu lances ça sur un site non prévu pour, tu peux vite déclencher un festival de timeouts, de saturation DB, ou de limitation côté API.

Le pire, c’est quand tu fais ça depuis une pipeline CI ou un cron, que ça se relance en cas d’échec, et que tu te retrouves avec plusieurs crawls concurrents. Ce n’est pas « un audit ». C’est un dogpile.

Robots.txt et AI Crawl Control : à respecter, mais à comprendre

Le respect de robots.txt par défaut est une bonne nouvelle, parce que ça évite les abus évidents. Mais ça ne résout pas ton problème principal : même un crawl autorisé peut être trop agressif. Si ton robots.txt autorise tout, ce n’est pas une invitation à taper 50 000 URLs d’un coup avec rendu headless.

Autre point terrain : « respecter robots » ne veut pas dire « je suis safe juridiquement / éthiquement / produit ». Si tu crawles un site tiers, tu dois avoir une raison solide et une politique claire. Et si tu crawles ton propre site, tu dois éviter de te donner le droit d’ignorer tes propres règles juste parce que « c’est interne ». Les règles existent souvent pour de bonnes raisons (facettes, recherche interne, endpoints de préprod, etc.).

Le vrai garde-fou : définir ton scope avant d’appuyer sur le bouton

Si tu ne définis pas de périmètre, tu n’es pas en train d’auditer, tu es en train « d’aspirer ». Et l’aspiration brute est presque toujours inutile. En audit SEO ou QA rendu, ce qui compte, c’est de couvrir les templates et les parcours qui représentent ton business, pas de faire un inventaire complet de chaque variante d’URL.

Concrètement, je traite ça comme une stratégie d’échantillonnage intelligent, même quand l’outil sait faire du discovery. Tu pars de quelques hubs (homepage, catégories, pages docs racines), tu limites la profondeur, tu brides ce qui ressemble à des paramètres de facettes, et tu assumes que tu ne veux pas « l’exhaustif ». L’exhaustif, tu le fais plus tard, quand tu sais ce que tu cherches et que ton infra peut l’encaisser.

Asynchrone : jobs, retries et idempotence (sinon ça dégénère)

Le job asynchrone est ton ami, mais seulement si tu l’encadres. Il faut que ton système sache créer un job, stocker l’ID, poller sans spammer, et surtout ne pas relancer un crawl complet parce qu’une étape de récupération a échoué.

Je vois souvent le bug classique : « l’appel de collecte a timeout, donc je relance le crawl ». Mauvaise idée. Un timeout côté client ne veut pas dire que le job n’existe pas côté serveur. Tu veux des retries sur la récupération, pas sur le lancement, et tu veux des clés d’idempotence ou au minimum une déduplication côté stockage.

// Pseudo-exemple : lance un crawl, récupère un jobId, puis poll.
// Vérifie l’URL exacte dans la doc Cloudflare : ici je garde l’idée, pas le chemin exact.

type CrawlStartResponse = { result?: { job_id: string } };

authorization: {
  const token = process.env.CLOUDFLARE_API_TOKEN!;
  const start = await fetch("https://api.cloudflare.com/.../crawl", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      url: "https://example.com/",
      maxDepth: 2,
      // L’idée : rester petit au début. Un crawl “full site” en prod, ça se mérite.
      output: "markdown",
    }),
  });

  const startJson = (await start.json()) as CrawlStartResponse;
  const jobId = startJson.result?.job_id;
  if (!jobId) throw new Error("Crawl start failed");

  for (let i = 0; i < 60; i++) {
    await new Promise(r => setTimeout(r, 2000));

    const status = await fetch(`https://api.cloudflare.com/.../crawl/${jobId}`, {
      headers: { "Authorization": `Bearer ${token}` },
    });

    const statusJson = await status.json();
    if (statusJson.result?.state === "completed") {
      // Stocke les résultats, ne les garde pas juste en mémoire.
      break;
    }

    if (statusJson.result?.state === "failed") {
      throw new Error("Crawl failed");
    }
  }
}

Stockage : ne transforme pas ton crawl en décharge

Si tu lances un crawl, tu vas récupérer des volumes. Même « seulement » 5 000 pages, ça peut devenir énorme quand tu gardes l’HTML complet, les métadonnées, des captures, des versions. Le réflexe que je recommande, c’est de stocker deux choses, pas dix.

D’abord, un artefact brut pour debug (HTML ou équivalent), avec l’URL, le timestamp, le status code, et idéalement un hash de contenu. Ensuite, une version normalisée pour ton use case (Markdown pour RAG, JSON pour audit). Et tu mets une politique de rétention. Si ton but est un audit de refonte, tu as besoin de comparer « avant/après », pas d’archiver 18 mois de pages de blog en double.

Le plus important : garde une traçabilité simple. Une page sans son URL canonique, son URL finale après redirections, et son contexte de crawl, c’est un morceau de texte anonyme. Pour du RAG, ça te revient dans la figure au moment où tu veux citer une source et que tu ne sais plus d’où vient le paragraphe.

La « definition of done » : ce que tu veux vérifier, noir sur blanc

Un crawl qui « marche » techniquement n’a aucun intérêt si tu ne sais pas ce que tu cherches à valider. Le piège, c’est de lancer un gros job, de recevoir un gros JSON, de le mettre dans un bucket, et de conclure que tu as fait de la QA.

Sur un audit SEO post-refonte, ta done definition peut être très concrète : aucune page money en noindex, pas de chaînes de redirections, canonicals cohérents, pas de 404 sur des URLs internes, contenu principal présent après rendu. Sur un monitoring, c’est souvent une histoire de seuils et de diff : « si le title change », « si le contenu chute de 70% », « si le rendu contient un message d’erreur ». C’est bête, mesurable, et ça déclenche des alertes qui veulent dire quelque chose.

Mon avis (assez sec) : excellent outil, mais traite-le comme un crawler dangereux

Je suis preneur d’un /crawl qui fait du rendu navigateur et sort du Markdown prêt à indexer. Ça peut te faire gagner des jours, surtout quand tu dois objectiver un problème de rendu JS ou accélérer un audit après une refonte.

Mais si tu le branches « en full site » sans scope, sans limitation, sans stockage propre, et sans stratégie de retry, tu ne fais pas du SEO technique. Tu fais un incident de prod avec de la data inutile à la fin. Commence petit, prouve la valeur sur 50–200 URLs, mets des garde-fous, puis seulement après tu montes en puissance.

Sources

Cet article vous a plu ?

Commentaires

Laisser un commentaire

Entre 10 et 2000 caractères

Les commentaires sont modérés avant publication.

Aucun commentaire pour le moment.

Soyez le premier à donner votre avis !