C’était un soir de décembre, froid, humide, le genre de soirée où l’on se réfugie dans des obsessions mineures pour oublier le reste. Tout ce que je voulais, c’était de l’ordre. Un pantalon. Un Chino Regular, L32, noir. Rien d’extravagant, juste une pièce manquante pour calmer ma névrose de la garde-robe parfaite. J’avais le beige, le marine. Le noir n’existait plus. Rupture de stock.
Dans un monde normal, on passe à autre chose. Mais le refus a ce don d’exciter la volonté. Je ne voulais pas attendre le hasard d’un réassort ; je voulais l’omniscence. Je devais être le premier, une sorte de scalper de la fringue basique, prêt à dégainer dès que le stock_quantity passerait à 1.
J’ai ouvert mon terminal comme on ouvre une bière : par automatisme. J’ai lancé un workflow n8n, confiant, naïf. Une requête HTTP, un cron de 15 minutes. La routine.
La réponse a claqué comme un coup de fouet : 403 Forbidden.

Pas une simple erreur de permission. Une fin de non-recevoir signée DataDome. Le site ne se contentait pas de vérifier mon User-Agent ; il analysait mes tripes, mes headers, mon empreinte. Mon nœud HTTP avait la discrétion d'un parpaing dans une vitrine. J’étais bot, et j’étais dehors.
L’ego a pris le relais. J’ai sorti l’artillerie lourde. Puppeteer ? Détecté. Le headless chrome s'est fait sortir avant même d'avoir rendu le DOM. J'ai payé pour voir. J'ai pris des crédits chez ScrapingBee, j'ai activé leurs proxys résidentiels, puis leurs "Stealth Proxys" censés tromper la vigilance des plus paranoïaques.
Rien. Le néant. Toujours cette page de garde, ce captcha invisible qui me riait au nez. J’en étais réduit à envisager des outils de clic-bouton pour amateurs, type VisualPing. La honte.
C’est là que j’ai arrêté de forcer la porte pour regarder la serrure. Le problème n’était pas mon IP, ni mes headers. C’était mon accent. Mon client TLS parlait comme un robot. Le handshake me trahissait avant même l'envoi du premier octet.

J’ai changé d’arme. curl_cffi. Une librairie Python capable d'improviser, d'emprunter l'empreinte JA3 d'un vrai navigateur, de simuler la signature TLS de Chrome jusqu'au bout des ongles. J’ai relancé le script. La 403 s’est tue. Le HTML est tombé.
Une victoire en demi-teinte. Car récupérer le HTML d’une SPA (Single Page Application) moderne, c’est comme récupérer une coquille vide. Les stocks n’y étaient pas. Tout est injecté en JavaScript, côté client. Et ma librairie ne joue pas le JS.
Retour à la chirurgie. Console développeur, onglet Network. J’ai disséqué les appels XHR comme un légiste cherche la cause du décès. J'ai écarté les fausses pistes, les GetDrawerSizeGuide qui ne mènent nulle part. Et j'ai trouvé la veine : GetProductDetailsAvailability.
Un endpoint pur. Pas de fioritures, pas de HTML à parser à la machette. Juste un JSON froid, clinique, contenant la vérité absolue sur les stocks magasins et web.
Il restait à mapper leurs codes internes. Le "Noir" n’est pas noir, c’est Y0508_6. Une nomenclature absurde, bureaucratique.
Le script tourne désormais dans le silence de mon serveur.
Il interroge, vérifie, dort, recommence.
J'ai contourné DataDome, j'ai reverse le flux, j'ai vaincu la machine pour un pantalon à 8 balles.
Ce n'est pas une question de vêtement.
C'est juste pour le calme de savoir que quand le stock reviendra, je le saurai avant tout le monde.
Aujourd'hui, la ligne de code correspondant au noir a été purgée du serveur distant. Délistée. Ce n'est plus une rupture de stock, c'est une extinction d'espèce. J'ai l'arme la plus sophistiquée du monde, braquée sur une chaise vide.
Je n'ai pas éteint le script pour autant. Il continue d'envoyer ses requêtes dans le noir, comme une sonde perdue dans l'espace qui bip encore pour personne. Parfois, l'obstination est la seule chose qui nous reste quand la logique a quitté la pièce.

