← Retour au blog

API JSON caché du site : comment découvrir les points de terminaison internes et réduire le trafic des parseurs

Le site s'envoie lui-même des données en JSON — et cette réponse est des dizaines de fois plus légère qu'une page HTML. Analysons étape par étape comment trouver le point de terminaison interne dans DevTools, pourquoi le cURL copié fonctionne alors que votre code ne fonctionne pas, que faire avec les tokens et la pagination, et quand il vaut mieux abandonner l'idée.

📅22 septembre 2026
API JSON caché du site : comment découvrir les points de terminaison internes et réduire le trafic des parseurs

Le parseur tire 400 Ko de HTML pour huit champs que le site renvoie en réponse JSON de 8 Ko. La différence de cinquante fois n'est pas une question de « code joli », mais de factures pour les proxys résidentiels, où vous payez pour chaque gigaoctet. Analysons comment trouver l'API interne du site, ce qui empêche sa répétition en 2026, et quand il vaut mieux abandonner cette idée.

Pourquoi chercher une API cachée si le HTML est déjà analysé

Presque toutes les interfaces modernes — React, Vue, Angular, Next.js — chargent d'abord la structure de la page, puis récupèrent les données par des requêtes séparées vers leurs propres points de terminaison. Ces points de terminaison ne sont pas documentés, mais ils existent, répondent en JSON pur et sont accessibles sans navigateur headless.

Ce que vous obtenez en y accédant :

  • Le trafic diminue d'un ordre de grandeur. Lors de l'analyse d'une page de produits typique, la page HTML pèse environ 400 Ko avec le balisage, les styles et les trackers, tandis que le point de terminaison JSON correspondant pèse environ 8 Ko, avec plus de champs : ID internes, stocks, variantes de produits.
  • Pas besoin de navigateur. Le rendu JavaScript disparaît, ainsi que la mémoire, le processeur et des dizaines de requêtes supplémentaires pour les polices et l'analyse.
  • Les données sont déjà structurées. Pas de sélecteurs qui se cassent à cause d'un changement de classe CSS.
  • Moins de requêtes — moins de raisons d'être banni. Le rendu d'une seule page de catalogue dans un navigateur implique des dizaines d'appels au site ; le même volume de données via l'API — un seul.

Pour un projet utilisant des proxys résidentiels, c'est une économie directe : le tarif est calculé par gigaoctets, et passer du rendu au JSON réduit généralement la facture plus que n'importe quelle astuce pour bloquer les images. Un sujet connexe — comment réduire le trafic du parseur par 5 fois avec d'autres méthodes.

Étape par étape : comment trouver le point de terminaison

  1. Vérifiez d'abord s'il existe une API officielle. Jetez un œil à /developers, /api, /docs du site cible. Une API publique documentée est versionnée et avertit des dépréciations — une API privée change silencieusement.
  2. Ouvrez les DevTools (F12) et allez dans l'onglet Network, en vous assurant que l'enregistrement est activé.
  3. Activez le filtre Fetch/XHR. Cela élimine les images, les polices et l'analyse, ne laissant que les appels pour les données.
  4. Nettoyez la liste pour éliminer le bruit du chargement initial.
  5. Provoquez les données nécessaires : faites défiler les résultats, cliquez sur « page suivante », appliquez un filtre, ouvrez une fiche. La requête qui vous intéresse apparaîtra au moment de l'action.
  6. Trouvez la réponse avec vos données. Le moyen le plus rapide — Ctrl+F dans le panneau Network : recherchez une valeur unique que vous voyez à l'écran (article, prix exact, morceau de nom) et regardez quelle requête l'a générée.
  7. Copiez la requête en entier : clic droit sur la ligne → Copier → Copier en tant que cURL. Ensuite, convertissez-la en code via curlconverter — ainsi, vous ne perdrez aucun en-tête.

Les chemins caractéristiques à surveiller en premier : /api/, /v1/, /v2/, /search, /products, /listings, /graphql.

Cas particulier : sites sur Next.js

Ici, les données ne nécessitent souvent pas de requête séparée — elles sont directement dans le HTML. Sur l'ancien Pages Router, c'est le bloc __NEXT_DATA__. Sur l'App Router (Next.js 13 et plus récent), les données pour l'hydratation sont dispersées dans les appels self.__next_f.push() dans plusieurs nœuds script — c'est un payload sérialisé des composants React Server. L'analyser manuellement est désagréable : les chunks se réfèrent les uns aux autres via des préfixes $ et peuvent être coupés au milieu d'une chaîne. Pour Python, il existe une bibliothèque nextflight qui analyse à la fois le Flight-payload depuis le HTML et la réponse RSC brute (requête avec l'en-tête RSC: 1), et propose de chercher par noms de clés plutôt que par indices de tableau — ainsi, le parseur survit au redéploiement du site.

Inversement des paramètres : pagination et filtres

Le point de terminaison trouvé est presque toujours paramétré. Trois schémas se rencontrent :

  • Par pages : ?page=3&per_page=20
  • Décalage et limite : ?offset=40&limit=20
  • Curseur : ?after=<token>&limit=20 — le token de la page suivante arrive dans le corps de la réponse précédente

Trois règles qui économisent des heures de débogage :

  • Arrêtez-vous sur un lot vide, et non sur un nombre de pages pré-calculé : le compteur total dans les API privées ment plus souvent qu'on ne le souhaiterait.
  • Vérifiez la taille réelle du lot. Vous avez demandé 100, reçu 20 — cela signifie que le point de terminaison a son propre plafond, et votre arithmétique sur les pages est déjà incorrecte.
  • Ne tentez pas d'accéder à la page 500. La pagination profonde est presque partout coupée par le serveur ; à la place, découpez l'échantillon avec des filtres — par catégorie, par plage de prix, par date.

Pourquoi cURL depuis le navigateur fonctionne, mais votre code ne fonctionne pas

C'est le point d'échec le plus fréquent, et la raison est presque toujours la même : en-tête perdu. Le cURL copié porte tout le contexte de la requête, tandis que le client fait maison ne l'a pas.

Ce qui s'avère généralement obligatoire :

  • En-têtes personnalisés avec le préfixe X- — X-CSRF-Token, X-Requested-With: XMLHttpRequest et toutes sortes de X-*-Token que le frontend insère lui-même. Sans eux, vous obtiendrez une réponse dans la plage 400–500.
  • Referer — un en-tête contextuel généré par l'action de l'utilisateur. De nombreux points de terminaison vérifient que la requête « vient de sa propre page ».
  • Authorization: Bearer <JWT> — un token à courte durée de vie, généralement de 15 à 60 minutes. Le hardcoding est inutile : il faut savoir obtenir un nouveau.
  • Cookies de session — gardez-les dans un objet de session, ne les copiez pas manuellement.
  • Type de contenu correct Content-Type pour POST : application/json et application/x-www-form-urlencoded codent le corps différemment, et un désaccord avec le type déclaré casse la requête silencieusement.

Où chercher les tokens eux-mêmes, s'ils ne sont pas dans les cookies : dans le code source HTML à l'intérieur de <script> (recherche par valeur connue via Ctrl+F), dans les bundles JavaScript, dans localStorage ou IndexedDB — onglet Application dans DevTools.

Les pièges dont on découvre les conséquences trop tard

L'API privée change sans avertissement. Elle n'a pas de versionnement, de promesses de compatibilité ou de support : l'équipe frontend renomme un champ un jeudi soir, et votre parseur collecte du vide. La protection n'est pas un « sélecteur fiable », mais un contrôle de la structure : vérifiez que les champs obligatoires sont présents et du bon type ; surveillez la part de valeurs vides et le nombre d'enregistrements dans le passage ; ignorez les enregistrements corrompus, mais alertez si le défaut dépasse 10 % ; conservez les réponses brutes pour avoir quelque chose à comparer ensuite.

API parfois protégée plus strictement que la page. Cela arrive régulièrement : le HTML est renvoyé sans problème, mais sur /api/, il y a un anti-bot qui vérifie à la fois le fingerprint TLS et la combinaison des en-têtes. Dans ce cas, l'économie de trafic se transforme en augmentation de la part des requêtes échouées, et le gain est absorbé.

Requêtes signées. Si dans les paramètres, vous voyez quelque chose comme sign, hash ou _s, le frontend calcule la signature en JavaScript. La reproduire est un projet à part, et souvent, il est moins coûteux de rester sur le HTML.

Restrictions de fréquence. Les points de terminaison privés ne sont pas conçus pour le flux : maintenez 1 à 2 requêtes par seconde, définissez des délais séparés pour la connexion et la lecture (par exemple, 5 et 30 secondes), répétez uniquement les erreurs transitoires — 429, 500, 502, 503, 504 — et ne touchez pas aux 401 et 404. Un délai exponentiel avec jitter est obligatoire, sinon tous les workers repartiront en même temps. Pour plus de détails — dans l'analyse des délais et de la logique de retry pour les proxys.

Cadre juridique. Les points de terminaison publics non authentifiés — une situation, l'accès au compte — fondamentalement une autre : l'inscription signifie accepter les conditions d'utilisation. Les données personnelles sont soumises au RGPD, peu importe à quel point elles sont faciles à obtenir. Les faits — prix, caractéristiques, disponibilité — ne sont pas protégés par le droit d'auteur, contrairement aux textes et aux images.

Quand rester sur HTML

L'API cachée n'est pas toujours un avantage. Restez sur l'analyse des pages si :

  • le site est serveur et il n'y a tout simplement pas d'API interne ;
  • le point de terminaison nécessite une signature ou une rotation de tokens — le maintenir coûte plus cher que la page ;
  • l'API a une protection plus sévère que les pages publiques ;
  • vous avez besoin du résultat final, que le frontend assemble à partir de plusieurs sources ;
  • vous gérez des dizaines de sites : un unique pipeline HTML évolue mieux qu'un zoo d'API privées avec des caprices individuels.

Quel type de proxy choisir pour le parsing API

Passer au JSON change le calcul, car le goulet d'étranglement se déplace : le trafic devient faible, mais les exigences en matière de qualité IP et de stabilité de session augmentent.

  • Point de terminaison ouvert sans autorisation et sans anti-bot. Ici, des proxies de centre de données suffisent : le volume de données est faible, pas besoin de payer pour des résidentiels.
  • Point de terminaison derrière un anti-bot ou lié à une session. Besoin de proxies résidentiels avec une session collante : le token, les cookies et l'IP doivent correspondre tout au long de la chaîne, sinon le serveur réinitialisera la session à la deuxième requête. Dans ce cas, la facture restera modeste — les gigaoctets en mode JSON sont consommés lentement.
  • Données provenant d'une application mobile. Si la version web est fermée, mais que l'application renvoie la même chose plus simplement, les points de terminaison sont recherchés par interception du trafic — c'est une procédure distincte, expliquée dans l'article sur la recherche d'une API cachée d'application mobile via mitmproxy.

En résumé

Vingt minutes dans DevTools remplacent souvent des jours de lutte avec un navigateur headless : filtre Fetch/XHR, recherche par valeur visible, Copier en tant que cURL — et vous avez une requête fonctionnelle. Ensuite, ce sont les détails qui comptent : transférer tous les en-têtes, analyser le schéma de pagination, mettre en place une validation de réponse et évaluer objectivement si le point de terminaison n'est pas plus protégé que la page elle-même. Là où l'API privée fonctionne, elle réduit à la fois le volume de trafic et le nombre de requêtes — c'est-à-dire immédiatement le coût des proxys et la probabilité de bannissement.