Como Fazer uma Extração Completa de Catálogo com Python: Texto, Imagens e Especificações

Aprenda a estruturar um pipeline em Python para extração de dados de produtos, incluindo especificações técnicas e download eficiente de imagens.

Extrair um catálogo completo de produtos a partir de um site público é uma necessidade comum em projetos de migração de plataforma, inteligência de mercado ou treinamento de modelos analíticos. No entanto, o que parece ser uma tarefa simples de extração pontual pode rapidamente se tornar complexo: estruturas de páginas com renderização dinâmica, dezenas de milhares de imagens em alta resolução e especificações técnicas aninhadas em tabelas irregulares costumam interromper scripts ingênuos.

Neste artigo, você entenderá como arquitetar um pipeline de extração de dados eficiente em Python, separando a coleta de metadados do download de arquivos de mídia e garantindo integridade estrutural do início ao fim.

1. Desacoplando Metadados e Mídia

O erro mais frequente em raspagens pontuais é tentar baixar imagens pesadas no mesmo fluxo síncrono em que se navega pelas páginas de produto. Isso eleva o tempo de execução e aumenta a chance de falhas por timeout.

A abordagem correta envolve duas fases bem delimitadas:

  1. Fase de Coleta Estrutural: Navegação pelas listagens e páginas de detalhe para coletar URLs canônicas, títulos, preços, SKUs, tabelas técnicas e URLs diretas das imagens, salvando esses registros em formato intermediário (JSONL ou banco SQLite).
  2. Fase de Ingestão de Ativos: Leitura da lista de URLs de imagens e download concorrente em lotes controlados.

2. Mapeamento de Dados e JSON-LD

Antes de escrever seletores CSS complexos para cada campo visual da página, verifique o código-fonte em busca de scripts do tipo application/ld+json. A maioria dos e-commerces modernos injeta dados estruturados de schema de produto diretamente no HTML para fins de SEO.

Exemplo prático de extração combinada em Python usando BeautifulSoup:

python
import json
from bs4 import BeautifulSoup

def extrairdadosproduto(htmlcontent: str) -> dict:
soup = BeautifulSoup(html
content, ‘html.parser’)
dados = {}

# Tentativa de extração via JSON-LD (Schema.org)
schema_tag = soup.find('script', type='application/ld+json')
if schema_tag:
    try:
        schema_data = json.loads(schema_tag.string)
        if schema_data.get('@type') == 'Product':
            dados['titulo'] = schema_data.get('name')
            dados['descricao'] = schema_data.get('description')
            dados['sku'] = schema_data.get('sku')
            dados['imagens'] = schema_data.get('image', [])
    except (json.JSONDecodeError, TypeError):
        pass

# Fallback para seletores CSS se campos críticos estiverem ausentes
if not dados.get('titulo'):
    h1 = soup.find('h1', class_='product-title')
    dados['titulo'] = h1.get_text(strip=True) if h1 else None

# Coleta de especificações técnicas em tabela
especificacoes = {}
for linha in soup.select('table.specs-table tr'):
    colunas = linha.find_all(['th', 'td'])
    if len(colunas) == 2:
        chave = colunas[0].get_text(strip=True)
        valor = colunas[1].get_text(strip=True)
        especificacoes[chave] = valor

dados['especificacoes'] = especificacoes
return dados

3. Download Concorrente de Imagens com aiohttp

Quando lidamos com milhares de produtos, baixar imagens sequencialmente inviabiliza a operação. O uso de asyncio e aiohttp com um limitador de semáforo permite transferências rápidas sem saturar a banda local ou disparar bloqueios no servidor de origem.

python
import asyncio
import aiohttp
from pathlib import Path

async def baixarimagem(session: aiohttp.ClientSession, url: str, destino: Path, semaforo: asyncio.Semaphore):
async with semaforo:
try:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=15)) as resposta:
if resposta.status == 200:
conteudo = await resposta.read()
destino.write
bytes(conteudo)
except Exception as erro:
print(f”Falha ao baixar {url}: {erro}”)

async def pipelinedownload(urlsimagens: list[tuple[str, Path]], maxconexoes: int = 10):
semaforo = asyncio.Semaphore(max
conexoes)
async with aiohttp.ClientSession() as session:
tarefas = [
baixarimagem(session, url, caminho, semaforo)
for url, caminho in urls
imagens
] await asyncio.gather(*tarefas)

4. Normalização com Técnicas de IA

Como especialista em IA e processamento de dados, observo que um dos maiores gargalos pós-extração é a inconsistência textual de tabelas técnicas (por exemplo, variações como ‘Voltagem: 110V’, ‘Tensão: 127V’, ‘Alimentação: 110 Volts’). Em vez de criar centenas de expressões regulares manuais, pipelines avançados utilizam modelos de linguagem compactos em modo batch ou técnicas de similaridade por embeddings para agrupar e padronizar chaves de atributos automaticamente em um esquema unificado.

5. Resiliência Operacional

Mesmo para uma extração única, implemente:

  • Mecanismo de Retentativa: Aplique retentativas com backoff exponencial via biblioteca tenacity.
  • Checkpoints: Salve o progresso a cada página processada para permitir retomada imediata em caso de falha de conexão.
  • Headers Reais: Envie cabeçalhos de requisição realistas (User-Agent atualizado, Accept-Language e Referer) para evitar rejeições básicas por proxies.

Se sua empresa necessita de uma extração completa e precisa de dados de catálogos complexos, com tratamento de especificações e entrega estruturada pronta para consumo, conheça as soluções em automação e engenharia de dados oferecidas pela consultoria do Thiago Programador.

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