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)

import requests 

# Definição dos parâmetros de busca
Classe = "ADI"
NumeroInicial = 5500
NumeroFinal = 6000

for n in range (NumeroFinal-NumeroInicial+1):
    
    # Módulo de geração de URLs
    NumProcesso = str(NumeroFinal-n)
    
    url = ('http://www.stf.jus.br/portal/peticaoInicial/'
           + 'verPeticaoInicial.asp?base='
           + Classe 
           + '&documento=&s1=1&numProcesso=' 
           + NumProcesso)
    
    print (url)
    
    # Módulo básico de extração
    html = requests.get(url).text

    
    # redução do texto às variáveis
    inicio = html.find('processo/verProcessoAndamento.asp?')
    html = html[inicio:]
    
    # Módulo básico de gravação
    nomedoarquivo = ('ADIhtml\\teste' 
                     + Classe 
                     + str(0)*(4-len(NumProcesso)) 
                     + NumProcesso 
                     + '.html')
    
    arquivo = open(nomedoarquivo, 'w', encoding='utf-8')
    arquivo.write(url + ">>>> \n" + html)
Código para extração de dados das páginas de metadados do controle concentrado

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.