Aller au contenu
R&D16 avril 20269 min

Pixee Scraper : R&D d'une plateforme multi-scrapers B2B/B2C en 2026

Scraper 19 sites e-commerce (fournisseurs + concurrents) avec un framework commun : les vrais défis techniques d'un projet de R&D interne en cours.

Par Pixee Play
Pixee Scraper : R&D d'une plateforme multi-scrapers B2B/B2C en 2026

Chez Pixee Play, nous travaillons depuis plusieurs mois sur Pixee Scraper, une plateforme interne de R&D destinée à industrialiser l'extraction de catalogues produits fournisseurs (B2B) et la surveillance de prix concurrents (B2C). À l'heure où j'écris ces lignes (avril 2026, v3.10), la plateforme pilote 19 scrapers actifs — 14 fournisseurs et 5 concurrents — et alimente notre PIM Pixee PIM avec des dizaines de milliers de fiches produits enrichies. Ce billet détaille les choix techniques et les vrais obstacles rencontrés : c'est un retour de R&D, pas un produit marketing. Certains problèmes sont résolus, d'autres sont des fronts ouverts.

Le problème de départ : 19 sites, 19 techniques différentes

Chaque fournisseur ou marketplace a sa propre stack technique, son propre anti-bot, son propre niveau de structuration des données. En 2026, nous gérons des sites sur :

  • PrestaShop 1.6, 1.7 et 8.x (B2B et B2C, avec ou sans login)
  • Sylius PHP (framework Symfony e-commerce)
  • Sana Commerce (SPA JS-heavy)
  • Joomla + VirtueMart (avec API Algolia en sortie)
  • Drupal 10+
  • Oxatis (FR, JSON-LD structured data)
  • ASP.NET legacy
  • APIs REST propriétaires (Ubaldi Pro avec JWT)
  • Custom Svelte SSR (TopAchat, en MPN cross-check)

L'approche naïve — un script Python par site — explose rapidement en dette technique : duplication de code, mises à jour impossibles, pas de monitoring centralisé. Notre objectif était de construire un framework commun qui absorbe 80 % de la complexité et laisse chaque scraper se concentrer sur les 20 % de spécifique.

Architecture : un framework DRY au cœur du projet

Le module src/common/ fournit les briques partagées :

  • BasePipeline : éliminer ~170 lignes de boilerplate par scraper. CLI argparse (full/incremental/resume/discover), gestion des signaux, barres de progression, state management, cycle de vie DB, rebuild catalogue, tracking erreurs. 15 scrapers sur 15 en héritent.
  • BaseDbStore et BaseJsonStore[T] : persistance PostgreSQL + JSON atomique, upsert sur clé naturelle. 14 scrapers sur 14 migrés.
  • BasePlaywrightSession, BaseHttpxSession, BaseCurlSession : abstraction de la couche réseau. Login, cookies, rate limiter, retry exponentiel. 12 scrapers sur 15 ont migré.
  • ProxyManager : 5 providers (none / static_list / tailscale / brightdata / endpoint_pool) avec 4 stratégies de routage (round-robin, weighted, failover, least_failures).
  • AdaptiveRateLimiter : ajuste dynamiquement le délai entre requêtes via EWMA du temps de réponse HTTP. Si le site rame, on lève le pied sans intervention manuelle. Opt-in par scraper.

Le gain concret : ajouter un nouveau scraper prend désormais 2 à 4 jours de développement, contre 2 à 3 semaines au démarrage du projet.

Le vrai combat : l'anti-bot moderne

En 2026, scraper un site B2C sérieux (Amazon, LDLC, ManoMano, Cdiscount) sans être bloqué demande de jouer sur plusieurs plans. Voici nos défenses empilées.

1. Trois niveaux de stealth navigateur

Playwright seul se fait détecter facilement (CDP leaks, fingerprint navigator.webdriver, plugins manquants). Nous avons modélisé 3 tiers, activables par scraper :

  • safe : Playwright standard, suffisant pour les sites B2B avec login (on est authentifié, pas besoin de se cacher).
  • stealth : rebrowser-playwright, fork qui patche les leaks CDP (Runtime.enable, object-mutations).
  • camoufox : Camoufox, fork Firefox anti-détection avec canvas/WebGL noise, fingerprint rotation. Plus lourd à lancer mais passe Cloudflare Turnstile dans des cas où stealth échoue.

2. TLS fingerprinting avec curl_cffi

Certains WAF (Oxatis notamment) détectent les clients HTTP non-navigateur via le TLS ClientHello : ordre des cipher suites, extensions, ALPN. Python httpx et requests ont une signature distincte de Chrome/Firefox. La parade : curl_cffi, qui impersonne le TLS fingerprint de Chrome/Firefox/Safari via libcurl patchée.

Notre BaseCurlSession encapsule cette couche. Un scraper peut passer de httpx à curl_cffi en changeant sa classe parente — tout le reste (proxy, cookies, rate limiter) reste identique.

3. Proxies résidentiels et rotation

Les IP datacenter (AWS, OVH, Hetzner) sont bloquées en quelques requêtes sur les sites sérieux. Notre stack supporte :

  • Tailscale comme réseau de sortie résidentiel (routage via nos machines physiques)
  • BrightData / endpoint pools avec 4 stratégies de sélection
  • Failover automatique quand un endpoint dépasse un seuil d'échecs
  • Drag-and-drop ordering des endpoints dans le dashboard (priorité manuelle par scraper)

4. Ce qui reste ouvert

Datadome reste notre front le plus difficile. Les sites protégés par Datadome (certaines marketplaces FR) demandent encore des solutions sur mesure. C'est un sujet de R&D actif pour la v3.11.

Le casse-tête des sélecteurs qui changent

Les équipes front-end des sites cibles refont leurs CSS tous les 3 à 6 mois. Un sélecteur .product-price__value devient [data-testid="price-amount"] du jour au lendemain. Sans détection proactive, vos scrapers retournent silencieusement des données vides pendant des jours. Nous avons développé deux outils pour traiter ce problème.

Extraction health scoring

Chaque produit extrait reçoit un score de qualité : complétude des champs critiques (prix, nom, référence), cohérence des valeurs (prix non nul, cohérence avec l'historique), présence des champs optionnels. Un rolling window calcule la moyenne sur les N dernières exécutions, et un score-drop detection alerte quand un scraper tombe sous le seuil historique — exporté en métriques Prometheus.

Selector Doctor : diagnostic DOM automatique

Quand une dégradation est détectée, un outil de diagnostic analyse automatiquement le DOM cible :

  • Comparaison avec un snapshot de référence pris en état sain
  • Recherche textuelle (chercher « Prix » ou « € » dans le DOM pour retrouver l'élément)
  • Application de patterns CMS connus (PrestaShop, Sylius, Shopify ont des structures typiques)
  • Suggestions de nouveaux sélecteurs CSS avec un score de confiance

L'opérateur reçoit une PR semi-automatique avec les sélecteurs candidats — il valide ou ajuste. Temps de résolution d'un site cassé : de 2-4h à 15-30 min.

Le wizard de création assisté par ML

Ajouter un nouveau site implique de détecter sa CMS, sa structure d'URL sitemap, la présence ou non d'un login, le niveau d'anti-bot. Nous avons entraîné un petit modèle ML sur 32 sites analysés, validation croisée 5-fold :

  • Détection CMS (PrestaShop / Sylius / Shopify / Drupal / Magento / custom) : 55 % d'accuracy (petit dataset, marge de progression)
  • Détection besoin de session (login obligatoire ou pas) : 58 % d'accuracy
  • Score anti-bot probable : heuristique (Cloudflare cookies, Akamai headers, reCAPTCHA)

Le wizard propose un template pré-rempli (7 templates CMS : PrestaShop 1.6, 1.7, Sylius, Drupal, Joomla, Oxatis, ASP.NET) : sélecteurs, pattern login, stratégie d'extraction. L'opérateur ajuste plutôt que de tout écrire from scratch.

L'accuracy est encore modeste — c'est attendu avec 32 samples seulement. Chaque nouveau site analysé alimente le dataset. L'intérêt n'est pas la précision parfaite, c'est de guider rapidement le bon point de départ.

Profils d'extraction adaptatifs

Un crawl complet d'un catalogue de 40 000 produits prend 8 à 12 heures. Mais on n'a pas besoin de tout ré-extraire chaque fois. Nous avons défini 4 profils :

  • full : toutes les données (prix, spécifications, images, descriptions, PDFs attachés)
  • price_specs : prix + specs techniques (pas d'images ni descriptions)
  • price_only : prix seul — gain ×3 à ×5 en temps d'exécution
  • auto : full au premier run, price_only ensuite (détection via DB)

En pratique : le premier crawl d'un fournisseur est en full, les runs hebdo suivants basculent en price_only pour réactualiser uniquement les prix. Les specs sont rafraîchies une fois par mois en price_specs.

Le pipeline PDF : du scraping au RAG

11 de nos 15 scrapers B2B extraient des documents attachés (datasheets, manuels, certificats, fiches techniques). Ces PDFs sont précieux pour l'enrichissement catalogue — ils contiennent les spécifications techniques exhaustives que les pages produits résument. Le pipeline, côté Pixee PIM, orchestré par Celery Beat horaire :

  1. Download HTTP du PDF (retry ×2 avec backoff exponentiel)
  2. SHA256 dedupe : si le PDF a déjà été traité sur un autre produit, on réutilise
  3. Upload S3 avec versioning
  4. OCR via Docling (IBM) — conversion PDF → Markdown structuré
  5. Chunking sémantique + embedding
  6. Injection dans Qdrant (base vectorielle) pour RAG
  7. Indexation de la fiche produit enrichie dans Pixee PIM

Résultat : une recherche sur un attribut technique (« IP67 », « PoE+ », « Cat 6a ») retrouve les produits dont la fiche ne le mentionnait pas mais dont le datasheet le contenait. Ça change radicalement la qualité des résultats pour les fiches techniques complexes.

Le dashboard : FastAPI + HTMX, zéro build JS

Le Scraper Hub est le centre de contrôle : start/stop des runs, monitoring en temps réel, scheduling cron, queue (max 6 scrapers simultanés, FIFO auto-drain), exports (CSV, JSON, Excel en streaming), CRUD proxies, settings par scraper.

Choix technique fort : FastAPI + HTMX + Jinja2 + Tailwind CDN. Pas de React, pas de Vue, pas de build step JS. Les interactions dynamiques (drag-and-drop, filtres persistés en sessionStorage, refresh partiel) se font en HTMX avec quelques lignes JS vanilla.

Pourquoi ce choix ? Pour un outil interne à un petit nombre d'utilisateurs, les avantages sont clairs :

  • Boilerplate minimal : une route FastAPI qui renvoie du HTML, un template qui itère
  • Pas de problème de synchro state client/serveur : la source de vérité est la DB, le HTML est généré à chaque requête
  • Time-to-ship : une nouvelle page avec formulaire + tableau = 30 min
  • Pas de build pipeline à maintenir, pas de version Node.js à tenir, pas de vulnerabilities npm

HTMX est un excellent rapport qualité / simplicité pour les UIs admin.

Légalité et éthique : non négociable

Le scraping a une éthique. Nous la documentons dans nos pratiques projet :

  • Respect de robots.txt : même quand techniquement nous pourrions l'ignorer
  • Rate limiting agressif : délais entre requêtes, adaptive throttling, jamais de DoS involontaire
  • Pas de données personnelles : nous extrayons des catalogues produits publics, jamais d'avis clients nominatifs ou d'infos personnelles
  • Conformité RGPD : les bases que nous alimentons sont propriétaires, avec DPO désigné côté Pixee PIM
  • Relation contractuelle : pour les sites B2B sous login, nous avons systématiquement l'autorisation du fournisseur (c'est leur intérêt : nous ingérons leur catalogue vers notre PIM au bénéfice mutuel)
  • TOS des marketplaces B2C : nous monitorons des prix publics, à cadence raisonnable, sans reproduire intégralement leur catalogue

Les chiffres actuels (avril 2026)

  • 19 scrapers actifs (14 fournisseurs B2B + 5 concurrents B2C)
  • 274 tests automatisés (framework commun + spécifiques scrapers)
  • 17 modules communs dans src/common/
  • ~150 000 fiches produits dans la DB à date, dont une majorité enrichies par le pipeline RAG PDF
  • 2 328 assets PDFs déjà ingérés (OCR Docling + indexation Qdrant)
  • 3 niveaux de stealth (safe, stealth, camoufox) avec sélection per-scraper
  • Extraction health + Selector Doctor actifs sur les 19 scrapers

Ce qui reste en R&D

Plusieurs fronts sont ouverts, et c'est normal pour un projet à ce stade :

  • Datadome : nous n'avons pas encore de solution systématique qui passe cette protection en environnement serveur. Benchmark de solutions commerciales en cours.
  • Détection sémantique des champs : passer d'une sélection CSS statique à une extraction LLM-guided (GPT-4o vision sur screenshot) pour les sites très dynamiques. Expérimental.
  • Consolidation cross-sources : quand un même produit (même EAN) est trouvé sur 4 fournisseurs différents, fusion intelligente des attributs avec arbitrage de qualité.
  • Self-healing selectors : le Selector Doctor propose, mais idéalement il devrait appliquer automatiquement après validation d'un seuil de confiance. Sujet d'architecture encore ouvert.

Conclusion

Pixee Scraper n'est ni un produit commercial, ni une démo — c'est une plateforme de R&D interne qui nous permet d'industrialiser notre expertise scraping + enrichissement catalogue, et de la mettre au service de nos clients via Pixee PIM. Les choix techniques (Python async, Playwright multi-tiers, curl_cffi TLS, HTMX dashboard, pipeline RAG) sont opinionés et testés en production sur des volumes réels. Si vous avez un besoin d'extraction catalogue fournisseur ou de veille prix concurrentielle structurée et légale, nous pouvons en discuter — le socle existe, nous l'adaptons à chaque contexte client. Contactez Pixee Play pour un échange technique.