You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
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_falhaNone 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/binarioNone, 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.