Chargement…
Chargement…
Case study orienté impact: objectif métier clair, exécution maîtrisée, preuve ROI et plan de delivery traçable.
Statut
En production
Projet personnel en conditions réelles
Preuve technique
Anti-détection réel
Playwright furtif + connexion CDP
Accès
Démo live
Lien direct plus bas sur cette page
Scope livré
0 livrables
Briques prêtes à exploiter par les équipes
Aperçu produit
Prochain rapport
Lundi 09h00
Tableau de bord
Jan 2024 → Déc 2024
Cibles surveillées
◎14
Vérifications/jour
◈554
Taux de succès
◉98 %
Verdicts ambigus
◆2
Vérifications mensuel (/jour)
Alertes intelligentes
Changement détecté — Cible « Concurrent A »
il y a 2 min
Verdict ambigu — vérification manuelle requise
il y a 11 min
Export CSV historique planifié à 18h00
il y a 34 min
Prochain rapport auto
Lundi 6 Jan · 09:00
Architecture système
Cibles
Configs YAML déclaratives
Navigateur furtif
Playwright/Patchright · CDP
Verdict explicite
Jamais de faux positif silencieux
Dashboard web
Historique CSV · taux succès
Alertes
Telegram · Discord · Webhook
Code — extrait anonymisé
1# Verdict explicite — jamais de sélection silencieuse en cas de doute2async def evaluate_target(target: TargetConfig, page: Page) -> CheckResult:3 element = await page.query_selector(target.selector)45 if element is None:6 return CheckResult(verdict="ambigu", reason="sélecteur introuvable")78 value = await extract_value(element, target.extract_rule)9 matched = [r for r in target.rules if r.matches(value)]1011 if len(matched) == 0:12 # Jamais de repli silencieux sur la première option valide13 return CheckResult(verdict="ambigu", reason="aucune règle ne correspond")1415 return CheckResult(verdict=matched[0].verdict, value=value, rule=matched[0].name)
1# Un compteur d'erreurs unique — plus jamais de CDP injoignable en silence2async def run_check(target: TargetConfig) -> None:3 try:4 result = await evaluate_target(target, page=await get_page(target))5 except Exception as exc:6 error_counter.increment(target.id)7 if error_counter.exceeds(target.id, threshold=ERROR_ALERT_THRESHOLD):8 await send_alert(target, kind="error_streak", detail=str(exc))9 return1011 if result.verdict != previous_verdict(target.id):12 await send_alert(target, kind="change_detected", result=result)13 await capture_snapshot(target, page) # HTML + screenshot1415 persist_result(target.id, result)
Démo interactive
/ testez la technologieLe problème
Surveiller en continu un concurrent (baisse de prix, retour en stock, nouvelle offre) est impossible avec les outils no-code classiques (n8n, Zapier, Make) ou grand public (Visualping, Distill.io) dès qu'un site est protégé par un WAF ou bloque les navigateurs automatisés — la veille s'arrête net ou remonte des faux positifs.
La solution
Moteur de surveillance piloté par des configs de cible déclaratives (YAML) : navigateur furtif (Playwright/Patchright) ou connexion à un vrai Chrome via CDP, simulation de comportement humain (délais, mouvements de souris, frappe caractère par caractère), règles de détection configurables (texte, sélecteur, valeur numérique). Verdict toujours explicite — jamais de supposition silencieuse : si aucune règle ne correspond, le statut est « ambigu » et déclenche une vérification manuelle plutôt qu'un faux résultat. Alertes Telegram, Discord et webhook générique (Slack, n8n, Make, Zapier), avec capture HTML + screenshot à chaque déclenchement. Dashboard web de pilotage : démarrage/arrêt, édition des cibles, historique exportable en CSV, taux de succès calculé automatiquement.
Défis techniques
Ne jamais retourner un faux résultat : l'ancien moteur sélectionnait silencieusement la première option valide d'un menu quand aucune ne correspondait exactement. Corrigé pour retourner explicitement « ambigu » et ne rien sélectionner — couvert par test dédié.
Un CDP injoignable pouvait générer des milliers d'erreurs consécutives sans jamais déclencher d'alerte (3989 observées en prod). Le chemin d'erreur passe désormais par le même compteur que toute autre erreur.
Impact clé
Stack technique