Como passei de gastar 10 minutos por anúncio, a executar bots Selenium em 6 PCs remotos, até fazer engenharia inversa de uma API privada e construir sistemas de extração que mais ninguém construiu — tudo porque o Wallapop não tem uma API pública.
Uma nota sobre o âmbito. Tudo o que aqui está foi construído para gerir o meu próprio negócio: as contas de vendedor, o inventário e os dados de encomendas são todos meus. São ferramentas operacionais internas que gerem os meus próprios anúncios e encomendas — com pedidos conservadores, com limitação de taxa e a um ritmo humano — porque a plataforma não expõe nenhuma API pública para vendedores. É infraestrutura para um negócio que opero, não ferramentas apontadas a mais ninguém.
Capítulo 1: O Inferno Manual
O Wallapop é o maior marketplace de segunda mão de Espanha. Milhões de utilizadores. Milhares de milhões em volume de transações. E em 2023, não havia forma de publicar anúncios em massa.
Cada anúncio tinha de ser criado manualmente através da interface web. Carregar fotografias. Escrever um título. Escrever uma descrição. Definir um preço. Escolher uma categoria. Definir a localização. Clicar em publicar. 5 a 10 minutos por artigo.
Quando se gere um negócio de comércio eletrónico que vende liquidações da Amazon, pode ter-se 500 a 600 artigos no catálogo a qualquer momento. Façam as contas: 600 artigos × 7 minutos = 70 horas de trabalho manual só para listar tudo uma vez. E é preciso voltar a publicar de poucos em poucos dias para se manter visível nos resultados de pesquisa.
Isto não é um modelo de negócio. É um trabalho de introdução de dados.
Capítulo 2: O Bot Selenium
Por isso, construí um bot. Um sistema de automação de navegador baseado em Selenium capaz de navegar pela interface web do Wallapop, preencher todos os campos, carregar imagens e publicar — automaticamente.
A arquitetura era direta, mas exigia resolver vários problemas nada triviais:
- XPaths dinâmicos — O frontend em React do Wallapop gera estruturas de DOM diferentes consoante a categoria, o estado e as opções de envio. Criei um ficheiro
xpaths.jsonconfigurável que mapeava cada campo ao seu seletor, de modo que, quando o Wallapop mudava a interface (o que acontecia regularmente), só tinha de atualizar a configuração - Aleatorização de imagens — Carregar exatamente as mesmas imagens de produto em várias contas acionaria a deteção de duplicados. Construí um pipeline em OpenCV que aplicava transformações subtis a cada imagem: micro-rotação, injeção de ruído, variação de brilho, ligeiro esticamento. O suficiente para enganar o hashing percetual, invisível ao olho humano
- Temporização anti-deteção — Um bot que preenche formulários em 0,5 segundos parece um bot. Adicionei atrasos aleatórios entre ações (variação da velocidade de escrita, pausa antes de clicar, comportamento de scroll) para imitar a interação humana. Cada anúncio demorava cerca de 1 minuto — mais lento do que uma máquina poderia ir, mas rápido o suficiente para ser útil
Capítulo 3: A Quinta de 6 PCs
Um minuto por anúncio. 600 artigos. São 10 horas numa só máquina. Ainda demasiado lento, sobretudo quando é preciso voltar a publicar a cada 3 dias para o posicionamento em SEO.
A minha solução foi a força bruta: montei 5-6 PCs, liguei-me a todos eles remotamente via AnyDesk e executei várias instâncias do bot em simultâneo em cada máquina. Cada PC tinha a sua própria conta Wallapop, o seu próprio perfil de navegador, o seu próprio IP (redes diferentes).
O fluxo de trabalho era assim:
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? De todo. Era eficaz? Permitiu-me operar a uma escala que teria sido impossível manualmente. Enquanto os concorrentes passavam o dia inteiro a publicar artigos um a um, eu tinha o meu catálogo completo online em várias contas numa hora.
Capítulo 4: A Viragem — Da Publicação às Operações
À medida que o negócio crescia, surgiram ferramentas externas como o PortalHero capazes de tratar da publicação em massa. Deleguei essa parte por completo. Mas surgiu um novo problema, maior: a gestão de encomendas.
Quando se têm 10 encomendas por dia numa só conta, geram-se manualmente a partir da aplicação Wallapop. Abrir a app, verificar se há novas encomendas, anotar o código do artigo, ir ao armazém, encontrá-lo, embalá-lo, imprimir a etiqueta, enviá-lo. Tudo bem.
Mas estávamos a crescer. Rápido. Passámos de 10 encomendas/dia para quase 100 encomendas/dia em mais de 12 contas. Cada conta tinha a sua caixa de entrada, as suas encomendas, as suas etiquetas de envio. A minha equipa de armazém precisava de uma visão unificada de todas as encomendas pendentes. Eu precisava de análises sobre quais as contas com melhor desempenho. Precisava de acompanhar quais os artigos vendidos, quais os pendentes de envio, quais os devolvidos.
A interface web do Wallapop não dá nada disto. Sem exportações. Sem API. Sem operações em massa. Apenas uma aplicação concebida para telemóvel, pensada para particulares que vendem os seus sapatos velhos.
Eu precisava de dados. E o Wallapop não mos ia dar.
Capítulo 5: Abrir o Capô
Abri as Chrome DevTools na aplicação web do Wallapop e comecei a observar o separador Network.
Cada clique, cada carregamento de página, cada scroll — o navegador fazia pedidos HTTP a api.wallapop.com. E as respostas eram JSON limpo e estruturado. Os endpoints seguiam padrões. A autenticação era um bearer token no cabeçalho. A paginação era baseada em cursor.
Comecei a mapear tudo:
/bff/delivery/orders/ongoing— todas as encomendas ativas de uma conta/bff/delivery/orders/{id}— detalhes da encomenda, incluindo os URLs das etiquetas de envio/bff/messaging/inbox— todas as conversas (úteis para validação E análise)/bff/sales/as_seller— histórico de vendas concluídas/api/v3/user/items— todos os anúncios publicados com estatísticas
Passei dias a explorar. Cada pedido, cada resposta, cada cabeçalho. Mudava parâmetros, via o que acontecia. Tentava chamar endpoints com diferentes tokens de autenticação. Seguia o fluxo de um ciclo de vida completo de uma encomenda: criação → aceitação → envio → entrega → conclusão.
E encontrei ouro. Não apenas os endpoints óbvios, mas também os não documentados. Detalhes de encomendas em pacote (bundle). Transações da carteira. Estatísticas ao nível da conta. URLs de descarregamento de etiquetas de envio. Histórico de mensagens de chat com data e hora.
Ninguém tinha publicado nada disto. Não havia documentação da API do Wallapop em lado nenhum da internet. Eu estava a construir este mapa do zero.
Capítulo 6: Construir os Extratores
Com a API mapeada, comecei a construir sistemas de extração. Não scripts rápidos — pipelines de dados de nível de produção que correriam a cada 15 minutos, 24 horas por dia, 7 dias por semana, em todas as 12+ contas.
O Extrator de Encomendas (2.100 linhas)
Este é o núcleo das operações do meu negócio. Extrai todas as encomendas de todas as contas e persiste-as em PostgreSQL com seguimento de estado completo:
- Mais de 20 estados de encomenda — pending, accepted, shipped, in_transit, delivered, completed, cancelled, returned, disputed... cada um com dados diferentes disponíveis e ações diferentes necessárias
- Deteção de pacotes (bundles) — Os pacotes do Wallapop (encomendas com vários artigos) têm uma estrutura de resposta de API completamente diferente. O extrator deteta-os, decompõe-os em artigos individuais e extrai o código LPN de cada descrição de produto através de regex
- Criação de venda — Quando uma encomenda atinge o estado "completed", cria automaticamente um registo de venda com: preço do artigo, comissão da plataforma, receita líquida, data de pagamento, dados do comprador
- Seguimento de devoluções — Deteta devoluções e cria registos de retirada que atualizam o estado do inventário
Este único extrator substituiu o que teriam sido 2 a 3 funcionários a tempo inteiro a verificar manualmente 12 contas Wallapop a cada hora.
O Extrator de Chats
Cada conversa com cada potencial comprador, extraída e armazenada. Isto dá-me algo que o Wallapop nunca disponibiliza: análise do funil de vendas.
- Quantas conversas por dia?
- Qual é a taxa de conversão de conversa em venda?
- Que contas geram mais interação?
- A que horas do dia os compradores enviam mais mensagens?
- Tempo médio de resposta por conta (os meus funcionários estão a responder com rapidez suficiente?)
Nenhum destes dados existe na interface do Wallapop. Eu construí-os.
O Extrator de Anúncios
Acompanha cada artigo publicado em todas as contas: visualizações, favoritos, conversas, preço, estado. Isto revela quais os produtos com bom desempenho e quais os que são invisíveis.
Um desafio de engenharia fundamental foi a anti-oscilação dos IDs de produto. Quando os sistemas do Wallapop reindexam um anúncio, o product_id pode mudar temporariamente. Um seguimento ingénuo criaria registos duplicados. Construí uma lógica de deteção que reconhece estas oscilações e mantém um seguimento consistente.
A Evolução: V1 → V3
Os extratores passaram por 5 versões principais à medida que o negócio crescia e eu aprendia mais sobre a 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
Anti-Deteção à Escala
Fazer milhares de chamadas à API por dia em mais de 12 contas exige um trabalho sério de anti-deteção. Se for apanhado, as contas são banidas — o que significa inventário perdido, vendas perdidas, receita perdida.
- Rotação de User-Agent — Conjunto de mais de 50 UAs reais de navegador armazenados em PostgreSQL, rodados por sessão
- Temporização de pedidos — Atrasos aleatórios entre pedidos. Não
sleep(1)— massleep(random.uniform(0.8, 2.3)). Intervalos fixos são um sinal de deteção - Fingerprinting de cabeçalhos — Replicação exata dos cabeçalhos de pedido do navegador, incluindo ordem, capitalização e cabeçalhos opcionais. Um pedido da biblioteca
requestsdo Python parece diferente do Chrome, a menos que se corresponda a cada cabeçalho - Consistência de sessão — O mesmo UA, os mesmos cookies, o mesmo conjunto de cabeçalhos durante toda a sessão. Mudar a meio da sessão é suspeito
- Perturbação de imagens (para o publicador em Selenium) — Transformações OpenCV: ruído gaussiano, micro-rotação (0,1-0,5°), variação de brilho (±3%), ligeiro esticamento. Derrota o hashing percetual ao mesmo tempo que é invisível para os humanos
As Guerras dos Duplicados
Quando se operam mais de 12 contas no mesmo marketplace, inevitavelmente esbarra-se na deteção de anúncios duplicados. Os sistemas do Wallapop sinalizam anúncios que parecem idênticos em várias contas e podem aplicar-lhes shadow-ban ou eliminá-los.
Construí um conjunto completo de investigação e mitigação anti-duplicados:
- Deteção de anúncios-sombra (shadow listings) — Scripts que verificam se os anúncios estão realmente visíveis nos resultados de pesquisa (um anúncio pode existir no teu perfil mas ser invisível para os compradores)
- Analisador de e-mails de eliminação do Wallapop — Analisa ficheiros MBOX do Gmail para identificar quais os anúncios removidos e porquê
- Sanitizador de políticas — Analisa títulos e descrições de anúncios em busca de "palavras-armadilha" que acionam a remoção automática (certas categorias de produto, termos restritos)
- Deduplicação de títulos — Garante que não há duas contas com anúncios de títulos idênticos, usando variações geradas
Foi uma corrida ao armamento constante. O Wallapop atualizava a deteção, eu investigava os novos padrões, construía contramedidas e adaptava-me. Mais de 15 scripts dedicados inteiramente a este problema.
O Que Este Sistema Permite
Hoje, os meus extratores correm automaticamente a cada 15 minutos via APScheduler. Os dados fluem para o PostgreSQL, onde os dashboards do Retool dão à minha equipa visibilidade em tempo real sobre:
- Todas as encomendas pendentes de todas as contas numa só visão unificada
- Análise de vendas — receita por conta, por dia, por categoria de produto
- Tempos de resposta no chat — os funcionários estão a responder dentro do nosso SLA?
- Desempenho dos anúncios — visualizações, favoritos, taxa de conversa por artigo
- Reconciliação da carteira — o dinheiro na carteira do Wallapop corresponde aos nossos registos de venda?
Este sistema é único. Mais ninguém construiu este nível de automação para o Wallapop. Há empresas com centenas de anúncios que gerem tudo manualmente porque "não há API". Eu provei que há — basta encontrá-la por conta própria.
O 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 anúncio a um sistema de extração totalmente automatizado, multiconta, com anti-deteção, a correr 24 horas por dia, 7 dias por semana. Não por ler documentação — por ler pacotes de rede.
Os extratores são de código aberto: github.com/AspiranteD/wallapop-data-extractors