Comment je suis passé de 10 minutes par annonce à l'exécution de bots Selenium sur 6 PC distants, puis au reverse engineering d'une API privée et à la création de systèmes d'extraction que personne d'autre n'a construits — tout cela parce que Wallapop ne dispose d'aucune API publique.
Une précision sur le périmètre. Tout ce qui est décrit ici a été conçu pour faire tourner ma propre entreprise : les comptes vendeurs, l'inventaire et les données de commandes m'appartiennent. Ce sont des outils d'exploitation internes qui gèrent mes propres annonces et commandes — avec des requêtes conservatrices, à débit limité et au rythme d'un humain — parce que la plateforme n'expose aucune API publique pour les vendeurs. C'est de l'infrastructure pour une entreprise que j'exploite, et non un outil dirigé contre qui que ce soit d'autre.
Chapitre 1 : L'enfer manuel
Wallapop est la plus grande place de marché d'occasion d'Espagne. Des millions d'utilisateurs. Des milliards en volume de transactions. Et en 2023, ils n'avaient aucun moyen de publier des annonces en masse.
Chaque annonce devait être créée manuellement via leur interface web. Télécharger les photos. Rédiger un titre. Rédiger une description. Fixer un prix. Choisir une catégorie. Définir la localisation. Cliquer sur publier. 5 à 10 minutes par article.
Quand vous gérez une activité e-commerce de revente de liquidations Amazon, vous pouvez avoir 500 à 600 articles dans votre catalogue à tout moment. Faites le calcul : 600 articles × 7 minutes = 70 heures de travail manuel rien que pour tout mettre en ligne une seule fois. Et il faut republier tous les quelques jours pour rester visible dans les résultats de recherche.
Ce n'est pas un modèle économique. C'est un poste de saisie de données.
Chapitre 2 : Le bot Selenium
Alors j'ai construit un bot. Un système d'automatisation de navigateur basé sur Selenium, capable de naviguer dans l'interface web de Wallapop, de remplir tous les champs, de télécharger les images et de publier — automatiquement.
L'architecture était simple, mais elle exigeait de résoudre plusieurs problèmes loin d'être triviaux :
- XPaths dynamiques — Le frontend React de Wallapop génère des structures DOM différentes selon la catégorie, l'état et les options de livraison. J'ai créé un fichier
xpaths.jsonconfigurable qui associait chaque champ à son sélecteur, de sorte que lorsque Wallapop modifiait son interface (ce qui arrivait régulièrement), je n'avais qu'à mettre à jour la configuration - Randomisation des images — Télécharger exactement les mêmes images de produit sur plusieurs comptes déclenchait la détection de doublons. J'ai construit un pipeline OpenCV qui appliquait des transformations subtiles à chaque image : micro-rotation, injection de bruit, variation de luminosité, léger étirement. Suffisant pour tromper le hachage perceptuel, invisible à l'œil humain
- Cadençage anti-détection — Un bot qui remplit des formulaires en 0,5 seconde ressemble à un bot. J'ai ajouté des délais aléatoires entre les actions (variation de la vitesse de frappe, pause avant de cliquer, comportement de défilement) pour imiter l'interaction humaine. Chaque annonce prenait environ 1 minute — plus lent qu'une machine ne pourrait aller, mais assez rapide pour être utile
Chapitre 3 : La ferme de 6 PC
Une minute par annonce. 600 articles. Cela fait 10 heures sur une seule machine. Encore trop lent, surtout quand il faut republier tous les 3 jours pour le positionnement SEO.
Ma solution fut la force brute : j'ai installé 5 à 6 PC, je m'y suis connecté à distance via AnyDesk, et j'ai exécuté plusieurs instances du bot simultanément sur chaque machine. Chaque PC avait son propre compte Wallapop, son propre profil de navigateur, sa propre IP (réseaux différents).
Le flux de travail ressemblait à ceci :
Me (AnyDesk) ──→ PC 1 (Office): 2 browser instances × Account A, B
──→ PC 2 (Warehouse): 2 browser instances × Account C, D
──→ PC 3 (Home): 2 browser instances × Account E, F
──→ PC 4 (Employee 1): 1 browser instance × Account G
──→ PC 5 (Employee 2): 1 browser instance × Account H
──→ PC 6 (Laptop): 1 browser instance × Account I
Result: ~600 listings published in ~1 hour
Frequency: Every 3 days (re-publish for positioning)
Était-ce élégant ? Absolument pas. Était-ce efficace ? Cela m'a permis d'opérer à une échelle qui aurait été impossible manuellement. Pendant que mes concurrents passaient leur journée entière à publier des articles un par un, j'avais tout mon catalogue en ligne sur plusieurs comptes en une heure.
Chapitre 4 : Le pivot — de la publication à l'exploitation
À mesure que l'entreprise grandissait, des outils externes comme PortalHero sont apparus, capables de gérer la publication en masse. J'ai entièrement délégué cette partie. Mais un nouveau problème, plus important, a émergé : la gestion des commandes.
Quand vous avez 10 commandes par jour sur un seul compte, vous les gérez manuellement depuis l'application Wallapop. Ouvrir l'appli, vérifier les nouvelles commandes, noter le code de l'article, aller à l'entrepôt, le trouver, l'emballer, imprimer l'étiquette, l'expédier. Ça va.
Mais nous étions en pleine croissance. Rapide. Nous sommes passés de 10 commandes/jour à près de 100 commandes/jour sur plus de 12 comptes. Chaque compte avait sa propre boîte de réception, ses propres commandes, ses propres étiquettes d'expédition. Mon équipe d'entrepôt avait besoin d'une vue unifiée de toutes les commandes en attente. J'avais besoin d'analyses sur les comptes les plus performants. J'avais besoin de suivre quels articles avaient été vendus, lesquels étaient en attente d'expédition, lesquels avaient été retournés.
L'interface web de Wallapop ne vous donne rien de tout cela. Aucun export. Aucune API. Aucune opération en masse. Juste une application pensée d'abord pour mobile, conçue pour des particuliers vendant leurs vieilles chaussures.
J'avais besoin de données. Et Wallapop n'allait pas me les donner.
Chapitre 5 : Ouvrir le capot
J'ai ouvert les Chrome DevTools sur l'application web de Wallapop et j'ai commencé à observer l'onglet Network.
Chaque clic, chaque chargement de page, chaque défilement — le navigateur effectuait des requêtes HTTP vers api.wallapop.com. Et les réponses étaient du JSON propre et structuré. Les endpoints suivaient des schémas. L'authentification reposait sur un bearer token dans l'en-tête. La pagination était basée sur des curseurs.
J'ai commencé à tout cartographier :
/bff/delivery/orders/ongoing— toutes les commandes actives d'un compte/bff/delivery/orders/{id}— les détails d'une commande, y compris les URL des étiquettes d'expédition/bff/messaging/inbox— toutes les conversations (utile à la fois pour la validation ET l'analyse)/bff/sales/as_seller— l'historique des ventes finalisées/api/v3/user/items— toutes les annonces publiées avec leurs statistiques
J'ai passé des jours à explorer. Chaque requête, chaque réponse, chaque en-tête. Je modifiais les paramètres, j'observais ce qui se passait. J'essayais d'appeler les endpoints avec différents jetons d'authentification. Je retraçais le flux complet du cycle de vie d'une commande : création → acceptation → expédition → livraison → finalisation.
Et j'ai trouvé de l'or. Pas seulement les endpoints évidents, mais aussi des endpoints non documentés. Les détails des commandes groupées (bundles). Les transactions du portefeuille. Les statistiques au niveau du compte. Les URL de téléchargement des étiquettes d'expédition. L'historique des messages de chat avec horodatage.
Personne n'avait publié quoi que ce soit là-dessus. Il n'existait aucune documentation de l'API Wallapop nulle part sur internet. Je construisais cette carte à partir de zéro.
Chapitre 6 : Construire les extracteurs
L'API une fois cartographiée, j'ai commencé à construire des systèmes d'extraction. Pas des scripts vite faits — des pipelines de données de niveau production qui tourneraient toutes les 15 minutes, 24h/24 et 7j/7, sur l'ensemble des 12+ comptes.
L'extracteur de commandes (2 100 lignes)
C'est le cœur de l'exploitation de mon entreprise. Il extrait chaque commande sur tous les comptes et les persiste dans PostgreSQL avec un suivi d'état complet :
- Plus de 20 états de commande — pending, accepted, shipped, in_transit, delivered, completed, cancelled, returned, disputed... chacun avec des données disponibles différentes et des actions requises différentes
- Détection des bundles — Les bundles Wallapop (commandes multi-articles) ont une structure de réponse API totalement différente. L'extracteur les détecte, les décompose en articles individuels et extrait le code LPN de chaque description de produit à l'aide d'expressions régulières
- Création de la vente — Lorsqu'une commande atteint l'état « completed », un enregistrement de vente est automatiquement créé avec : le prix de l'article, la commission de la plateforme, le revenu net, la date de paiement et les informations de l'acheteur
- Suivi des retours — Détecte les retours et crée des enregistrements de retrait qui mettent à jour le statut de l'inventaire
Cet unique extracteur a remplacé ce qui aurait été 2 à 3 employés à temps plein vérifiant manuellement 12 comptes Wallapop toutes les heures.
L'extracteur de conversations
Chaque conversation avec chaque acheteur potentiel, extraite et stockée. Cela me donne quelque chose que Wallapop ne fournit jamais : l'analyse de l'entonnoir de vente.
- Combien de conversations par jour ?
- Quel est le taux de conversion conversation-vente ?
- Quels comptes génèrent le plus d'engagement ?
- À quels moments de la journée les acheteurs écrivent-ils le plus ?
- Le temps de réponse moyen par compte (mes employés répondent-ils assez vite ?)
Aucune de ces données n'existe dans l'interface de Wallapop. Je les ai construites.
L'extracteur d'annonces
Suit chaque article publié sur tous les comptes : vues, favoris, conversations, prix, statut. Cela révèle quels produits performent bien et lesquels sont invisibles.
Un défi technique majeur fut l'anti-oscillation des identifiants de produit. Lorsque les systèmes de Wallapop réindexent une annonce, le product_id peut changer temporairement. Un suivi naïf créerait des enregistrements en double. J'ai construit une logique de détection qui reconnaît ces oscillations et maintient un suivi cohérent.
L'évolution : V1 → V3
Les extracteurs ont traversé 5 versions majeures à mesure que l'entreprise se développait et que j'en apprenais davantage sur l'API :
V1 (2023)
└─ Hardcoded bearer tokens in JSON files
└─ Single account, sequential processing
└─ Manual token refresh every few hours
V2 (2023)
└─ Bearers stored in Google Sheets (shared across scripts)
└─ Multi-account with user_hash tracking
└─ Tkinter UI for employees to paste new bearers
└─ Validation before each extraction run
V2.5 (2024)
└─ Cookie-based auth (no more manual bearer management)
└─ Automatic accessToken refresh via session cookies
└─ JWT decoding for expiration checking
└─ Accounts stay authenticated for weeks
V2.6 (2024)
└─ ThreadPoolExecutor for parallel multi-account extraction
└─ Each account gets its own thread and rate limiting
└─ 12 accounts extracted in parallel instead of sequential
V3 (2024-2025)
└─ Bundle order support (multi-item orders)
└─ LPN extraction from descriptions via regex
└─ Warehouse location enrichment
└─ Cross-reference with preparation Excel from Drive
└─ ~2,100 lines for orders alone
L'anti-détection à grande échelle
Effectuer des milliers d'appels API par jour sur plus de 12 comptes exige un sérieux travail d'anti-détection. Se faire repérer, c'est se faire bannir les comptes — ce qui signifie de l'inventaire perdu, des ventes perdues, du chiffre d'affaires perdu.
- Rotation des User-Agent — Un pool de plus de 50 vrais UA de navigateurs stockés dans PostgreSQL, en rotation à chaque session
- Cadençage des requêtes — Des délais aléatoires entre les requêtes. Pas
sleep(1)— maissleep(random.uniform(0.8, 2.3)). Les intervalles fixes sont un signal de détection - Empreinte des en-têtes — Réplication exacte des en-têtes de requête du navigateur, y compris l'ordre, la casse et les en-têtes optionnels. Une requête issue de la bibliothèque
requestsde Python paraît différente de celle de Chrome, à moins de reproduire chaque en-tête - Cohérence de session — Même UA, mêmes cookies, même jeu d'en-têtes pour toute la durée d'une session. Changer en cours de session est suspect
- Perturbation des images (pour le publieur Selenium) — Transformations OpenCV : bruit gaussien, micro-rotation (0,1-0,5°), variation de luminosité (±3 %), léger étirement. Met en échec le hachage perceptuel tout en restant invisible pour les humains
La guerre des doublons
Quand vous exploitez plus de 12 comptes sur la même place de marché, vous vous heurtez inévitablement à la détection des annonces en double. Les systèmes de Wallapop signalent les annonces qui apparaissent identiques sur plusieurs comptes et peuvent les shadow-bannir ou les supprimer.
J'ai construit une suite complète d'investigation et d'atténuation des doublons :
- Détection des annonces fantômes (shadow) — Des scripts qui vérifient si les annonces sont réellement visibles dans les résultats de recherche (une annonce peut exister dans votre profil mais être invisible pour les acheteurs)
- Parseur des e-mails de suppression de Wallapop — Analyse les fichiers MBOX de Gmail pour identifier quelles annonces ont été supprimées et pourquoi
- Assainisseur de conformité — Analyse les titres et descriptions des annonces à la recherche de « mots-pièges » qui déclenchent une suppression automatisée (certaines catégories de produits, termes restreints)
- Dédoublonnage des titres — Garantit qu'aucun compte n'a d'annonces avec des titres identiques, en utilisant des variations générées
C'était une course aux armements permanente. Wallapop mettait à jour sa détection, j'enquêtais sur les nouveaux schémas, je construisais des contre-mesures et je m'adaptais. Plus de 15 scripts entièrement dédiés à ce problème.
Ce que ce système permet
Aujourd'hui, mes extracteurs tournent automatiquement toutes les 15 minutes via APScheduler. Les données affluent dans PostgreSQL, où des tableaux de bord Retool offrent à mon équipe une visibilité en temps réel sur :
- Toutes les commandes en attente sur l'ensemble des comptes, dans une vue unifiée
- Les analyses de ventes — chiffre d'affaires par compte, par jour, par catégorie de produit
- Les temps de réponse aux conversations — les employés répondent-ils dans le cadre de notre SLA ?
- La performance des annonces — vues, favoris, taux de conversation par article
- Le rapprochement du portefeuille — l'argent présent dans le portefeuille Wallapop correspond-il à nos enregistrements de vente ?
Ce système est unique. Personne d'autre n'a construit ce niveau d'automatisation pour Wallapop. Il existe des entreprises avec des centaines d'annonces qui gèrent tout manuellement parce qu'« il n'y a pas d'API ». J'ai prouvé qu'elle existe — il suffit de la trouver soi-même.
L'arc complet
2023 Q1: Publishing manually → 10 min/item, max 50 items/day
2023 Q2: Selenium bot → 1 min/item, 1 machine
2023 Q3: 6-PC farm via AnyDesk → 600 items/hour across 12 accounts
2023 Q4: Delegated publishing → Focus shifted to operations
2024 Q1: First API reverse engineering → Manual bearer tokens, 1 account
2024 Q2: Multi-account extractors → Bearers in Sheets, UI for team
2024 Q3: Cookie-based auth → No more manual token management
2024 Q4: Parallel extraction → 12 accounts in <5 minutes
2025: Bundles + full ERP integration → 2,100-line orders extractor
Anti-duplicate suite → 15+ investigation scripts
Production scheduler → Automatic every 15 minutes
De 10 minutes par annonce à un système d'extraction entièrement automatisé, multi-comptes et anti-détection fonctionnant 24h/24 et 7j/7. Pas en lisant de la documentation — mais en lisant des paquets réseau.
Les extracteurs sont open source : github.com/AspiranteD/wallapop-data-extractors