Retour au blog
· 8 min de lecture

Utiliser les LLM pour extraire des données structurées de pages web désordonnées

LLMIAweb scrapingextraction de donnéesdonnées structurées

Le problème de la fragilité

Chaque web scraper a la même faiblesse : les sélecteurs CSS. Vous écrivez document.querySelector('.product-price .amount') et ça marche parfaitement — jusqu’à ce que le site soit refondu, renomme la classe en price-value, l’enveloppe dans un nouveau div, ou passe d’un HTML rendu côté serveur à un composant chargé en JavaScript.

Quand votre scraper surveille 50 sites, au moins un d’entre eux change quelque chose chaque semaine. Vous passez plus de temps à maintenir des sélecteurs qu’à construire de nouvelles fonctionnalités. C’est un tapis roulant.

C’est là que les LLM changent la donne. Au lieu de dire à un scraper exactement où trouver le prix (chemin CSS fragile), vous dites à un LLM “extrais le prix de cette page” et il comprend à quoi ressemble un prix — quelle que soit la structure du HTML.

Comment fonctionne l’extraction par LLM

Le pattern de base est direct :

  1. Récupérer le contenu de la page (HTML ou texte rendu)
  2. Le nettoyer (supprimer navigation, footers, scripts — garder le contenu principal)
  3. L’envoyer à un LLM avec un prompt définissant quoi extraire et le schéma de sortie attendu
  4. Valider la réponse structurée contre votre schéma
  5. Stocker les données validées

Voici à quoi ça ressemble en pratique. Disons que vous devez extraire des informations produit d’une page e-commerce. Le prompt pourrait être :

Extrais les informations suivantes de cette page produit :
- name : le nom du produit
- price : le prix actuel en nombre (pas le prix d'origine/barré)
- currency : le code devise (EUR, USD, GBP, etc.)
- in_stock : booléen, si le produit est disponible
- description : une brève description du produit (max 200 caractères)

Retourne du JSON valide correspondant à ce schéma. Si un champ ne peut pas être déterminé, utilise null.

Le LLM lit le contenu de la page — HTML désordonné, formatage incohérent, prix multiples (original, remisé, réservé aux membres) — et retourne du JSON propre. Il comprend que “19,99 EUR” et “$19.99” et “Prix : 19.99$” représentent tous des prix. Il sait que “En stock”, “Disponible”, “Expédition sous 2-3 jours” et une icône de coche verte signifient tous que le produit est disponible.

Pas de sélecteurs CSS. Pas de XPath. Pas de regex qui casse quand quelqu’un ajoute un espace.

Quand utiliser les LLM vs le parsing traditionnel

Les LLM ne remplacent pas le scraping traditionnel — ils le complètent. Voici quand chaque approche a du sens :

Utilisez des sélecteurs CSS/XPath traditionnels quand :

  • Vous scrapez un seul site avec une structure stable
  • Les données sont à des emplacements prévisibles et cohérents
  • Vous avez besoin de vitesse maximale et de coût minimal
  • Le volume est extrêmement élevé (des millions de pages par jour)

Utilisez l’extraction par LLM quand :

  • Vous scrapez de nombreux sites avec des structures différentes
  • Les layouts changent fréquemment
  • Les données nécessitent une interprétation (pas juste une localisation)
  • Vous devez extraire du texte non structuré, pas seulement du HTML structuré
  • Le volume est modéré (des milliers à dizaines de milliers de pages par jour)

Utilisez les deux quand :

  • Vous avez un mix de sources stables et instables
  • Certains champs sont faciles à localiser (CSS) et d’autres nécessitent de la compréhension (LLM)
  • Vous voulez les sélecteurs CSS pour la vitesse avec le LLM en fallback quand les sélecteurs échouent

L’approche hybride est la plus puissante — similaire au choix entre API et scraping. Essayez d’abord l’extraction CSS rapide et économique. Si elle échoue ou retourne des résultats suspects, basculez sur l’extraction LLM. Loggez le fallback pour pouvoir mettre à jour vos sélecteurs plus tard si vous le souhaitez.

Rendre ça rentable

L’inquiétude évidente avec l’extraction par LLM est le coût. Envoyer des pages HTML complètes à une API LLM n’est pas donné — et la plupart de ce HTML est de la navigation, des headers, des footers et des scripts sans intérêt.

Nettoyez avant d’envoyer. Supprimez tout ce qui n’est pas le contenu principal. Retirez toutes les balises <script>, <style>, <nav>, <header>, <footer>. Supprimez les attributs HTML qui ne portent pas de sens sémantique (noms de classe, IDs, attributs data). Convertissez le HTML restant en texte propre ou markdown minimal. Ça réduit typiquement le nombre de tokens de 80 à 90 %.

Utilisez le bon modèle pour le bon travail. Pas toute extraction ne nécessite Claude Opus ou GPT-4o. Pour des extractions directes (nom, prix, disponibilité), des modèles plus légers comme Claude Haiku ou GPT-4o mini délivrent 95 %+ de précision à une fraction du coût. Réservez les modèles plus puissants pour les extractions complexes qui nécessitent du raisonnement — interpréter des descriptions ambiguës, gérer plusieurs niveaux de prix, ou extraire de contenu fortement non structuré.

Groupez les pages similaires. Si vous extrayez les mêmes champs de 100 pages du même site, vous pouvez souvent envoyer plusieurs contenus de page dans un seul appel API avec un prompt partagé. Ça réduit l’overhead du prompt système et de la définition de schéma répétés pour chaque page.

Cachez intelligemment. Si une page n’a pas changé depuis la dernière extraction (vérifiez avec les ETags ou le hashing du contenu), ne ré-extrayez pas. Cela seul peut réduire les appels API LLM de 60 à 70 % pour les sites qui se mettent à jour rarement.

Avec ces optimisations, le coût de l’extraction par LLM se situe typiquement entre 0,001 et 0,01 $ par page — comparable aux coûts de proxy que vous payez déjà pour le scraping.

Sorties structurées : la percée de fiabilité

L’amélioration la plus significative de l’extraction par LLM au cours de la dernière année est le support des sorties structurées. Claude et GPT supportent désormais la génération contrainte — le modèle est forcé de retourner du JSON valide correspondant à un schéma spécifique. Plus besoin de parser des réponses en texte libre en espérant que le format soit correct.

Ça change tout pour l’utilisation en production. Au lieu de prompter le modèle puis d’écrire des regex fragiles pour extraire des valeurs de sa réponse, vous définissez un schéma JSON et l’API garantit que la réponse y correspond. Chaque champ a le bon type. Les champs requis sont toujours présents. Pas de clés inattendues ni de crochets manquants.

Combiné avec la validation de schéma de votre côté (Zod, Pydantic), ça crée un double filet de sécurité qui rend l’extraction LLM aussi fiable que le parsing traditionnel pour la plupart des cas d’usage.

Gérer les cas limites

Les LLM sont impressionnants pour l’extraction, mais pas parfaits. Voici comment gérer les cas où ils trébuchent :

Données ambiguës. Une page affiche trois prix — original, soldé et réservé aux membres. Lequel le LLM doit-il retourner ? Soyez explicite dans votre prompt. “Extrais le prix de vente actuellement affiché visible pour les utilisateurs non connectés, pas le prix d’origine ni le prix membre.”

Valeurs hallucinées. Occasionnellement, un LLM va générer des données plausibles qui ne sont pas sur la page. Croisez les valeurs extraites avec le contenu brut. Si le LLM retourne un prix de 29,99 € mais que la chaîne “29,99” n’apparaît nulle part dans le contenu de la page, signalez-le pour revue.

Contenu multilingue. Les pages dans des langues que le modèle maîtrise moins bien peuvent avoir une précision d’extraction inférieure. Pour les cas d’usage critiques, testez la qualité d’extraction par langue et envisagez d’utiliser des prompts spécifiques à chaque langue ou une pré-traduction.

Pages volumineuses. Certaines pages dépassent la fenêtre de contexte du modèle même après nettoyage. Pour celles-ci, extrayez d’abord la section pertinente (le conteneur produit, le corps de l’article) et n’envoyez que cette section au LLM.

Un exemple concret

Nous avons construit un système de veille concurrentielle pour un distributeur européen qui suit les prix sur 120 sites e-commerce différents dans 8 pays. L’approche traditionnelle aurait nécessité 120 configurations de scraper différentes, chacune avec des sélecteurs CSS spécifiques au site, maintenues individuellement.

À la place, nous avons construit 3 templates de scraper (un pour les pages produit uniques, un pour les pages de listing, un pour les résultats de recherche) alimentés par l’extraction LLM. Le même schéma de prompt gère les pages produit en français, allemand, italien, espagnol et anglais sans modification. Quand un site est redesigné, l’extracteur continue de fonctionner parce qu’il lit du contenu, pas une structure DOM.

La maintenance est passée de roughly 15 heures par semaine (corriger des sélecteurs cassés) à environ 2 heures par semaine (principalement gérer de nouvelles structures de sites jamais rencontrées). La précision d’extraction se maintient à 97,5 % sur tous les sites, validée par des vérifications manuelles ponctuelles.

Chez SilentFlow, cette combinaison de scraping intelligent et d’extraction alimentée par LLM est au coeur de ce qu’on construit. Le web est désordonné, non structuré et en perpétuel changement. Les scrapers traditionnels luttent contre cette réalité. Les LLM l’embrassent — comprenant le contenu comme un humain le ferait, mais à une échelle qu’aucune équipe humaine ne peut égaler. Le résultat est une extraction de données plus résiliente, plus adaptable et finalement plus fiable que n’importe quelle approche basée sur des sélecteurs.

Lancez votre projet scraping

Besoin d'automatiser votre collecte de données ? Dites-nous ce dont vous avez besoin, on vous répond sous 24 heures.

Envoyer le message