Pular para o conteúdo principal

Capítulo 3: Lidando com Diferentes Tipos de Arquivo

Introdução​

Documentos do mundo real vêm em muitos formatos, cada um com desafios únicos. Este capítulo aborda estratégias para lidar com PDFs, imagens, tabelas e dados estruturados.

Desafios com PDFs​

PDFs são o formato de documento mais comum, mas também o mais desafiador:

Áreas Problemáticas​

DesafioDescriçãoSolução
PDFs escaneadosImagens, não textoProcessamento OCR
TabelasEstrutura perdidaExtratores especializados
Multi-colunaOrdem de leitura incorretaAnálise de layout
Cabeçalhos/RodapésRuído repetidoFiltragem

Opções de Extração de PDF​

# Opção 1: Básica (PyPDF2/PyPDFLoader)
from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader("document.pdf")
# Prós: Rápido, simples
# Contras: Ruim com layouts complexos

# Opção 2: Melhor para tabelas (PDFPlumber)
from langchain.document_loaders import PDFPlumberLoader
loader = PDFPlumberLoader("document.pdf")
# Prós: Melhor extração de tabelas
# Contras: Mais lento

# Opção 3: Melhor qualidade (Unstructured)
from langchain.document_loaders import UnstructuredPDFLoader
loader = UnstructuredPDFLoader(
"document.pdf",
mode="elements", # Preserva a estrutura
strategy="hi_res" # Melhor qualidade
)
# Prós: Melhor qualidade geral
# Contras: Requer dependências adicionais

OCR para Documentos Escaneados​

Para PDFs escaneados e imagens:

# Usando Tesseract OCR
from langchain.document_loaders import UnstructuredPDFLoader

loader = UnstructuredPDFLoader(
"scanned_document.pdf",
strategy="ocr_only",
ocr_languages="eng"
)
documents = loader.load()

# Usando Amazon Textract
from langchain.document_loaders import AmazonTextractPDFLoader

loader = AmazonTextractPDFLoader(
"scanned.pdf",
client=textract_client
)

Boas Práticas de OCR​

  1. Pré-processar imagens - Corrigir inclinação, melhorar contraste
  2. Especificar idioma - Melhora a precisão
  3. Pós-processar texto - Corrigir erros comuns de OCR
  4. Pontuação de confiança - Marcar extrações com baixa confiança

Lidando com Tabelas​

Tabelas exigem tratamento especial para preservar a estrutura:

# Método 1: Converter para Markdown
from langchain.document_loaders import UnstructuredPDFLoader

loader = UnstructuredPDFLoader(
"report.pdf",
mode="elements"
)
docs = loader.load()

# Tabelas vêm como elementos estruturados
for doc in docs:
if doc.metadata.get("category") == "Table":
# Processar tabela de forma especial
table_markdown = convert_table_to_markdown(doc)

# Método 2: Usando Camelot para PDFs
import camelot

tables = camelot.read_pdf("document.pdf", pages="all")
for table in tables:
df = table.df
markdown = df.to_markdown()

Estratégia de Divisão de Tabelas​

def chunk_with_tables(documents):
chunks = []

for doc in documents:
if is_table(doc):
# Manter tabelas como blocos únicos
chunks.append(doc)
else:
# Divisão normal para texto
text_chunks = splitter.split_documents([doc])
chunks.extend(text_chunks)

return chunks

Imagens em Documentos​

Extraia e processe imagens:

# Extrair imagens de PDF
import fitz # PyMuPDF

doc = fitz.open("document.pdf")
for page_num, page in enumerate(doc):
images = page.get_images()
for img_index, img in enumerate(images):
# Extrair imagem
xref = img[0]
base_image = doc.extract_image(xref)
image_bytes = base_image["image"]

# Processar com modelo de visão
description = vision_model.describe(image_bytes)

# Adicionar descrição ao documento

Integração com Modelo de Visão​

from langchain.chat_models import ChatOpenAI

# Usar GPT-4 Vision para compreensão de imagens
vision_llm = ChatOpenAI(model="gpt-4-vision-preview")

def describe_image(image_path):
response = vision_llm.invoke([
{
"type": "image_url",
"image_url": f"data:image/jpeg;base64,{base64_image}"
},
{
"type": "text",
"text": "Descreva esta imagem em detalhes para busca de documentos."
}
])
return response.content

Dados Estruturados​

JSON/JSONL​

from langchain.document_loaders import JSONLoader

loader = JSONLoader(
file_path="data.json",
jq_schema=".data[].content",
text_content=False
)

CSV​

from langchain.document_loaders import CSVLoader

loader = CSVLoader(
file_path="data.csv",
csv_args={"delimiter": ","},
source_column="source"
)

# Para CSVs grandes, processe em lotes
import pandas as pd

def load_csv_in_batches(file_path, batch_size=1000):
for chunk in pd.read_csv(file_path, chunksize=batch_size):
yield from chunk.to_dict('records')

Bancos de Dados SQL​

from langchain.document_loaders import SQLDatabaseLoader
from langchain.utilities import SQLDatabase

db = SQLDatabase.from_uri("postgresql://user:pass@localhost/db")

loader = SQLDatabaseLoader(
db=db,
query="SELECT id, content, metadata FROM documents WHERE active = true"
)

Pipeline Completo de Processamento​

from pathlib import Path

def process_document(file_path: str):
"""Processador universal de documentos"""
path = Path(file_path)
extension = path.suffix.lower()

loaders = {
".pdf": lambda p: UnstructuredPDFLoader(p, strategy="hi_res"),
".docx": lambda p: Docx2txtLoader(p),
".txt": lambda p: TextLoader(p, encoding="utf-8"),
".html": lambda p: UnstructuredHTMLLoader(p),
".md": lambda p: UnstructuredMarkdownLoader(p),
".csv": lambda p: CSVLoader(p),
".json": lambda p: JSONLoader(p, jq_schema=".[]")
}

if extension not in loaders:
raise ValueError(f"Unsupported file type: {extension}")

loader = loaders[extension](str(path))
documents = loader.load()

# Adicionar metadados do arquivo
for doc in documents:
doc.metadata["file_name"] = path.name
doc.metadata["file_type"] = extension
doc.metadata["file_size"] = path.stat().st_size

return documents

Resumo​

Tipo de ArquivoMelhor LoaderObservações
PDF (texto)PDFPlumberLoaderSuporte avançado a tabelas
PDF (escaneado)UnstructuredPDFLoader + OCRUse a estratégia hi_res
WordDocx2txtLoaderRápido e confiável
HTMLUnstructuredHTMLLoaderRemove tags
CSVCSVLoaderLote para arquivos grandes
ImagensModelos de visãoPara imagens embutidas

Principais Pontos​

  1. PDFs são complexos - Use o loader adequado para sua necessidade
  2. OCR para documentos escaneados - Essencial para PDFs baseados em imagem
  3. Tabelas exigem tratamento especial - Não divida blocos entre linhas
  4. Imagens precisam de descrição - Use modelos de visão
  5. Teste seu pipeline - Com amostras representativas

Próximos Passos​

Teste seu conhecimento com o Quiz do Módulo 2!