Monitorar preços, estoques e catálogos visuais em múltiplos e-commerces diariamente é uma necessidade crítica para inteligência de mercado. No entanto, quando a escala atinge dezenas de milhares de requisições, pipelines amadores falham: bloqueios por IP aumentam, o download síncrono de imagens esgota a memória do servidor e os custos de armazenamento explodem sem uma estratégia de ingestão contínua.
Neste artigo técnico, vamos explorar como arquitetar um sistema robusto de extração de dados e imagens em massa utilizando Python, processamento assíncrono e persistência direta no Amazon S3.
1. O Desafio Estrutural: Texto vs. Imagens em Larga Escala
Extrair metadados em texto (título, preço, SKU) é relativamente leve. O verdadeiro gargalo de performance reside no tratamento de mídia. Baixar milhares de imagens de alta resolução para o disco local antes de enviar para a nuvem cria problemas de I/O, enche o armazenamento efêmero de containers e desacelera os workers de extração.
Para resolver isso, a arquitetura deve operar com streams em memória (in-memory buffer) e upload multipart para o AWS S3, garantindo zero dependência de disco rígido local.
2. Arquitetura do Pipeline Diário
O ecossistema ideal para lidar com scrapers diários distribui as responsabilidades em etapas desacopladas:
- Orquestração e Agendamento: Um agendador (Airflow, Prefect ou AWS EventBridge com Lambda) dispara os jobs diários com base nos catálogos-alvo.
- Engine de Extração Assíncrona: Uso de
httpxouaiohttppara endpoints de API internos do e-commerce, ouPlaywrightem modo headless para renderizar Single Page Applications (SPAs). - Pool de Proxies e Rotação de Headers: Implementação de proxies residenciais e emulação de comportamento de navegação (evitando captchas e bloqueios de Cloudflare/Akamai).
- Ingestão Direta no Amazon S3: Uso do SDK
boto3para persistir dados estruturados em formato Parquet/JSONL e streaming de imagens.
3. Implementação Prática: Streaming de Imagem Direto para o S3
Em vez de salvar as imagens localmente via open('img.jpg', 'wb'), consumimos o stream HTTP e o enviamos diretamente ao bucket via boto3:
python
import asyncio
import aiohttp
import boto3
from io import BytesIO
s3client = boto3.client(‘s3’)
BUCKETNAME = ‘ecommerce-lake-daily’
async def streamimagetos3(session: aiohttp.ClientSession, imageurl: str, s3key: str):
async with session.get(imageurl) as response:
if response.status == 200:
content = await response.read()
buffer = BytesIO(content)
# Upload em memória para o S3
loop = asyncio.get_running_loop()
await loop.run_in_executor(
None,
lambda: s3_client.upload_fileobj(
buffer,
BUCKET_NAME,
s3_key,
ExtraArgs={'ContentType': response.headers.get('Content-Type', 'image/jpeg')}
)
)
return f"s3://{BUCKET_NAME}/{s3_key}"
return None
Essa abordagem reduz drasticamente a latência e o consumo de disco do cluster de scraping.
4. Boas Práticas para Resiliência em Produção
- Particionamento de Dados no S3: Estruture o bucket por data de execução:
s3://bucket/ano=2024/mes=05/dia=10/loja_id/dados.parquet. Isso viabiliza consultas eficientes via AWS Athena ou DuckDB posterior. - Rate Limiting Adaptativo: Utilize limitadores de concorrência com
asyncio.Semaphorepara não derrubar a loja monitorada nem gerar alertas excessivos nos sistemas de segurança perimetral. - Tratamento de Mudanças de Layout: Como especialista em IA e engenharia de dados, recomendo integrar parsers secundários com modelos de linguagem (LLMs) leves para remapear seletores CSS dinamicamente quando a estrutura do HTML mudar.
Conclusão e Próximos Passos
Construir um scraper diário corporativo exige mais do que scripts isolados; demanda uma infraestrutura de dados orientada à resiliência, escalabilidade e custo otimizado na nuvem.
Se a sua empresa precisa estruturar um pipeline contínuo de extração de dados de e-commerce, alimentar datalakes para precificação dinâmica ou implementar inteligência competitiva com visão computacional, entre em contato comigo através da página de consultoria do Thiago Programador para desenharmos uma solução sob medida.


