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

Add Vitória-ES spider #748

Merged
merged 11 commits into from
Jan 13, 2025
Merged

Add Vitória-ES spider #748

merged 11 commits into from
Jan 13, 2025

Conversation

ayharano
Copy link
Contributor

@ayharano ayharano commented Oct 20, 2022

AO ABRIR um Pull Request de um novo raspador (spider), marque com um X cada um dos items do checklist
abaixo. NÃO ABRA um novo Pull Request antes de completar todos os items abaixo.

Checklist - Novo spider

  • Você executou uma extração completa do spider localmente e os dados retornados estavam corretos. (log)
  • Você executou uma extração por período (start_date e end_date definidos) ao menos uma vez e os dados retornados estavam corretos.
  • Você verificou que não existe nenhum erro nos logs (log/ERROR igual a zero).
  • Você definiu o atributo de classe start_date no seu spider com a data do Diário Oficial mais antigo disponível na página da cidade.
  • Você garantiu que todos os campos que poderiam ser extraídos foram extraídos de acordo com a documentação.

Descrição

Adiciona spider para Vitória, ES

@trevineju trevineju linked an issue Oct 20, 2022 that may be closed by this pull request
@ayharano ayharano force-pushed the es_vitoria branch 4 times, most recently from 66ff3fe to fd08532 Compare October 30, 2022 22:36
@ayharano ayharano changed the title [WIP] Add Vitória-ES spider Add Vitória-ES spider Oct 30, 2022
@ayharano ayharano marked this pull request as ready for review October 30, 2022 22:44
@ayharano ayharano mentioned this pull request Oct 31, 2022
@ayharano ayharano mentioned this pull request Dec 1, 2022
5 tasks
@ayharano ayharano marked this pull request as draft December 18, 2022 12:17
@ayharano ayharano force-pushed the es_vitoria branch 2 times, most recently from dbe9f8b to f18af11 Compare December 18, 2022 21:32
@ayharano ayharano marked this pull request as ready for review December 18, 2022 21:40
@trevineju trevineju self-requested a review January 7, 2025 19:31
@trevineju trevineju force-pushed the es_vitoria branch 3 times, most recently from f8d243c to ffca201 Compare January 13, 2025 08:44
@trevineju
Copy link
Member

trevineju commented Jan 13, 2025

Finalmente vindo nessa PR! 😅

Dessa vez, optei por revisar e ir commitando, permitindo que a navegação pelos commits deixe visual o progresso da revisão. Deixo comentários para os commits mais importantes em seguida, mas, no geral, a lógica estava funcionado perfeitamente (💖💖), só a coleta dos metadados que tive que atualizar os seletores (em parse_editions_list()). Como já fazem mais de 2 anos, talvez o layout da página tenha atualizado...

Confirmando que estava funcional, passei a olhar para melhorias / refatorar o código. Os comentários são todos nessa linha.


e424be9: remove init() - não faz parte do padrão do projeto usar o __init__() da classe do raspador. Quando for necessário inicializar alguma variável auxiliar, fazemos no start_requests() e parse() já que são os primeiros métodos acionados no fluxo normal.


707707e & a14da77: muda passagem de valores entre métodos e a forma de percorrer datas - aqui tem dois aspectos:

  1. Para passar alguns dados entre um método e outro, o uso de cookiejar foi adotado (acho isso super elegante hahaha adorei que usou), para evitar interferencia na concorrência. Então, ficou redundante passar um parâmetro de callback, já que teria cookie na cookiejar (🤣) da response.

Original

def initial_parse(self, response):
   # ...
   yield FormRequest.from_response(
      # ... 
      cb_kwargs={"year": year},             # passa year como parametro
      # ...
      meta={"cookiejar": f"{self.name}_{year}_12"},  # adiciona year na cookiejar
   )

def parse_year(self, response, year):    # espera receber year de argumento

Revisado

def make_year_request(self, response):    # método renomeado para ser mais intuitivo com o papel dele
   # ...
   yield FormRequest.from_response(
      # ...
      # não recorre à cb_kwargs
      meta={"cookiejar": (yearly_date.year)},  # cookie modificado para ser só o numero, sem string
   )

def make_month_request(self, response):   # não precisa de year
   year = response.meta.get("cookiejar")   # acessa year por meio do cookiejar
  1. Tanto no controle do fluxo de data do ano (em initial_parse()), quanto o do mês, (em parse_year()) funcionavam na exata mesma estrutura: coleta metadados do formdata, depois coleta lista de datas disponíveis no site, e aí interava sob a lista, fazendo controles de fluxo para manter no intervalo de coleta do raspador.

Porém, é mais prático gerar todos os pares (mes, ano) que o raspador quer coletar logo no início e aproveitar a lógica de cookiejar já implementada para ir propagando os valores para os métodos. Aí não precisa repetir verificações depois disso pois o intervalo de interesse foi forçado logo no começo.

  • minha modificação tem um ponto negativo. Antes, você verificava que a primeira requisição já estava na página de um dado mês e já mandava parsear os diários, poupando a interação na lista de datas fazer aquele mês de novo. Como é só uma requisição a mais, em prol do código ficar mais legível e limpo (menos "if... if...") julguei que valia a pena a modificação

ed14bd6 & 034395a : coleta campos do formulário - antes estava coletando o nome dos campos do formdata dinamicamente. Tem a riqueza disso ser robusto, talvez evitando o raspador de quebrar caso o site for atualizado.

Inicialmente, criei o método set_form_params() para coletar os campos dinamicamente apenas uma vez, logo no início (antes, aparecia 3 vezes: linhas 73:74; linhas 100:104; linhas 152:156). Aqui a intenção inicial era uma revisão que visava generalização / evitar repetição, mas como um deles já era hardcoded pq não dava pra coletar na página; acabei revendo e deixando tudo hardcoded. Se os campos do formulário mudarem, vai quebrar o raspador e aí analisamos a situação.


e75155f - aqui retirei o RETRY_HTTP_CODES pois fiz uma coleta completa sem ele e não pareceu ter esse problema (sem contar que o scrapy já tenta 3x o acesso por padrão) e removi campos do formdata que não precisava por ser redundante. Como estava fazendo yield FormRequest.from_response, cada response que já tinha passado por uma interação de form, já "carregava" os campos que tinham sido preenchidos antes. Partindo disso, apenas precisa dos campos novos ou modificados.

@trevineju
Copy link
Member

Obrigada pela PR @ayharano e, como sempre, pela paciência 🙇🏼‍♀️

@trevineju trevineju merged commit 876ddc5 into okfn-brasil:main Jan 13, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Vitória-ES
2 participants