github jtrecenti/juscraper v0.5.0

7 hours ago

Added

  • TJMG cposg: consulta processual de 2º grau sem captcha, com partes e advogados (nome e OAB). Aceita CNJ ou o número TJMG (processo_interno do cjsg) e devolve uma linha por recurso, com classe, assunto, câmara, situação, datas e a coluna partes (lista de {tipo, nome, baixa, advogados}). Recursos em segredo de justiça vêm com segredo_justica=True e sem partes.
  • Novo agregador falcao (FalcaoScraper) para a Jurisprudência Nacional da Justiça do Trabalho (sistema do CSJT em jurisprudencia.jt.jus.br, endpoint público /no-auth/pesquisa). Uma busca cobre o TST e os 24 TRTs. listar_decisoes(pesquisa, paginas=None, **kwargs), com o par listar_decisoes_download/listar_decisoes_parse, devolve um pd.DataFrame com as colunas canônicas processo, colecao, tribunal, relator, classe, classe_sigla, ementa (texto sem HTML), data_julgamento e data_juntada, além dos campos brutos de cada coleção, exceto os highlight*, que incluem marcações de busca e variantes anonimizadas. Na coleção precedentes, processo é uma chave legível como TST-SUM-392 ou TST-OJ-SBDI2-130; precedentes regionais sem id usam o idTema, como TRT9-idTema43-IUJ_7_TRT9. O filtro colecao escolhe entre acordaos (default), sentencas, decisoesmonocraticas, precedentes e recursorevista. Os demais filtros são tribunais, relator, orgao_julgador, classe (sigla, como em classe_sigla), fase_processual, prioridade, tem_ementa, somente_ementa, ordenacao e data_juntada_inicio/data_juntada_fim, que podem ser usados sozinhos. Kwargs desconhecidos levantam TypeError, e query/termo são aceitos com DeprecationWarning. Particularidades do backend: tamanho_pagina só aceita 5 ou 10; a busca para em 10000 resultados, com UserWarning quando paginas=None atinge o teto; o bloqueio do WAF levanta BotChallengeBlockedError; e o bloqueio de IP por excesso de requisições, que dura horas, levanta requests.HTTPError sem retry. Quando a coleta ou o parsing de listar_decisoes falha, as páginas já recebidas ficam num diretório temporário e uma nota da exceção informa o caminho, para recuperar o resultado parcial com listar_decisoes_parse; não há retomada automática. Cada listar_decisoes_download grava num subdiretório próprio.
  • TJPE cpopg: consulta processos de 1º grau na consulta pública do PJe (pje.cloud.tjpe.jus.br/1g/), com o mesmo retorno do cpopg dos TRFs, inclusive download_pecas=True. Processo sob segredo de justiça não aparece na consulta pública e sai como linha só com id_cnj. O site fica atrás de um AWS WAF que desafia de forma intermitente: o cookie aws-waf-token é obtido com Playwright só quando o desafio aparece; sem o Playwright instalado, o cpopg funciona enquanto o WAF não desafiar e levanta ImportError quando desafia. Desafio repetido logo após a renovação do cookie, ou cookie que não pôde ser obtido (Chromium do Playwright ausente, cookie não emitido no prazo), levanta WafChallengeError, subclasse de BotChallengeBlockedError, e interrompe o lote em vez de marcar cada processo como não encontrado; o mesmo vale para o ImportError no download das peças.
  • Extra pip install "juscraper[waf]", com o Playwright usado pelo STF e pelo TJPE. O extra juscraper[stf] continua instalando o mesmo, e as mensagens de erro passam a citar [waf].
  • JusbrScraper aceita politica= no construtor para ajustar, campo a campo, os perfis HTTP "listagem" (lista de processos e detalhes, timeout de 15 s) e "documento" (texto e binário, timeout de 30 s): timeout, max_retries, base_backoff, retryable_statuses, retry_on_timeout e retry_on_connection_error. Exemplo: jus.scraper("jusbr", politica={"documento": {"timeout": 10}}). Perfil ou campo desconhecido levanta ValueError.
  • JusBR e PDPJ: auth_govbr() obtém o token JWT pelo login no gov.br, no Google Chrome, Chromium ou Microsoft Edge instalado, aberto com perfil temporário no portal de serviços do PDPJ, com o novo extra govbr (pip install 'juscraper[govbr]'). O navegador abre como processo comum, sem as flags de automação do Playwright, que só se conecta por CDP para escutar a rede: com navigator.webdriver ligado, o captcha do gov.br recusava a resposta correta. navegador= aponta o executável quando ele não é encontrado. O token é capturado da resposta do endpoint de token do SSO do PJe, que traz também o refresh token, ou, na falta dela, do cabeçalho Authorization das chamadas do portal. Com refresh token, o access token é renovado sozinho antes de vencer, em qualquer requisição dos dois scrapers. A credencial fica em $XDG_CONFIG_HOME/juscraper/pdpj_token.json (default ~/.config/...), com permissão 0600, compartilhada por JusBR e PDPJ; salvar=False desliga a gravação. Sem token=, os construtores carregam a credencial da variável de ambiente PDPJ_JWT (o JusBR aceita também JUSBR_JWT) e depois do cache, ignorando com aviso a que estiver vencida. Se o SSO recusar ou não responder à renovação, a requisição levanta ErroSsoPdpj (subclasse de RuntimeError) e a coleta para, sem retry. Nos métodos em lote (cpopg e download_documents do JusBR; existe com lista, cpopg, documentos, movimentos, partes e download_documents do PDPJ), as falhas anteriores vão numa nota do erro, como no 401. A recusa (RenovacaoPdpjError) pede novo auth_govbr(); na indisponibilidade (SsoPdpjIndisponivelError), a chamada seguinte tenta renovar de novo. O login exige navegador com janela e não roda no Colab nem em CI. Refs #22.
  • STF listar_decisoes aceita checkpoint_dir e resume=True para retomar coletas interrompidas. Preserva páginas em disco, valida a compatibilidade antes de requisitar e reinicia apenas a janela incompleta, sem misturar tentativas. Sem diretório, não grava checkpoints.
  • ComunicaCNJScraper.listar_comunicacoes aceita numero_processo, enviado à API como numeroProcesso, só com os dígitos. O termo livre (pesquisa) não encontra as comunicações de um processo pelo número. Com numero_processo, pesquisa passa a ser opcional; sem nenhum dos dois, o método levanta ValueError antes da requisição, onde antes levantava ValidationError pela falta de pesquisa.
  • PdpjScraper(politica=...) ajusta por campo os perfis listagem e documento, como politica={"documento": {"timeout": 20}}; o que não for passado fica como o raspador declara. Os campos aceitos são timeout, max_retries, base_backoff, retryable_statuses, retry_on_timeout e retry_on_connection_error.
  • TRF3 cjsg: busca de jurisprudência no portal web.trf3.jus.br/jurisprudencia, com cjsg_download/cjsg_parse. O filtro base escolhe entre acordaos (default, acórdãos do TRF3), turmas_recursais (acórdãos das Turmas Recursais dos JEFs), monocraticas (decisões monocráticas do TRF3) e monocraticas_turmas_recursais. Os demais filtros são numero_processo, relator e classe (texto, na grafia que o portal indexa, como "NERY JUNIOR" ou "AI - AGRAVO DE INSTRUMENTO"), orgao_julgador, ementa, indexacao, data_julgamento_inicio/_fim ou data_publicacao_inicio/_fim e tamanho_pagina (10, 30 ou 50). O formulário tem um só par de datas: passar os dois tipos levanta ValueError, assim como orgao_julgador, ementa ou indexacao nas bases de monocráticas, que não têm esses campos. O DataFrame traz processo, classe, orgao_julgador, relator, relator_acordao, data_julgamento, data_publicacao, meio_publicacao, ementa (nas monocráticas, o texto da decisão), base, url_inteiro_teor (só acórdãos) e inteiro_teor. A lista de resultados já traz ementa e inteiro teor, então uma busca custa três requisições fixas (abertura da aba, busca e o redirect para a página 1) mais uma por página adicional. O filtro orgao_julgador aceita o rótulo do dropdown do formulário ("3ª Turma"), o nome indexado da opção ("TERCEIRA TURMA") ou o valor da coluna orgao_julgador dos acórdãos antigos ("QUINTA TURMA - 1A. SEÇÃO", com "1a. seção" trocado por "1A", como no formulário), sem diferença de caixa e de espaços; a busca lê o dropdown no formulário da aba que já abre a sessão e manda o par de rótulo e nome indexado da opção, como o navegador (medido com "medicamento": "QUINTA TURMA" traz 576 documentos, contra 443 do rótulo sozinho e 133 do nome indexado sozinho). Rótulo de mais de uma opção, como "5ª Turma" nos acórdãos, levanta ValueError com os nomes indexados que desfazem a ambiguidade; texto que não casa com nenhuma opção vai como está. Em parte dos acórdãos antigos das Turmas Recursais (na medição, todos os de 2013 e 2014 e parte dos de 2011), ementa vem nula porque o portal não traz a ementa; inteiro_teor vem preenchido. O bloqueio da Akamai levanta BotChallengeBlockedError. Resposta que não é a lista de resultados (sessão expirada, formulário devolvido, página de manutenção) levanta RuntimeError, em vez de virar DataFrame vazio; busca sem resultados continua devolvendo DataFrame vazio. TRF3Scraper(politica={"cjsg": {...}}) ajusta o perfil HTTP da busca.
  • DatajudScraper aceita politica= no construtor para ajustar o timeout do perfil HTTP "busca", usado por listar_processos e contar_processos (default de 60 s, como antes). Exemplo: jus.scraper("datajud", politica={"busca": {"timeout": 180}}). Consultas grandes, como um ano inteiro de um assunto num TRF, passavam de 60 s já na primeira página, e o limite não era configurável. O valor é um número positivo e finito de segundos ou o par (conexão, leitura); None, que esperaria indefinidamente, e outros valores levantam ValueError na construção. O DataJud tem retry próprio, então só timeout é aceito: os demais campos de RequestPolicy levantam ValueError, como perfil desconhecido.
  • Suporte a pandas 3 e a Python 3.15. A dependência passa de pandas>=2,<3 para pandas>=2,<4: projetos que já usam pandas 3, como os criados agora por uv init e uv add pandas, deixam de falhar na resolução, que antes recuava até o juscraper 0.1.5 e quebrava ao compilar o greenlet no Python 3.13. No Google Colab, pip install e pip install -U mantêm o pandas 2.2 pré-instalado. No Python 3.15 o resolvedor escolhe o pandas mais novo; a 3.0.6 é a primeira com wheel para essa versão. Quem fixar no 3.15 pandas 2 ou pandas 3 até a 3.0.3 compila o pandas do código-fonte, e esse binário derruba o interpretador em pd.to_datetime.

Changed

  • DataJud listar_processos: o UserWarning de paginação interrompida passa a dizer quantos registros vieram das páginas pedidas e quantos a consulta encontrou (hits.total da página 1), como em "20 registro(s) recebido(s) de 25 encontrado(s) pela consulta", com "pelo menos" quando o total vem truncado. Quando a falha é na página 1, o aviso diz que nada veio e sugere reduzir o recorte com data_ajuizamento_inicio/_fim ou aumentar o timeout com politica=. Antes, o aviso só dizia "Resultados parciais retornados", sem indicar quanto faltava. O trecho "Resultados parciais retornados" continua na mensagem.
  • JusbrScraper.cpopg e JusbrScraper.download_documents passam a ter contrato de falha por linha. O 401 (token ausente, vencido ou inválido) propaga requests.HTTPError e interrompe o lote, com as falhas anteriores numa nota do erro (__notes__); antes, um token vencido no meio do lote virava "Nao encontrado na lista inicial" no cpopg e texto=None no download_documents, sem sinal. As demais falhas viram linha com conteúdo None e a coluna nova motivo_falha (http_<status>, retry_esgotado_<status>, timeout, conexao ou json_invalido; None sem falha), e um único UserWarning ao fim da chamada conta as falhas e cita algumas. No cpopg, a linha de falha sai com status_consulta="Falha na consulta", que substitui "Erro ao obter ou parsear detalhes"; o CNJ que a listagem responde com 404 continua "Nao encontrado na lista inicial", mas o 404 nos detalhes e nos documentos passa a ser falha (http_404). Resposta 200 com JSON na forma errada vira json_invalido, em vez de sumir como "não encontrado". No download_documents, motivo_falha traz o motivo do texto quando o texto falha, senão o do binário, e o aviso cita as duas falhas. Exceções fora desse vocabulário (TooManyRedirects, por exemplo) propagam; antes, o download de texto engolia qualquer exceção. O 403 deixa de ser retentado, porque na PDPJ ele nega o recurso, e o timeout de leitura passa a ser retentado.
  • JusbrScraper(token=...) passa a validar o token por auth() e levanta ValueError para JWT vencido ou malformado; antes aceitava qualquer string. auth_firefox() também passa o token obtido por auth(), usa o timeout do perfil "listagem" nas requisições ao SSO e levanta RuntimeError com mensagem clara quando a resposta não traz access_token, em vez de KeyError ou JSONDecodeError.
  • PDPJ: cpopg, documentos, movimentos, partes, existe com lista e download_documents ganham a coluna motivo_falha, None quando a requisição deu certo. Quando a requisição de um processo ou documento falha, a linha sai com o conteúdo None e o motivo em vocabulário fechado: http_<status>, retry_esgotado_<status>, timeout, conexao ou json_invalido. Um único UserWarning ao fim da chamada conta as falhas e cita algumas. O 401 continua interrompendo a coleta, com as falhas anteriores numa nota do erro (__notes__). Exceções fora desse vocabulário (TooManyRedirects, por exemplo) propagam; antes viravam linha vazia sem aviso. Em documentos, movimentos e partes, o processo cuja consulta falhou deixa de sumir do resultado. No download_documents com texto e binário, motivo_falha guarda o motivo do texto quando o texto falhou, senão o do binário; o aviso cita as duas falhas.
  • PDPJ cpopg: o 404 deixa de derrubar a chamada inteira e vira linha de falha, com status_consulta="Falha na consulta" e o motivo nao_encontrado (ver abaixo). "Nao encontrado" continua só para a resposta 200 com lista vazia.
  • PDPJ: o processo ausente do data lake sai com o motivo novo nao_encontrado em cpopg, documentos, movimentos, partes e existe com lista. A API diz isso de duas formas, medidas em campo: 404 no endpoint do processo, ou 500 no endpoint com 404 na pesquisa por numeroProcesso. Antes, o 404 saía http_404, e o 500 era retentado 6 vezes, cerca de 1 min por processo, e saía retry_esgotado_500, como se fosse instabilidade. No primeiro 500 de um processo, o raspador faz a pesquisa numa tentativa só: com 404, para e marca o processo; com qualquer outra resposta, segue as tentativas do perfil.
  • JusBR e PDPJ download_documents: o documento sem arquivo no metadado (sem a chave arquivo no JusBR, arquivo_id vazio no PDPJ) deixa de gerar requisição. A API responde 404 ao pedido de texto dele, e o raspador registrava http_404 e um aviso de falha; agora a linha sai com os conteúdos None, motivo_falha None e fora do aviso. No PDPJ, a base sem a coluna arquivo_id continua baixando, porque não informa se há arquivo.
  • PDPJ: existe com str, contar e pesquisa levantam o erro da requisição em vez de devolver False, 0 ou o resultado truncado. Na pesquisa, a página que falhava encerrava o laço em silêncio e devolvia só as páginas anteriores.
  • PDPJ: resposta 200 com corpo que não é o JSON esperado (objeto no lugar de lista ou o contrário, item da lista do cpopg que não é objeto, página da pesquisa sem a lista content, /existe diferente de true/false, /processos:contar sem inteiro, corpo que não é JSON) levanta InvalidJSONResponseError e, nos métodos com linha por item, vira motivo_falha="json_invalido". Antes, o resultado dependia do caso: um objeto no lugar da lista do cpopg virava processo encontrado, um corpo que não era JSON levantava JSONDecodeError, uma lista no lugar do objeto fazia o processo sumir de documentos, movimentos e partes, a pesquisa encerrava a coleta na página sem content, o /existe convertia qualquer outro JSON em booleano ({} virava False) e o contar devolvia 0, ou True quando o corpo era true ou {"total": true}. A página da pesquisa que traz content: null e numberOfElements igual ao inteiro 0 continua aceita como página vazia; sem a chave content, ou com outra contagem, levanta.
  • PDPJ: as requisições passam a usar a política HTTP do core, com os perfis listagem (timeout de 30 s) e documento (timeout de 60 s, texto e binário). Cada perfil faz até 6 tentativas com espera de 2 a 32 s e retenta timeout de leitura. Os status 500, 502 e 504 passam a ser retentados, além de 429 e 503; o 403 não é retentado, porque a API o usa para negar um documento isolado. O erro de conexão não é retentado, como antes, e o timeout de conexão (ConnectTimeout), que antes era retentado como timeout, passa a contar como erro de conexão: uma tentativa só, com motivo_falha="conexao".
  • JusbrScraper.auth() e PdpjScraper.auth() validam o token pela mesma função, e a mensagem de token malformado do PDPJ passa a ser "Token JWT inválido: ...", com acento, como no JusBR. Um auth() que falha mantém o token e o header anteriores nos dois raspadores.
  • PdpjScraper.download_documents: with_text e with_binary passam a ser keyword-only. download_documents(df, None, True, False) levanta TypeError; use download_documents(df, with_text=True, with_binary=False).
  • JusbrScraper.download_documents: documento cujo texto só tem espaço sai com texto=None, como no PDPJ; antes saía "". O texto bruto continua em _raw_text_api, e motivo_falha fica None.
  • clean_document_text passa a ficar só em juscraper.core.parse_utils; o import de juscraper.aggregators.jusbr.parse e de juscraper.aggregators.pdpj.parse levanta ImportError. Os parsers internos do JusBR (parse_process_list_response, parse_process_details_response) deixam de aceitar None.
  • Nos DataFrames devolvidos pelos métodos públicos dos raspadores, inclusive os de subclasses criadas pelo usuário, valor ausente em coluna de texto passa a sair sempre como None, em coluna object, em toda versão do Python e do pandas. Antes, no pandas 2, a mesma coluna trazia None ou NaN conforme o caminho: chave ausente num registro, concat e merge geravam NaN, como em 8 colunas do cjsg do TJSP sobre registros incompletos. Com o pandas 3, essas colunas sairiam com o tipo str e NaN. isna() e fillna() funcionam igual; código que testava math.isnan nesses valores precisa trocar por pd.isna. Colunas numéricas e de data mantêm NaN/NaT, inclusive as colunas object de datetime.date que os parsers produzem com .dt.date, e o tipo "string" pedido explicitamente não é alterado.
  • Os avisos (UserWarning e DeprecationWarning) passam a apontar sempre para a linha do código de quem chamou o juscraper. Antes, o ponto de atribuição era contado à mão em cada aviso e, em alguns caminhos, apontava para dentro da própria biblioteca, como o aviso de erro ao interpretar a resposta JSON do DataJud, que apontava para o cliente do DataJud. Com isso, avisos de depreciação que o Python escondia por estarem atribuídos à biblioteca passam a aparecer, como o de query= no cjsg do TJSP. Filtros de aviso por módulo (warnings.filterwarnings(..., module=...)) que dependiam da atribuição antiga podem precisar de ajuste.

Fixed

  • TJSP cjpg e cjpg_parse: três situações deixam de levantar ValueError: No objects to concatenate, erro do pandas que não dizia o que houve. Diretório sem arquivo HTML devolve DataFrame vazio, o que inclui cjpg(..., paginas=...) só com páginas além do total da busca. Caminho inexistente ou inacessível levanta FileNotFoundError. Diretório em que todos os arquivos falharam levanta ValueError com a contagem, o nome de um dos arquivos e o erro dele. A falha parcial continua como antes: o arquivo com erro vai para o log e os demais são devolvidos.
  • TJMG cjsg: buscas com mais de ~15 páginas deixam de falhar com HTTPError 401. A validação do captcha expira no meio da paginação; agora o scraper resolve o captcha de novo e repete a página.
  • PDPJ pesquisa() sem limite de páginas deixa de levantar requests.HTTPError ao fim de toda coleta. A API responde 404 ("Não foram encontrados registros") à página seguinte à última com dados; o 404 agora encerra a coleta, e na página 1 devolve DataFrame vazio. Outros status continuam levantando. O docstring de itens_por_pagina passa a dizer que a API ignora o valor e devolve até 100 itens por página.
  • STF: o filtro classe passa a valer também nas facetas de base e indicadores, sem restringir a própria faceta de classe; respostas com timeout da busca ou shards falhos levantam RuntimeError em vez de devolver resultados parciais; a obtenção e renovação do cookie funcionam com um loop asyncio ativo, inclusive em notebooks Jupyter, mantendo a API síncrona.
  • STF listar_decisoes(paginas=None) ordena a coleta integral só por id, sem o score de relevância. Com pesquisa textual, o score varia entre réplicas do índice e a mesma página voltava com outra ordem, o que repetia ou pulava documentos e interrompia a coleta com erro de IDs duplicados entre páginas. Páginas explícitas mantêm a ordem do portal. Checkpoints gravados com a ordenação anterior passam a ser recusados como incompatíveis.
  • STF listar_decisoes(paginas=None) deixa de truncar buscas em 10.000 documentos com aviso. Divide consultas maiores em janelas de datas disjuntas e falha explicitamente quando um dia ou o residual sem data excede o teto, quando faltam IDs ou quando as contagens divergem. Mantém o DataFrame e a numeração de páginas explícitas. Datas abertas no STF deixam de receber limites artificiais; a coleta integral fixa a referência temporal da ordenação, sem prometer snapshot do índice.
  • TJSP cjpg: uma primeira página de erro ou captcha que também traz texto de zero resultados deixa de ser lida como busca vazia, e uma página completa sem marcador de paginação deixa de ser tratada como página única. Antes, a coleta devolvia DataFrame vazio no primeiro caso e baixava só a página 1 no segundo, e count_only=True devolvia 0 ou a contagem de linhas da página; agora a coleta e count_only=True levantam ValueError nesses estados. Na coleta dividida por auto_chunk, a janela afetada é omitida com UserWarning, como as demais falhas por janela. Refs #307.
  • TJSP cposg: partes e representantes deixam de ser concatenados ou invertidos — cada linha do tribunal agora produz a parte principal e, em seguida, um registro por advogado/procurador com o mesmo id_parte. O campo parte mantém o rótulo do tribunal com acentos e barra (Réu/Apdo, antes RuApdo). Campos ausentes do DOM canônico passam a sair None, sem a recuperação por regex sobre o HTML bruto que antes preenchia classe, assunto, secao, orgao_julgador, area, relator, valor_da_acao, origem e volume_apenso a partir de qualquer texto Rótulo: valor da página. O DataFrame sai com as 18 colunas públicas em ordem fixa, inclusive em buscas vazias; antes a ordem seguia os campos encontrados no primeiro processo. No cpopg, cpopg_parse passa a aceitar um caminho de arquivo explícito, em vez de devolver {}, e DataFrames auxiliares vazios preservam as colunas públicas de partes, movimentações e petições. cpopg e cpopg_parse passam a levantar ValueError quando nenhum arquivo do diretório pode ser lido, e antes levantavam IndexError. Refs #307.
  • PdpjScraper.auth() (e o construtor com token=) passa a recusar JWT vencido com ValueError("Token JWT expirado."), como o JusBR. Antes o token vencido era aceito e a falha só aparecia na primeira chamada à API, porque verify_signature=False desliga também a verificação de exp no PyJWT. Token sem o claim exp continua aceito. Refs #351.
  • PdpjScraper.download_documents passa a usar os valores validados e coeridos por InputDownloadDocumentsPdpj: por exemplo, with_text="false" deixa de ser tratado como verdadeiro e max_docs_per_process="1" passa a limitar corretamente. O método também rejeita base_df que não seja pd.DataFrame e limites negativos antes de iterar ou fazer chamadas de rede.
  • PdpjScraper.download_documents: max_docs_per_process passa a contar as linhas devolvidas por processo, como no JusBR, e documentos sem id_documento (inclusive NaN) deixam de ocupar vaga do limite; antes, com [sem id, b, c] e limite 2, só b era baixado. Um erro HTTP num documento, exceto 401, deixa de propagar requests.HTTPError e descartar o que já tinha sido baixado: a linha sai com texto/binario None, ocupa vaga do limite e a coleta segue, com um único UserWarning ao fim que conta as falhas e cita processo, documento e motivo. O retry esgotado e o erro de conexão, que já geravam linha vazia em silêncio, entram no mesmo aviso. Só o 401 continua propagando, porque token inválido atinge o lote inteiro, e as falhas anteriores a ele vão numa nota do próprio erro (__notes__), não no aviso; o 403 vira linha vazia como os demais erros, porque a API pode negar um documento isolado, como um sigiloso, com token válido.
  • Auto-chunk do eSAJ em buscas superiores a 366 dias (cjpg do TJSP e cjsg de TJAC, TJAL, TJAM, TJCE, TJMS e TJSP): query e termo usados sem pesquisa agora chegam a todas as janelas. Antes, o cjpg validava o alias e depois o descartava, e as janelas executavam uma busca textual vazia; o cjsg chamado com pesquisa=None e o alias levantava ValidationError, embora o mesmo pedido funcionasse em janela curta. Aliases de busca e de data passam a emitir exatamente um DeprecationWarning também no caminho dividido, onde antes não emitiam nenhum. Refs #130, #307.
  • TJSC cjsg: a coluna processo deixa de carregar o sufixo /TJSC, e resultados com o rótulo DECISÃO preservam a coluna decisao independentemente da ordem dos campos; decisao só preenche ementa quando o resultado não traz uma ementa explícita. Antes, a decisão podia desaparecer quando antecedia EMENTA. Refs #307.
  • TJSP cjsg em janela curta e com count_only=True: query e termo usados sem pesquisa passam a buscar pelo alias. Antes, o default pesquisa="" contava como valor informado e a chamada levantava ValueError de conflito entre pesquisa e o alias. cjsg(query=None) sem pesquisa, que antes fazia uma busca aberta, agora levanta TypeError pedindo pesquisa, como o cjpg e o caminho acima de 366 dias.
  • TJSP cjsg e cjpg com pesquisa, query ou termo acima de 120 caracteres levantam QueryTooLongError antes da primeira requisição também em intervalos acima de 366 dias. Antes, o auto-chunk tratava o erro como falha de cada janela e devolvia um DataFrame vazio com UserWarning.
  • TJPI e TJPR cjsg(paginas=None) calculam o total de páginas pela contagem de resultados que a primeira página publica ("de um total de N jurisprudência(s)" no TJPI, "N registro(s) encontrado(s)" no TJPR) e conferem o link de última página contra ela. Antes, o TJPI usava o maior page=N do paginador e o TJPR o maior pageNumber, que sem o link de última página são o fim da janela de páginas (2 ou 3 na primeira página), e a coleta baixava menos páginas em silêncio. Agora levanta ValueError depois da primeira página quando ela não traz a contagem (página de erro, markup novo), quando um link de última página não traz número de página inteiro >= 1 ou quando algum link aponta para outro total. Refs #307.
  • TJPR cjsg: o payload passa a enviar pageSize=50, o tamanho que o portal sempre devolve. Com o pageSize=10 anterior, o link "Última Página" apontava 5 vezes mais páginas do que existem, e paginas=None fazia cerca de 4 requisições vazias para cada página com resultados. O conteúdo de cada página não muda.
  • Construir um raspador sem download_path deixa de criar um diretório temporário. O diretório passa a ser criado na primeira leitura de download_path, e não na construção; quem informa o caminho não percebe diferença, e quem lê o atributo continua recebendo um diretório que existe. Antes, cada instância deixava um diretório vazio na pasta temporária do sistema, inclusive em raspadores que nunca gravam nele, como o DataJud. Vale para todos os raspadores. No TJSP, set_download_path() sem argumento segue trocando o diretório, agora também sob demanda. Refs #403.

Don't miss a new juscraper release

NewReleases is sending notifications on new releases.