Como Converter Extratos Bancários em PDF para SQLite Usando Python
Extratos bancários em formato PDF são projetados para leitura humana e impressão, não para consumo automatizado por sistemas. Quando um analista ou desenvolvedor precisa consolidar transações de dezenas de arquivos, a estrutura visual de tabelas e colunas frequentemente quebra em fluxos de texto desalinhados, tornando o processamento manual inviável e sujeito a inconsistências financeiras.
Neste artigo, você aprenderá a construir um pipeline determinístico em Python para extrair transações linha por linha de arquivos PDF e persistir esses registros de forma estruturada em uma base SQLite.
O Desafio: A Natureza Não Estruturada dos PDFs
Ao contrário de arquivos CSV ou JSON, documentos PDF armazenam instruções sobre onde posicionar glifos e caracteres em uma coordenada bidimensional, e não conceitos como linhas e colunas de dados. Para extrair informações financeiras com precisão, a solução precisa lidar com:
- Quebra de linhas: Descrições longas de transações que ocupam duas linhas.
- Padrões numéricos variados: Moedas com separadores de milhar e decimais inconsistentes (ex:
1.250,50vs1,250.50). - Transações mistas: Créditos e débitos identificados por sinais (
+,-) ou sufixos (C,D).
Arquitetura da Solução
Para garantir eficiência e integridade dos dados, o pipeline é dividido em três etapas:
- Extração de Texto Bruto: Utilização da biblioteca
pdfplumberpara manter a coerência espacial do documento. - Parsing e Validação com Expressões Regulares (Regex): Identificação dos componentes de cada transação (data, documento, histórico, valor).
- Persistência em Lote no SQLite: Gravação estruturada utilizando transações seguras no banco de dados local.
Implementação Passo a Passo
1. Configuração do Ambiente
Instale as bibliotecas necessárias via terminal:
bash
pip install pdfplumber
O SQLite já vem embutido na biblioteca padrão do Python através do módulo sqlite3.
2. Criação do Esquema no SQLite
Definir uma tabela otimizada com tipos estritos previne registros corrompidos:
python
import sqlite3
def initdb(dbpath=”extratos.db”):
conn = sqlite3.connect(dbpath)
cursor = conn.cursor()
cursor.execute(”’
CREATE TABLE IF NOT EXISTS transacoes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
data TEXT NOT NULL,
descricao TEXT NOT NULL,
documento TEXT,
valor REAL NOT NULL,
tipo TEXT CHECK(tipo IN (‘CREDITO’, ‘DEBITO’))
)
”’)
cursor.execute(‘CREATE INDEX IF NOT EXISTS idxdata ON transacoes(data);’)
conn.commit()
return conn
3. Extração e Parsing com Regex
Como especialista em IA e engenharia de dados, observo que a chave para uma ingestão confiável é combinar regras determinísticas com sanitização rigorosa antes da inserção.
Suponha um padrão de extrato onde a linha inicia com a data (DD/MM/AAAA), seguida por texto descritivo e finalizada com o valor monetário e um identificador (C ou D):
python
import re
import pdfplumber
TRANSACTION_REGEX = re.compile(
r”^(d{2}/d{2}/d{4})s+(.+?)s+([d.,]+)s*([CD])$”
)
def parsevalor(valorstr, tipostr):
# Converte padrão brasileiro para float padrão (ex: 1.500,50 -> 1500.50)
valorlimpo = valorstr.replace(“.”, “”).replace(“,”, “.”)
valor = float(valorlimpo)
return valor if tipo_str == “C” else -abs(valor)
def processarpdf(pdfpath):
registros = []
with pdfplumber.open(pdfpath) as pdf:
for page in pdf.pages:
texto = page.extracttext()
if not texto:
continue
for linha in texto.split("n"):
linha = linha.strip()
match = TRANSACTION_REGEX.match(linha)
if match:
data, descricao, valor_bruto, tipo_flag = match.groups()
valor_normalizado = parse_valor(valor_bruto, tipo_flag)
tipo = "CREDITO" if tipo_flag == "C" else "DEBITO"
registros.append((
data,
descricao.strip(),
"", # Campo de documento opcional
valor_normalizado,
tipo
))
return registros
4. Persistência em Lote (Batch Insert)
Inserir linha por linha gera sobrecarga desnecessária de I/O. Utilizamos executemany para máxima performance:
python
def salvar_transacoes(conn, registros):
query = ”’
INSERT INTO transacoes (data, descricao, documento, valor, tipo)
VALUES (?, ?, ?, ?, ?)
”’
with conn:
conn.executemany(query, registros)
print(f”{len(registros)} transações inseridas com sucesso.”)
5. Execução Integrada
python
def main():
dbconn = initdb(“financeiro.db”)
dados = processarpdf(“extratobancario.pdf”)
salvartransacoes(dbconn, dados)
db_conn.close()
if name == “main“:
main()
Boas Práticas e Resiliência
- Controle de Duplicidade: Adicione um hash único baseado em
(data, descricao, valor)para evitar reinserir as mesmas transações ao processar extratos sobrepostos. - Fallback para IA: Quando o layout bancário muda drasticamente ou o PDF contém texto digitalizado como imagem, pipelines modernos integram modelos de visão computacional ou OCR com LLMs locais para categorização semântica.
Precisa Escalar sua Automação de Dados?
Estruturar dados legados e automatizar processos contábeis exige precisão de código e arquitetura resiliente para evitar perdas financeiras.
Se a sua empresa precisa de pipelines de extração robustos, integração com bancos de dados ou soluções personalizadas com Inteligência Artificial, entre em contato com Thiago Programador para uma consultoria técnica especializada.


