Voltar as noticias
Como criei um rastreador de arbitragem de relógios em 2 semanas
Casos de UsoAltaEN

Como criei um rastreador de arbitragem de relógios em 2 semanas

Dev.to - MCP·5 de maio de 2026

TL;DR — Eu construí o Watch Arbitrage Tracker (Apify Store, GitHub): um ator Crawlee + Camoufox que coleta dados de 6 marketplaces de relógios de luxo em paralelo, calcula o preço médio entre plataformas para qualquer referência Patek/Rolex/AP e envia uma notificação no Telegram no momento em que uma listagem cai mais de X% abaixo do mercado. Menos de $1/mês para uso típico de revendedores. Também funciona como um servidor MCP para que Claude Desktop / Cursor / ChatGPT possam consultar o feed ao vivo em inglês simples.

A parte interessante não é a construção — são os 5 bugs que eu tive que corrigir em produção após o lançamento público, e a matemática da mediana entre plataformas que transforma "dados coletados" em um verdadeiro sinal de arbitragem.

O problema (real, validado, doloroso)

Revendedores de relógios profissionais — as pessoas que compram e vendem Patek 5711, Rolex Daytona, AP Royal Oak usados — passam mais de 3 horas por dia atualizando 6 marketplaces de revendedores em busca de inventário mal precificado. O trabalho é mecânico: abrir Chrono24, pesquisar 10 números de referência, comparar preços, mudar para WatchBox, repetir, mudar para Bobs Watches, repetir...

Existem ferramentas existentes (Watchcharts $79/mês, ChronoPulse $500/mês, Bezel Club), mas todas têm o mesmo defeito: ancoragem em uma única plataforma. Elas informam o preço médio no Chrono24, não no mercado. Isso é inútil para arbitragem — o objetivo é encontrar diferenças entre plataformas.

A matemática que realmente importa:

spread = cross_platform_median(refX) - listing_price(refX, platformY)

Se um Submariner 124060 está listado a $11,900 no WatchBox, mas a verdadeira mediana do mercado (calculada entre Chrono24 + WatchBox + Bobs) é $13,988 — isso representa um spread de 28,2%. Esse é o alerta que vale a pena acordar um revendedor às 3 da manhã.

Nenhuma ferramenta que eu consegui encontrar calcula uma verdadeira mediana entre plataformas. Então eu construí uma.

A pilha

Pilha padrão do Apify com uma reviravolta personalizada:

  • Crawlee + Camoufox (fork stealthy do Firefox) para resiliência contra bots. Chrono24 + Bobs Watches estão atrás do Cloudflare; Camoufox + rotação de proxy do Apify lidam com eles de forma confiável.
  • TypeScript em toda parte (modo estrito, Node 24).
  • Arquivos de crawler por plataforma (src/crawlers/{chrono24,watchbox,bobs,...}.ts) — cada um com ~100 linhas, todos se conformam ao mesmo formato de Listing para que o agregador não se importe de qual plataforma uma listagem veio.
  • Agregador (src/aggregator.ts) — agrupa listagens por sub-referência extraída (mais sobre isso no Bug #5 abaixo), calcula uma mediana ajustada, detecta spreads.
  • Dispatcher de alertas (src/alerts.ts) — Telegram por oportunidade com deduplicação de 24h.
  • Modo duplo — o mesmo código-fonte roda como um crawler em lote (cron agendado) E como um servidor MCP em modo Standby do Apify, expondo 3 ferramentas HTTP para agentes de IA.

Total: ~2000 LOC em 25 arquivos. Repositório: github.com/DataKazKN/watch-arbitrage-mcp.

Os 5 bugs que tive que corrigir AO VIVO em produção

Eu lancei o ator como um ator público pago Pay-Per-Event do Apify depois que minha última execução de teste parecia limpa. Então eu executei o ator com meu próprio token de bot do Telegram + 3 referências no dia seguinte ao lançamento e imediatamente encontrei 5 bugs que teriam feito o ator parecer quebrado para usuários de primeira viagem.

Bug #1 — WatchBox redirecionou toda pesquisa para uma página de splash (0 listagens extraídas)

A URL do crawler era:

https://www.the1916company.com/search/pre-owned/?q=rolex+116500LN

Na nossa verificação de 2026-05-04, isso retornou uma grade de azulejos com 8 listagens. Dois dias depois: zero. Por quê?

A inspeção do DOM ao vivo via Playwright revelou: o WatchBox agora redireciona qualquer consulta contendo uma palavra-chave de marca (rolex, patek, audemars) para uma página de splash de sugestão de marca que não tem azulejos de produto. O padrão de URL anterior quebrou silenciosamente.

A correção foi pequena, mas só foi possível encontrar indo às mãos:

// ANTES — incluía prefixo da marca → redireciona para splash → 0 azulejos
return `https://www.the1916company.com/search/pre-owned/?q=${encodeURIComponent(`${brand} ${ref}`)}`;

// DEPOIS — referência nua → chega na página de resultados real /search/?q=
return `https://www.the1916company.com/search/?q=${encodeURIComponent(ref)}`;

Lição: nunca confie em padrões de URL documentados por mais de 30 dias para sites que você não controla. Programe execuções mensais de verificação do DOM, mesmo em plataformas estáveis.

Bug #2 — Bobs Watches ponto de pesquisa errado (0 produtos renderizados)

Mesma padrão, causa diferente. O formulário da página inicial do Bobs Watches:

<form action="/shop" method="get">
  <input name="query" type="text">
</form>

O ponto de pesquisa real é /shop?query=124060 — mas eu estava roteando através de seus antigos URLs de catálogo /{brand}-{model}-{page}.html (que cobriam apenas as 7 principais coleções E inflacionavam o tamanho da amostra além da referência exata do usuário).

// ANTES — roteamento de URL de catálogo obsoleto
return `https://www.bobswatches.com/rolex-submariner-1.html`;

// DEPOIS — ponto de pesquisa real
return `https://www.bobswatches.com/shop?query=${encodeURIComponent(ref)}`;

Bônus: o intersticial "Um instante..." do Cloudflare leva ~8s para limpar com Camoufox. O timeout original de 30s do waitForSelector estava ocasionalmente muito apertado; aumentei para 45s. Menos execuções com zero falso.

B

Contexto Triplo Up

O rastreador de arbitragem de relógios oferece uma solução inovadora para revendedores que buscam otimizar suas operações. Ao integrar dados de múltiplas plataformas, ele melhora a eficiência e a precisão na identificação de oportunidades de arbitragem, essencial para o mercado brasileiro.

Noticias relacionadas

Gostou do conteudo?

Receba toda semana as principais novidades sobre WebMCP.