Cómo pasé de dedicar 10 minutos a cada anuncio, a ejecutar bots de Selenium en 6 PC remotos, a aplicar ingeniería inversa a una API privada y construir sistemas de extracción que nadie más ha construido, todo porque Wallapop no tiene una API pública.
Una nota sobre el alcance. Todo lo que se describe aquí se construyó para operar mi propio negocio: las cuentas de vendedor, el inventario y los datos de pedidos son míos. Son herramientas operativas internas que gestionan mis propios anuncios y pedidos, con peticiones conservadoras, limitadas por tasa y a ritmo humano, porque la plataforma no expone ninguna API pública para vendedores. Es infraestructura para un negocio que yo opero, no herramientas dirigidas a nadie más.
Capítulo 1: el infierno manual
Wallapop es el mayor mercado de segunda mano de España. Millones de usuarios. Miles de millones en volumen de transacciones. Y en 2023 no había ninguna forma de publicar anuncios de forma masiva.
Cada anuncio había que crearlo manualmente a través de su interfaz web. Subir fotos. Escribir un título. Escribir una descripción. Poner un precio. Elegir una categoría. Fijar la ubicación. Pulsar publicar. De 5 a 10 minutos por artículo.
Cuando llevas un negocio de comercio electrónico vendiendo liquidaciones de Amazon, puedes tener entre 500 y 600 artículos en tu catálogo en cualquier momento. Echa cuentas: 600 artículos × 7 minutos = 70 horas de trabajo manual solo para publicarlo todo una vez. Y tienes que volver a publicar cada pocos días para mantenerte visible en los resultados de búsqueda.
Eso no es un modelo de negocio. Es un trabajo de introducción de datos.
Capítulo 2: el bot de Selenium
Así que construí un bot. Un sistema de automatización de navegador basado en Selenium capaz de navegar por la interfaz web de Wallapop, rellenar todos los campos, subir imágenes y publicar, de forma automática.
La arquitectura era sencilla, pero exigía resolver varios problemas nada triviales:
- XPaths dinámicos: el frontend en React de Wallapop genera estructuras del DOM distintas según la categoría, el estado y las opciones de envío. Creé un archivo
xpaths.jsonconfigurable que asociaba cada campo a su selector, de modo que cuando Wallapop cambiaba su interfaz (cosa que pasaba con regularidad) solo tenía que actualizar la configuración - Aleatorización de imágenes: subir exactamente las mismas imágenes de producto en varias cuentas activaría la detección de duplicados. Construí un pipeline con OpenCV que aplicaba transformaciones sutiles a cada imagen: microrrotación, inyección de ruido, variación de brillo, ligero estiramiento. Suficiente para engañar al hashing perceptual, invisible al ojo humano
- Tiempos antidetección: un bot que rellena formularios en 0,5 segundos parece un bot. Añadí retardos aleatorizados entre acciones (variación en la velocidad de escritura, pausa antes de hacer clic, comportamiento de desplazamiento) para imitar la interacción humana. Cada anuncio tardaba alrededor de 1 minuto, más lento de lo que podría ir una máquina, pero lo bastante rápido para ser útil
Capítulo 3: la granja de 6 PC
Un minuto por anuncio. 600 artículos. Eso son 10 horas en una sola máquina. Seguía siendo demasiado lento, sobre todo cuando hay que volver a publicar cada 3 días para el posicionamiento SEO.
Mi solución fue la fuerza bruta: monté 5-6 PC, me conecté a todos ellos de forma remota mediante AnyDesk y ejecuté varias instancias del bot simultáneamente en cada máquina. Cada PC tenía su propia cuenta de Wallapop, su propio perfil de navegador, su propia IP (redes distintas).
El flujo de trabajo era así:
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)
¿Era elegante? En absoluto. ¿Era eficaz? Me permitía operar a una escala que habría sido imposible de forma manual. Mientras los competidores pasaban el día entero publicando artículos uno a uno, yo tenía todo mi catálogo activo en varias cuentas en una hora.
Capítulo 4: el giro, de publicar a operar
A medida que el negocio crecía, aparecieron herramientas externas como PortalHero capaces de gestionar la publicación masiva. Delegué esa parte por completo. Pero surgió un problema nuevo y mayor: la gestión de pedidos.
Cuando tienes 10 pedidos al día de una cuenta, los gestionas manualmente desde la app de Wallapop. Abres la app, miras si hay pedidos nuevos, apuntas el código del artículo, vas al almacén, lo encuentras, lo embalas, imprimes la etiqueta y lo envías. Bien.
Pero estábamos escalando. Rápido. Pasamos de 10 pedidos al día a casi 100 pedidos al día repartidos entre más de 12 cuentas. Cada cuenta tenía su propia bandeja de entrada, sus propios pedidos, sus propias etiquetas de envío. Mi equipo de almacén necesitaba una vista unificada de todos los pedidos pendientes. Yo necesitaba analíticas sobre qué cuentas rendían mejor. Necesitaba hacer seguimiento de qué artículos se habían vendido, cuáles estaban pendientes de envío y cuáles se habían devuelto.
La interfaz web de Wallapop no te da nada de esto. Sin exportaciones. Sin API. Sin operaciones masivas. Solo una app pensada para móvil y diseñada para particulares que venden sus zapatos viejos.
Necesitaba datos. Y Wallapop no iba a dármelos.
Capítulo 5: abriendo el capó
Abrí las DevTools de Chrome en la web de Wallapop y empecé a vigilar la pestaña Network.
Cada clic, cada carga de página, cada desplazamiento: el navegador hacía peticiones HTTP a api.wallapop.com. Y las respuestas eran JSON limpio y estructurado. Los endpoints seguían patrones. La autenticación era un token bearer en la cabecera. La paginación estaba basada en cursores.
Empecé a mapearlo todo:
/bff/delivery/orders/ongoing: todos los pedidos activos de una cuenta/bff/delivery/orders/{id}: detalles del pedido, incluidas las URL de las etiquetas de envío/bff/messaging/inbox: todas las conversaciones (útil tanto para validación COMO para analíticas)/bff/sales/as_seller: historial de ventas completadas/api/v3/user/items: todos los anuncios publicados con sus estadísticas
Pasé días explorando. Cada petición, cada respuesta, cada cabecera. Cambiaba parámetros y observaba qué ocurría. Probaba a llamar a los endpoints con distintos tokens de autenticación. Trazaba el flujo del ciclo de vida completo de un pedido: creación → aceptación → envío → entrega → finalización.
Y encontré oro. No solo los endpoints evidentes, sino otros sin documentar. Detalles de pedidos de tipo bundle. Transacciones del monedero. Estadísticas a nivel de cuenta. URL de descarga de etiquetas de envío. Historial de mensajes del chat con marcas de tiempo.
Nadie había publicado nada de esto. No había ninguna documentación de la API de Wallapop en ningún rincón de internet. Estaba construyendo este mapa desde cero.
Capítulo 6: construyendo los extractores
Con la API mapeada, empecé a construir sistemas de extracción. No scripts rápidos, sino pipelines de datos de nivel de producción que se ejecutarían cada 15 minutos, 24/7, en las más de 12 cuentas.
El extractor de pedidos (2.100 líneas)
Este es el núcleo de las operaciones de mi negocio. Extrae todos los pedidos de todas las cuentas y los persiste en PostgreSQL con un seguimiento completo de estados:
- Más de 20 estados de pedido: pending, accepted, shipped, in_transit, delivered, completed, cancelled, returned, disputed... cada uno con datos disponibles distintos y acciones requeridas distintas
- Detección de bundles: los bundles de Wallapop (pedidos de varios artículos) tienen una estructura de respuesta de API completamente diferente. El extractor los detecta, los descompone en artículos individuales y extrae el código LPN de la descripción de cada producto mediante regex
- Creación de ventas: cuando un pedido llega a "completed", crea automáticamente un registro de venta con: precio del artículo, comisión de la plataforma, ingreso neto, fecha de pago e información del comprador
- Seguimiento de devoluciones: detecta devoluciones y crea registros de retirada que actualizan el estado del inventario
Este único extractor sustituyó lo que habrían sido 2 o 3 empleados a tiempo completo revisando manualmente 12 cuentas de Wallapop cada hora.
El extractor de chats
Cada conversación con cada comprador potencial, extraída y almacenada. Esto me da algo que Wallapop nunca proporciona: analíticas del embudo de ventas.
- ¿Cuántas conversaciones al día?
- ¿Cuál es la tasa de conversión de conversación a venta?
- ¿Qué cuentas generan más interacción?
- ¿A qué horas del día escriben más los compradores?
- Tiempo medio de respuesta por cuenta (¿responden mis empleados con suficiente rapidez?)
Ninguno de estos datos existe en la interfaz de Wallapop. Yo los construí.
El extractor de anuncios
Hace seguimiento de cada artículo publicado en todas las cuentas: visitas, favoritos, conversaciones, precio, estado. Esto revela qué productos rinden bien y cuáles son invisibles.
Un reto de ingeniería clave fue la anti-oscilación de los IDs de producto. Cuando los sistemas de Wallapop reindexan un anuncio, el product_id puede cambiar temporalmente. Un seguimiento ingenuo crearía registros duplicados. Construí una lógica de detección que reconoce estas oscilaciones y mantiene un seguimiento coherente.
La evolución: V1 → V3
Los extractores pasaron por 5 versiones principales a medida que el negocio escalaba y yo aprendía más sobre la 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
Antidetección a escala
Hacer miles de llamadas a la API al día en más de 12 cuentas exige un trabajo serio de antidetección. Si te pillan, las cuentas se banean, lo que significa inventario perdido, ventas perdidas, ingresos perdidos.
- Rotación de User-Agent: un conjunto de más de 50 UA reales de navegador almacenados en PostgreSQL, rotados por sesión
- Tiempos de las peticiones: retardos aleatorizados entre peticiones. No
sleep(1), sinosleep(random.uniform(0.8, 2.3)). Los intervalos fijos son una señal de detección - Fingerprinting de cabeceras: replicación exacta de las cabeceras de petición del navegador, incluyendo el orden, las mayúsculas/minúsculas y las cabeceras opcionales. Una petición de la librería
requestsde Python tiene un aspecto distinto al de Chrome a menos que iguales todas las cabeceras - Coherencia de sesión: el mismo UA, las mismas cookies, el mismo conjunto de cabeceras durante toda la sesión. Cambiar a mitad de sesión es sospechoso
- Perturbación de imágenes (para el publicador de Selenium): transformaciones con OpenCV: ruido gaussiano, microrrotación (0,1-0,5°), variación de brillo (±3%), ligero estiramiento. Derrota al hashing perceptual sin dejar de ser invisible para las personas
Las guerras de los duplicados
Cuando operas más de 12 cuentas en el mismo mercado, te topas inevitablemente con la detección de anuncios duplicados. Los sistemas de Wallapop marcan los anuncios que parecen idénticos en varias cuentas y pueden aplicarles shadow ban o eliminarlos.
Construí una suite completa de investigación y mitigación de duplicados:
- Detección de anuncios fantasma: scripts que comprueban si los anuncios son realmente visibles en los resultados de búsqueda (un anuncio puede existir en tu perfil pero ser invisible para los compradores)
- Parser de correos de eliminación de Wallapop: analiza archivos MBOX de Gmail para identificar qué anuncios se eliminaron y por qué
- Sanitizador de políticas: revisa los títulos y descripciones de los anuncios en busca de "palabras trampa" que disparan la eliminación automática (ciertas categorías de producto, términos restringidos)
- Deduplicación de títulos: garantiza que ninguna pareja de cuentas tenga anuncios con títulos idénticos, usando variaciones generadas
Fue una carrera armamentística constante. Wallapop actualizaba su detección, yo investigaba los nuevos patrones, construía contramedidas y me adaptaba. Más de 15 scripts dedicados por completo a este problema.
Lo que permite este sistema
Hoy mis extractores se ejecutan automáticamente cada 15 minutos mediante APScheduler. Los datos fluyen a PostgreSQL, donde los dashboards de Retool dan a mi equipo visibilidad en tiempo real de:
- Todos los pedidos pendientes de todas las cuentas en una vista unificada
- Analíticas de ventas: ingresos por cuenta, por día, por categoría de producto
- Tiempos de respuesta del chat: ¿responden los empleados dentro de nuestro SLA?
- Rendimiento de los anuncios: visitas, favoritos, tasa de conversación por artículo
- Conciliación del monedero: ¿coincide el dinero del monedero de Wallapop con nuestros registros de ventas?
Este sistema es único. Nadie más ha construido este nivel de automatización para Wallapop. Hay empresas con cientos de anuncios que lo gestionan todo manualmente porque "no hay API". Yo demostré que sí la hay: solo tienes que encontrarla por ti mismo.
El arco completo
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 minutos por anuncio a un sistema de extracción totalmente automatizado, multicuenta y con antidetección funcionando 24/7. No leyendo documentación, sino leyendo paquetes de red.
Los extractores son de código abierto: github.com/AspiranteD/wallapop-data-extractors