Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Novo spider base]: NucleoGov - Anápolis, GO #1147

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

xxggabriel
Copy link

AO ABRIR uma Pull Request de um novo raspador (spider), marque com um X cada um dos items da checklist abaixo. Caso algum item não seja marcado, JUSTIFIQUE o motivo.

Layout do site publicador de diários oficiais

Marque apenas um dos itens a seguir:

  • O layout não se parece com nenhum caso da lista de layouts padrão
  • É um layout padrão e esta PR adiciona a spider base do padrão ao projeto junto com alguns municípios que fazem parte do padrão.
  • É um layout padrão e todos os municípios adicionados usam a classe de spider base adequada para o padrão.

Código da(s) spider(s)

  • O(s) raspador(es) adicionado(s) tem os atributos de classe exigidos.
  • O(s) raspador(es) adicionado(s) cria(m) objetos do tipo Gazette coletando todos os metadados necessários.
  • O atributo de classe start_date foi preenchido com a data da edição de diário oficial mais antiga disponível no site.
  • Explicitar o atributo de classe end_date não se fez necessário.
  • Não utilizo custom_settings em meu raspador.

Testes

  • Uma coleta-teste da última edição foi feita. O arquivo de .log deste teste está anexado na PR.
  • Uma coleta-teste por intervalo arbitrário foi feita. Os arquivos de .loge .csv deste teste estão anexados na PR.
  • Uma coleta-teste completa foi feita. Os arquivos de .log e .csv deste teste estão anexados na PR.

Verificações

  • Eu experimentei abrir alguns arquivos de diários oficiais coletados pelo meu raspador e verifiquei eles conforme a documentação não encontrando problemas.
  • Eu verifiquei os arquivos .csv gerados pela minha coleta conforme a documentação não encontrando problemas.
  • Eu verifiquei os arquivos de .log gerados pela minha coleta conforme a documentação não encontrando problemas.

Descrição

Este pull request adiciona o spider base para o sistema NucleoGov, utilizando o mapeador (PR #1019).

Observacao

Ao analisar o NucleoGov, notei que existe outro sistema que lista decretos de forma individual via API. Não consegui listar as demais cidades, mas sei que existem municípios de outros estados que utilizam esse sistema. Neste link é possível acessar os decretos do município de Rio Verde, Goiás.

Após a aceitação deste PR, criarei os spiders das outras cidades que utilizam o NucleoGov:

Municípios que faltam ser integrados:
  1. Diário Oficial de Cariri, TO
  2. Diário Oficial do Paraná, TO
  3. Diário Oficial de Jaú, TO
  4. Diário Oficial de Valparaíso de Goiás, GO
Testes

Devido ao intervalo de start_date ser de 2010, meu PC não tem espaço suficiente para fazer uma coleta completa.

Arquivos de teste:

ultima
maio/2024 - hoje

@trevineju
Copy link
Member

Obrigada pela PR, @xxggabriel

Após a aceitação deste PR, criarei os spiders das outras cidades que utilizam o NucleoGov

Precisamos de mais municípios para revisar esta PR (pelo menos 5 é o que indicamos sempre nesses casos). Aqui, o que está em jogo é: o código nucleogov.py precisa ser genérico o suficiente para ser a classe base para vários outros raspadores. Quando se adiciona só um, não temos essa garantia. Sabemos apenas que serve pra Anápolis.

Se você puder colocar o código para os demais 4 aqui, coloco sua PR na fila de revisão. Se puder adicionar os testes pra última edição e pro período arbitrário para cada um deles, seria ótimo.

Como você disse que não consegue a coleta completa, poderia tentar para, pelo menos, 1 ano? Não faz a coleta completa (fazemos depois quando formos revisar), mas pelo menos a arbitrária ficaria com um intervalo maior que apenas um mês.

@xxggabriel
Copy link
Author

Espero que isso atenda aos requisitos para revisão. Qualquer dúvida ou necessidade de ajuste, estou à disposição.

Testes para Jaú:

Testes para Paraná:

Testes para Cariri:

Testes para Valparaíso de Goiás:

@trevineju trevineju linked an issue May 29, 2024 that may be closed by this pull request
1 task
@trevineju
Copy link
Member

show, @xxggabriel!! Obrigada! PR adicionada à fila de revisão

Copy link
Member

@trevineju trevineju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

o estilo do código está excelente, @xxggabriel! A simplicidade foi ótima! Deixei só um ajuste pra formatação da URL.

Entretanto, o desempenho da coleta vai precisar de melhorias. Nos logs que você anexou aqui temos alguns problemas:

go_valparaiso_de_goias.log:
10526: 'downloader/response_status_count/429': 1897

to_cariri_do_tocantins.log:
3315: 'downloader/response_status_count/429': 741,

to_jau_do_tocantins.log:
2277: 'downloader/response_status_count/429': 555,

to_parana.log:
3308: 'downloader/response_status_count/403': 3,
3309: 'downloader/response_status_count/429': 440,

Bora focar no erro 429 primeiro que tem mais ocorrências. A response 429 indica que o raspador teve uma taxa de requisição muito elevada e por isso o site parou de responder. É preciso contornar isso. Vejo que tem dois possíveis caminhos:

  1. alterar a lógica de acesso à API.
    Em nuclegov.py, a lógica de requisição pra API é diária. Isso significa que raspador acaba fazendo 2 requisições nesse caso: 1 para acessar a API para certo dia e outra para obter arquivo pdf. Para coletar 15 edições de diários oficiais, ele faz cerca de 30 requisições.

Olhando o endereço https://dom.anapolis.go.gov.br/api/diarios, aparece na parte de baixo:

"first_page_url":"https://dom.anapolis.go.gov.br/api/diarios?per_page=15&page=1","from":1,"last_page":18,

Parece ser possível navegar por paginação, sabendo que começa na página 1 e termina na 18. Nesse caso, 1 requisição vai indicar 15 diários. E para coletar 15 diários, 16 requisições foram feitas (1 pra API + 15 pros arquivos). Isso já vai reduzir bem a quantidade de requisições feitas.

Talvez dê para calibrar esse per_page para valores um pouco mais altos (25? 30?) e experimentar se isso reduz ainda mais a quantidade de erros 429 no log. E nesse caso, também vai precisar tomar cuidado com o valor escolhido, para não forçar a API deles.

  1. Configurações personalizadas
    Adicionar custom_settings à classe nucleogov.py e experimentar calibrações. Se vc fizer uma busca no repositório, vai encontrar exemplos dessa setting para dar uma olhada e também tem na documentação do Scrapy. Aqui seria um exercicio de forçar o raspador a diminuir a concorrência ou adicionar algum delay até descobrir a configuração que surge mais efeito.

As sugestões 1 e 2 podem não ser excludentes também, e ambas se fazerem necessárias. Mas tentaria a 1 primeiro.

Você poderia fazer essas modificações e testar novamente? Pode seguir coletando um intervalo de um ano se seu pc continuar com limitações, sem problemas.

def start_requests(self):
days = rrule(freq=DAILY, dtstart=self.start_date, until=self.end_date)
for day in days:
yield scrapy.Request(self.url_base.format(day.strftime("%Y-%m-%d")))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

como a string de acesso a API /api/diarios?data={}&calendar=true&situacao=2" é igual em todas as classes filhas, nós temos adotado o padrão de deixar essa construção da URL na classe mãe, escondendo isso da classe filha e deixando mais simples o raspador do município.

Suggested change
yield scrapy.Request(self.url_base.format(day.strftime("%Y-%m-%d")))
url = f"{self.url_base}/api/diarios?data={day.strftime('%Y-%m-%d')}&calendar=true&situacao=2"
yield scrapy.Request(url)

Comment on lines +12 to +14
url_base = (
"https://dom.anapolis.go.gov.br/api/diarios?data={}&calendar=true&situacao=2"
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reflete aqui a mudança na classe base

Suggested change
url_base = (
"https://dom.anapolis.go.gov.br/api/diarios?data={}&calendar=true&situacao=2"
)
url_base = "https://dom.anapolis.go.gov.br"

Comment on lines +12 to +13
url_base = "https://diariooficial.valparaisodegoias.go.gov.br/api/diarios?data={}&calendar=true&situacao=2"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reflete aqui a mudança na classe base

Suggested change
url_base = "https://diariooficial.valparaisodegoias.go.gov.br/api/diarios?data={}&calendar=true&situacao=2"
url_base = "https://diariooficial.valparaisodegoias.go.gov.br"

Comment on lines +12 to +14
url_base = (
"https://dom.cariri.to.gov.br/api/diarios?data={}&calendar=true&situacao=2"
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reflete aqui a mudança na classe base

Suggested change
url_base = (
"https://dom.cariri.to.gov.br/api/diarios?data={}&calendar=true&situacao=2"
)
url_base = "https://dom.cariri.to.gov.br"

Comment on lines +12 to +13
url_base = "https://diariooficial.parana.to.gov.br/api/diarios?data={}&calendar=true&situacao=2"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reflete aqui a mudança na classe base

Suggested change
url_base = "https://diariooficial.parana.to.gov.br/api/diarios?data={}&calendar=true&situacao=2"
url_base = "https://diariooficial.parana.to.gov.br"

Comment on lines +12 to +13
url_base = "https://diariooficial.jau.to.gov.br/api/diarios?data={}&calendar=true&situacao=2"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reflete aqui a mudança na classe base

Suggested change
url_base = "https://diariooficial.jau.to.gov.br/api/diarios?data={}&calendar=true&situacao=2"
url_base = "https://diariooficial.jau.to.gov.br"

@trevineju
Copy link
Member

trevineju commented Jul 3, 2024

Outra coisa que dei uma olhada, mas ainda não entendi bem é qual o reflexo do campo calendar na query https://dom.anapolis.go.gov.br/api/diarios?data={}&calendar=true&situacao=2.

situacao=<valor> entendi que é
1 - em andamento (https://dom.anapolis.go.gov.br/api/diarios?situacao=1)
2 - publicado (https://dom.anapolis.go.gov.br/api/diarios?situacao=2)
e, realmente, só queremos pegar a versão final publicada.

mas calendar=true não entendi o que está sendo selecionado.

você entendeu, @xxggabriel? chegou a olhar isso?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

[Novo spider base]: nucleogov
2 participants