Como Construir um Coletor Escalável de Dados e Imagens de Marketplace com Python
Monitorar preços, analisar a concorrência e catalogar produtos são tarefas centrais para negócios que atuam no comércio eletrônico. No entanto, extrair dados estruturados e mídias visuais de marketplaces impõe barreiras técnicas significativas: renderização dinâmica via JavaScript, limitação de taxa (rate limiting), compressão de imagens em formatos proprietários e bloqueios baseados em padrões de tráfego.
Construir um coletor eficiente vai além de disparar requisições HTTP básicas. É necessário desenhar uma arquitetura que separe a extração de metadados do processamento de mídias pesadas, garantindo integridade e alto rendimento sem comprometer a estabilidade do sistema.
1. O Desafio da Extração Simultânea de Dados e Mídias
Ao raspar marketplaces, encontramos duas cargas de trabalho distintas:
- I/O bound leve (Metadados): Textos, preços, SKUs e atributos técnicos estruturados em JSON ou HTML.
- I/O bound pesado (Imagens): Download de dezenas de imagens em alta resolução por produto, exigindo alta vazão de rede, validação de integridade e armazenamento otimizado.
Se o fluxo síncrono tradicional for adotado, o download de uma imagem de 2 MB pode travar a extração textual de centenas de produtos. Por isso, a separação de responsabilidades em filas assíncronas é mandatória.
2. Arquitetura da Solução: Metadados Primeiro, Imagens Depois
A abordagem mais eficiente envolve dividir o coletor em dois estágios independentes:
[Marketplace]│
▼
[Extrator Assíncrono (Scrapy / aiohttp)]
│
├──► [Banco de Dados / Fila (Redis / PostgreSQL)] ──► Metadados (Preço, SKU, Specs)
│
└──► [Pipeline de Mídia (Worker Assíncrono)] │
├── Deduplicação via Hash (MD5/SHA256)
├── Redimensionamento/Conversão (WebP)
└── Upload (S3 / Storage Local)
Tecnologias Recomendadas
- Scrapy ou Playwright: Para orquestração de requisições e contorno de conteúdo dinâmico.
- HTTPX / aiohttp: Para requisições assíncronas sem overhead de navegador.
- Pillow / aiofiles: Para manipulação e salvamento assíncrono de binários de imagem.
3. Implementando o Download Assíncrono de Imagens
Para evitar gargalos de memória e bloqueios por conexões simultâneas excessivas, utilizamos semáforos (asyncio.Semaphore) para controlar a concorrência.
Veja um padrão de implementação em Python moderno:
python
import asyncio
import hashlib
from pathlib import Path
import httpx
SEMAPHORELIMIT = 10
OUTPUTDIR = Path(“downloads/images”)
OUTPUTDIR.mkdir(parents=True, existok=True)
async def downloadimage(client: httpx.AsyncClient, semaphore: asyncio.Semaphore, url: str) -> str | None:
async with semaphore:
try:
response = await client.get(url, timeout=15.0)
response.raisefor_status()
# Gera nome único baseado no conteúdo para evitar duplicatas
content_hash = hashlib.sha256(response.content).hexdigest()[:16]
file_path = OUTPUT_DIR / f"{content_hash}.jpg"
if not file_path.exists():
file_path.write_bytes(response.content)
return str(file_path)
except httpx.HTTPError as err:
# Log estruturado de falha de conexão
return None
async def processcatalog(imageurls: list[str]):
semaphore = asyncio.Semaphore(SEMAPHORE_LIMIT)
headers = {“User-Agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36”}
async with httpx.AsyncClient(headers=headers, follow_redirects=True) as client:
tasks = [download_image(client, semaphore, url) for url in image_urls]
results = await asyncio.gather(*tasks)
return [r for r in results if r is not None]
Como especialista em IA e engenharia de dados, recomendo sempre computar o hash do conteúdo da imagem antes de persistir no disco. Marketplaces frequentemente replicam as mesmas imagens entre diferentes anúncios; a deduplicação precoce economiza espaço em disco e largura de banda.
4. Estratégias Essenciais de Resiliência
Para garantir que o coletor opere de forma contínua sem interrupções operacionais:
- Rotação de Proxies e Cabeçalhos: Alterne pools de proxies residenciais para distribuir o IP de origem e emule headers realistas (
Accept-Language,Sec-Ch-Ua). - Backoff Exponencial: Se o servidor retornar códigos
429 (Too Many Requests)ou503, pause as tarefas aumentando progressivamente o intervalo entre tentativas. - Tratamento de Lazy Loading: Muitos catálogos carregam imagens apenas no scroll. Garanta que o extrator capture as tags corretas (como
data-srcou atributos dentro de scripts JSON-LD incorporados).
Conclusão e Próximos Passos
A automação de scraping de marketplace com Python viabiliza inteligência competitiva e sincronização de inventários. Contudo, transformar scripts pontuais em sistemas resilientes de missão crítica exige arquitetura distribuída, gestão de falhas e conformidade técnica.
Se sua empresa precisa de uma infraestrutura robusta para extração de dados e automação de catálogos em larga escala, entre em contato para uma consultoria técnica especializada e descubra como implementar coletores de alta performance sob medida para o seu ecossistema.


