Como Construir uma Arquitetura de Web Scraping Multiplataforma com Python

Como Construir uma Arquitetura de Web Scraping Multiplataforma com Python

Extrair dados públicos de ecossistemas heterogêneos é um dos desafios de engenharia de software mais complexos da atualidade. Coletar informações de plataformas de e-commerce consolidadas (como Amazon, Mercado Livre e Vinted) exige estratégias radicalmente distintas daquelas necessárias para redes sociais dinâmicas (como Instagram, Facebook e TikTok).

Enquanto marketplaces estruturam catálogos com paginação previsível, mas contam com defesas rígidas de anti-bot (como Cloudflare e Akamai), plataformas sociais dependem de Single Page Applications (SPAs), rolagem infinita e renderização client-side pesada. Tentar resolver essa variedade com um único script monolítico gera código frágil, difícil de manter e propenso a bloqueios rápidos.

A solução sustentável exige código limpo, desacoplamento e uma arquitetura modular orientada a padrões de projeto em Python.


1. O Desafio da Diversidade de Alvos

Ao estruturar um pipeline para capturar dados de seis plataformas distintas, encontramos dois perfis técnicos claros:

  1. E-commerce Estruturado (Amazon, Mercado Livre, Vinted): Foco em integridade de seletores de preços, disponibilidade de estoque e contorno de desafios de fingerprinting TLS.
  2. Mídias Sociais Dinâmicas (Instagram, TikTok, Facebook): Foco em emulação de comportamento humano, hidratação de estado React/GraphQL e interceptação de chamadas de API internas antes da renderização no DOM.

Para suportar essa variação sem duplicar lógica de infraestrutura, a abordagem correta é aplicar o padrão Strategy aliado a modelos de dados unificados.


2. Arquitetura Modular: O Padrão Strategy na Prática

Em vez de espalhar requisições HTTP e instâncias de navegadores por todo o projeto, centralizamos o ciclo de vida da extração em uma classe base abstrata e derivamos classes especializadas para cada plataforma.

Estrutura do Projeto

text
scraperproject/

├── core/
│ ├── base
scraper.py # Contrato abstrato e utilitários de rede
│ ├── proxymanager.py # Rotação inteligente de proxies
│ └── models.py # Validação e schemas com Pydantic

├── scrapers/
│ ├── amazon.py
│ ├── mercadolivre.py
│ ├── vinted.py
│ ├── tiktok.py
│ └── social
meta.py # Lógica compartilhada para IG e FB

└── main.py # Orquestrador de tarefas

Implementando a Classe Base

Utilizando bibliotecas modernas e assíncronas como httpx para endpoints diretos e playwright para páginas que exigem execução de JavaScript:

python
from abc import ABC, abstractmethod
from typing import Any, Dict, List
import httpx
from core.models import ExtractedItem

class BaseScraper(ABC):
def init(self, proxy: str = None):
self.proxy = proxy
self.headers = {
“User-Agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36”,
“Accept-Language”: “pt-BR,pt;q=0.9,en-US;q=0.8”,
}

@abstractmethod
async def scrape(self, target_url: str) -> List[ExtractedItem]:
    """Método obrigatório para extração dos dados."""
    pass

async def get_client(self) -> httpx.AsyncClient:
    return httpx.AsyncClient(
        headers=self.headers,
        proxy=self.proxy,
        timeout=30.0,
        follow_redirects=True
    )

Cada scraper específico implementa o método scrape, garantindo que o orquestrador trate todas as plataformas sob a mesma interface.


3. Normalização de Dados com Pydantic

Como especialista em IA e engenharia de dados, frequentemente vejo pipelines de machine learning e análise falharem devido a tipos de dados inconsistentes gerados por scrapers. Se o Mercado Livre retorna preços em formato monetário com vírgula e o TikTok retorna contadores de engajamento com sufixos (‘K’, ‘M’), a normalização precisa ocorrer imediatamente após a extração.

python
from pydantic import BaseModel, Field, field_validator
from datetime import datetime
from typing import Optional

class ExtractedItem(BaseModel):
platform: str
sourceid: str
title
orcaption: str
numeric
value: float = Field(default=0.0, description=”Preço ou contagem de engajamento”)
url: str
capturedat: datetime = Field(defaultfactory=datetime.utcnow)

@field_validator("numeric_value", mode="before")
def clean_numeric(cls, v):
    if isinstance(v, (int, float)):
        return float(v)
    if isinstance(v, str):
        clean_str = v.replace("R$", "").replace("$", "").replace(".", "").replace(",", ".").strip()
        if "K" in clean_str.upper():
            return float(clean_str.upper().replace("K", "")) * 1000
        if "M" in clean_str.upper():
            return float(clean_str.upper().replace("M", "")) * 1000000
        return float(clean_str)
    return 0.0

4. Estratégias Técnicas contra Bloqueios e Rate Limits

Para manter a estabilidade do fluxo de coleta nas seis plataformas sem interrupções constantes, quatro práticas técnicas são mandatórias:

  1. Impressão Digital TLS Consistente: Plataformas como Amazon detectam scripts não apenas por User-Agents, mas pela negociação TLS (ciphers e extensões). O uso de bibliotecas como curl_cffi pode ser necessário quando requisições httpx comuns forem barradas na camada de handshake.
  2. Interceptação de Tráfego de Rede (XHR/Fetch): Em redes sociais, evite parsear elementos complexos do DOM sempre que possível. Use o Playwright para escutar eventos de rede (page.on('response', ...)) e capturar as respostas JSON nativas que a própria interface consome.
  3. Backoff Exponencial com Jitter: Implemente repetições inteligentes para lidar com respostas HTTP 429 (Too Many Requests). Adicionar variações aleatórias de tempo entre as chamadas impede que o padrão do scraper seja classificado como automação previsível.
  4. Pool de Proxies Residenciais: Para plataformas de alta sensibilidade, a rotação de IPs residenciais evita bloqueios de sub-redes inteiras de data centers.

5. Fluxo de Execução Recomendado

Um fluxo de trabalho robusto deve operar nas seguintes etapas:

  1. Inspeção de Rede: Identifique se o dado desejado está contido no HTML inicial (SSR) ou se chega via requisição assíncrona (CSR/GraphQL).
  2. Definição de Driver: Aloque o coletor mais leve possível para a tarefa (httpx para chamadas diretas; Playwright apenas quando a execução de scripts for mandatória).
  3. Implementação da Estratégia Modular: Escreva a regra de extração isolada dentro do módulo correspondente da plataforma.
  4. Validação de Tipagem: Garanta que cada item extraído seja validado pelo Pydantic antes de ser enfileirado para persistência (PostgreSQL, MongoDB ou S3).

Conclusão e Próximos Passos

Criar um sistema de web scraping capaz de interagir simultaneamente com redes sociais e gigantes do varejo exige muito mais do que scripts rápidos; requer uma engenharia de dados defensiva, modular e escalável.

Se a sua empresa precisa de pipelines de extração de dados resilientes, arquitetura em Python de alta performance ou integração direta de dados com modelos de Inteligência Artificial, entre em contato para uma consultoria técnica especializada.

Preencha o formulário abaixo para que eu consiga entrar em contato com você.