STF - Controle Concentrado: Gerador de Banco de Dados
Combinação de dois algoritmos em Python que realizam (i) a extração de ações de controle concentrado e (ii) a sua organização em uma tabela. Esses dados são coletados a partir dos resultados das pesquisas na página ADI, ADC, ADO e ADPF, sendo gravados arquivos com os dados de cada processo, que podem ser convertidos em um arquivo .csv pelo segundo programa.
Tutorial do código de extração: Extrator Básico de Dados Judiciais.
Tutorial do código de geração de CSV: Organização dos dados em tabelas.
1. Módulo Extrator
1.1 Código em Python (versão 1.1, de 3/10/2020)
2. Descrição do programa
Observando com cuidado a página de pesquisa que é automatizada por este algoritmo, você perceberá que se trata de uma página no formato antigo do site, que é diferente do layout que você acessa hoje no www.stf.jus.br.
Esta pesquisa envolve as bases ADI, ADC, ADO e ADPF. Além disso, ela tem uma base BJMC, que tem REs com repercussão geral e alguns outros processos. A realização de buscas nessa página conduz a páginas com metadados acerca dos processos.
As informações não são completas, mas ela contém alguns campos que não estão disponíveis em outras buscas, como o dispositivo legal impugnado e uma classificação dos resultados.
Além disso, essa é uma página em que os dados estão condensados em blocos, o que torna a sua extração mais simples, motivo pelo qual ela é um ótimo ponto de partida para desenvolver habilidades de extração e de organização de dados.
Para extrair os dados dessa página, você pode utilizar o seguinte algoritmo em Python. Para compreender bem os seus termos, leia o tutorial Extrator Básico de Dados Judiciais. Esse é um programa que não gera uma tabela organizada (para isso há outro programa), mas uma conjunto de arquivos, com os dados de cada processo, gravados no diretório ADIhtml (ou em qualquer outro que você definir, adaptando o programa).
Para informações básicas sobre programação em Python e sobre os programas que é necessário instalar para poder utilizar esse código, acesse o Curso de Programação para Juristas.
2. Módulo Gerador de CSV
2.1 Código: versão 1.2 (1/11/20)
# importação de bibliotecas
import os
import csv
# módulo ListaDeArquivos: gera a lista de processoss no diretório
relacao = os.listdir("ADIhtml")
# módulo FunçãoExtrair: define a função extrair, para extrair um trecho de uma string, a partir de um marcador de início e um marcador de fim
def extrair(fonte,MarcadorInicio, MarcadorFim):
inicio = fonte.find(MarcadorInicio)
inicio = inicio + len(MarcadorInicio)
fim = fonte.find(MarcadorFim, inicio)
return fonte[inicio:fim]
# funções de limpeza
def limpar(fonte): # útil para textos em LN. retira parágrafos iniciais e converte quebras de linha em '//'
fonte = fonte.strip(' ')
fonte = fonte.strip('\n')
fonte = fonte.strip('\n')
fonte = fonte.strip('\n')
fonte = fonte.strip('\n')
fonte = fonte.strip(' ')
fonte = fonte.strip('\n')
fonte = fonte.strip('\n')
fonte = fonte.strip('\n')
fonte = fonte.strip(' ')
fonte = fonte.strip(' ')
fonte = fonte.strip(' ')
fonte = fonte.strip(' ')
fonte = fonte.strip(' ')
fonte = fonte.replace('\n','//')
fonte = fonte.replace(' ',' ')
return fonte
def limpar2(fonte): #útil para campos com início com espaços. exclui quebras de linha.
fonte = fonte.replace('\n','')
fonte = fonte.strip(' ')
fonte = fonte.strip(' ')
fonte = fonte.strip('-')
fonte = fonte.strip(' ')
fonte = fonte.strip(' ')
fonte = fonte.strip(' ')
return fonte
# módulo de iteração: define um sistema de iteração para analisar os os processos listados no diretório
for n in range (len(relacao)):
# módulo básico de leitura, gerando a string html
nomedoarquivo = relacao.pop()
arquivo = open('ADIhtml\\'+nomedoarquivo, 'r', encoding='utf-8')
html = arquivo.read()
arquivo.close()
# definição das variáveis dos campos a serem extraídos e atribuição de valor vazio a todas elas, para que que, caso não sejam encontrados valores no documento, sejam gravados valores 'NA' (Not Available)
classe = 'NA'
liminar = 'NA'
numero = 'NA'
origem = 'NA'
entrada = 'NA'
distribuicao = 'NA'
requerente = 'NA'
requerido = 'NA'
dispositivoquestionado ='NA'
resultadoliminar = 'NA'
resultadofinal = 'NA'
decisaomonofinal = 'NA'
fundamento = 'NA'
indexacao = 'NA'
# módulo de extração das variáveis
## exclusão dos processos sem dados
processoexistente = html.find('<div><h3><strong>')
if processoexistente == -1:
print (nomedoarquivo + ',Processo inexistente')
else:
##extrai classe+numero
classeenumero = extrair(html,'<div><h3><strong>','</strong>')
## definição de campo: número
classeenumero_split = classeenumero.split(' - ')
numero = classeenumero_split[1]
### definição de campo: com liminar (S/N)
if 'Liminar' in classeenumero:
liminar = 's'
else:
liminar = 'n'
## definição de campo: classe
classe = classeenumero_split[0].split(' (')
classe = classe[0]
classe = classe.replace('AÇÃO DIRETA DE INCONSTITUCIONALIDADE', 'ADI')
classe = classe.replace('ACAO DIRETA DE INCONSTITUCIONALIDADE', 'ADI')
## definição de campo: incidente
incidente = extrair(html, 'incidente=', '"')
## definição de campo: origem
origem = extrair(html,'Origem:</td><td><strong>','</strong>')
## definição de campo: incidente
entrada = extrair(html,'Entrada no STF:</td><td><strong>','</strong>')
## definição de campo: relator
relator = extrair(html,'Relator:</td><td><strong>','</strong>')
relator = relator.replace('MINISTRO','')
relator = relator.replace('MINISTRA','')
## definição de campo: distribuição
distribuicao = extrair(html,'Distribuído:</td><td><strong>','</strong>')
## definição de campo: requerente
requerente = extrair(html,'Requerente: <strong>','</strong>')
if '(CF 103, ' in requerente:
requerentesplit = requerente.split('(CF 103, ')
requerente = requerentesplit[0]
requerente = requerente.strip()
requerentetipo = requerentesplit[1]
requerentetipo = requerentetipo.replace(')','')
requerentetipo = requerentetipo.replace('0','')
else:
requerentetipo = 'NA'
## definição de campo: requerido
requerido = extrair(html,'Requerido :<strong>','</strong>')
## definição de campo: dispositivo questionado
dispositivoquestionado = extrair(html,'Dispositivo Legal Questionado</b></strong><br /><pre>','</pre>')
dispositivoquestionado = limpar(dispositivoquestionado)
## definição de campo: resultado da liminar
resultadoliminar = extrair(html,'Resultado da Liminar</b></strong><br /><br />','<br />')
## definição de campo: resultado final
resultadofinal = extrair(html,'Resultado Final</b></strong><br /><br />','<br />')
## definição de campo: decisão monocrática final
if 'Decisão Monocrática Final</b></strong><br /><pre>' in html:
decisaomonofinal = extrair(html,'Decisão Monocrática Final</b></strong><br /><pre>','</pre>')
decisaomonofinal = limpar(decisaomonofinal)
else:
decisaomonofinal = 'NA'
## definição de campo: fundamento
if 'Fundamentação Constitucional</b></strong><br /><pre>' in html:
fundamento = extrair(html,'Fundamentação Constitucional</b></strong><br /><pre>','</pre>')
fundamento = limpar2(fundamento)
else:
fundamento = 'NA'
## definição de campo: fundamento
if 'Indexação</b></strong><br /><pre>' in html:
indexacao = extrair(html,'Indexação</b></strong><br /><pre>','</pre>')
indexacao = limpar2(indexacao)
else:
indexacao = 'NA'
### criação da variável dados extraídos, com uma lista de dados
dados = [classe, numero, incidente, liminar, origem, entrada, relator, distribuicao, requerente, requerentetipo, requerido, dispositivoquestionado, resultadoliminar, resultadofinal, decisaomonofinal, fundamento, indexacao]
campos = 'classe, numero, incidente, liminar, origem, entrada, relator, distribuicao, requerente, requerentetipo, requerido, dispositivoquestionado, resultadoliminar, resultadofinal, decisaomonofinal, fundamento, indexacao' #inserir aqui o conteúdo da lista acima, trocando [] por ''
## módulo gravação do cabeçalho
if n == 0:
arquivoaberto = open("ADI.csv", mode='w', encoding="utf-8", newline='')
arquivoaberto_csv = csv.writer(arquivoaberto, delimiter=',')
campos = campos.split(',')
arquivoaberto_csv.writerow(campos)
arquivoaberto.close()
## módulo gravação dos dados
arquivoaberto = open("ADI.csv", mode='a+', encoding="utf-8", newline='')
arquivoaberto_csv = csv.writer(arquivoaberto, delimiter=',')
arquivoaberto_csv.writerow(dados)
arquivoaberto.close()
print (nomedoarquivo + ',Dados processados')
print ("Gravado arquivo ADI.csv, com todos os dados contidos no seu diretório ADIhtml, no diretório em que você executou o presente extrator")
2.2 Descrição do programa
Este programa parte do pressuposto de que você gravou os dados obtidos com o Módulo de Extração em um diretório, que deve ter somente os arquivos extraídos (a presença de outros arquivos impede o funcionamento adequado do programa).
Este algoritmo organizará os dados daqueles arquivos em uma tabela consolidada, promovendo já uma limpeza preliminar da maioria dos campos. Para compreender as funcionalidades usadas neste módulo, leia o seguinte tutorial com o passo a passo de construção de um módulo gerador de CSV: Organização dos dados em tabelas.