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

Cria spider para Maricá/RJ #1252

Closed
wants to merge 1 commit into from

Conversation

janainamendes29
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

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

Criado spider para Maricá/RJ, conforme issues #1201

@trevineju trevineju linked an issue Aug 12, 2024 that may be closed by this pull request
1 task
@slfabio
Copy link
Collaborator

slfabio commented Sep 3, 2024

Código revisado. Nada a acescentar.

@trevineju
Copy link
Member

vou revisar essa PR na quarta!

@trevineju trevineju self-requested a review September 23, 2024 22:01
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.

show de bola, @janainamendes29, obrigada pela contribuição! ❤️

A lógica do raspador está ótima. Minhas solicitações de mudanças vão na linha de adaptar o código para usar os recursos padrão do Scrapy. Também tem uma proposta pra lógica do filtro mensal, mas, objetivamente, também estava certa; a questão ali é se podemos melhorá-la.

name = "rj_marica"
allowed_domains = ["marica.rj.gov.br"]
start_date = date(2006, 7, 17)
BASE_URL = "https://www.marica.rj.gov.br/wp-admin/admin-ajax.php?slug={GAZETTE_TYPE}&post_type={GAZETTE_TYPE}&year={YEAR}&month={MONTH}&action=alm_get_posts&order=DESC&orderby=date&posts_per_page=31"
Copy link
Member

@trevineju trevineju Sep 25, 2024

Choose a reason for hiding this comment

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

Você está usando o FormRequest no contexto certo, mas não do jeito que ele foi criado pra ser usado. Não precisa deixar a querystring pré-formatada, a classe FormRequest tem um atributo formdata que é para ter os campos e valores da query, e ele mesmo constroi a querystring usando eles.

Suggested change
BASE_URL = "https://www.marica.rj.gov.br/wp-admin/admin-ajax.php?slug={GAZETTE_TYPE}&post_type={GAZETTE_TYPE}&year={YEAR}&month={MONTH}&action=alm_get_posts&order=DESC&orderby=date&posts_per_page=31"
BASE_URL = "https://www.marica.rj.gov.br/wp-admin/admin-ajax.php"

Comment on lines +29 to +33
)
yield scrapy.FormRequest(
method="GET",
url=base_url,
)
Copy link
Member

Choose a reason for hiding this comment

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

ficando assim com o formdata:

deixei algumas linhas comentadas pra mostrar o formdata conforme você tinha inicialmente criado, mas para te indicar também que alguns campos parecem não ser obrigatórios

exemplo de requisição que funciona sem eles: https://www.marica.rj.gov.br/wp-admin/admin-ajax.php?post_type=jom&year=2024&month=08&action=alm_get_posts&posts_per_page=31

Suggested change
)
yield scrapy.FormRequest(
method="GET",
url=base_url,
)
)
formdata = {
#"slug": gazette_type,
"post_type": gazette_type,
"year": year,
"month": month,
"action": "alm_get_posts",
#"order": "DESC",
#"orderby": "date",
"posts_per_page": "31",
}
yield scrapy.FormRequest(
method="GET",
url=self.BASE_URL,
formdata = formdata,
)

Comment on lines +38 to +41
gazette_list = html.split("\n\n\n")
for gazette_data in gazette_list[0:-1]:
raw_gazette_date = re.search(r"\d+\/\d+\/\d+", gazette_data).group(0)
gazette_date = dt.strptime(raw_gazette_date, "%d/%m/%Y").date()
Copy link
Member

Choose a reason for hiding this comment

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

estes zeros podem ser omitidos

Suggested change
gazette_list = html.split("\n\n\n")
for gazette_data in gazette_list[0:-1]:
raw_gazette_date = re.search(r"\d+\/\d+\/\d+", gazette_data).group(0)
gazette_date = dt.strptime(raw_gazette_date, "%d/%m/%Y").date()
gazette_list = html.split("\n\n\n")
for gazette_data in gazette_list[:-1]:
raw_gazette_date = re.search(r"\d+\/\d+\/\d+", gazette_data).group()
gazette_date = dt.strptime(raw_gazette_date, "%d/%m/%Y").date()

Comment on lines +55 to +60
yield scrapy.Request(
gazette_url,
method="GET",
callback=self.parse_gazette,
cb_kwargs={"gazette_item": gazette_item},
)
Copy link
Member

Choose a reason for hiding this comment

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

O "GET" já é o método de requisição padrão de Request, podendo ser omitido também

Suggested change
yield scrapy.Request(
gazette_url,
method="GET",
callback=self.parse_gazette,
cb_kwargs={"gazette_item": gazette_item},
)
yield scrapy.Request(
gazette_url,
callback=self.parse_gazette,
cb_kwargs={"gazette_item": gazette_item},
)

Comment on lines +20 to +23
end_date = self.end_date + relativedelta(months=1)
for monthly_date in rrule(
freq=MONTHLY, dtstart=self.start_date, until=end_date
):
Copy link
Member

@trevineju trevineju Sep 25, 2024

Choose a reason for hiding this comment

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

Aqui queria propor passar a implementar desse novo jeito...

Entendi que fez a adição de um mês (+ relativedelta(months=1)) pq o rrule tem uma [infeliz] limitação de nem sempre incluir o end_date, o que, pra lógica mensal deste raspador, implica correr o risco de não incluir o mês vigente. Tem outros raspadores na base de código do repositório que tiveram que fazer contornos parecidos (a base municipioonline é um caso).

Como é um "problema comum", hoje parei para dar uma olhada na docs de rrule (um pouco surpresa de não ter uma opção nativa pra isso e a gente ter que ficar contornando) quando achei essa outra possibilidade de implementação, usando rruleset. Me pareceu melhorar a legibilidade.

O que vocês acham? @janainamendes29, @slfabio e, como tô propondo nesse caso particular mas visando adotar como padrão do repo a partir de agora, @ogecece tb.

Suggested change
end_date = self.end_date + relativedelta(months=1)
for monthly_date in rrule(
freq=MONTHLY, dtstart=self.start_date, until=end_date
):
monthly_dates = rruleset()
monthly_dates.rrule(rrule(freq=MONTHLY, dtstart=self.start_date, until=self.end_date))
monthly_dates.rdate(dt(self.end_date.year, self.end_date.month, self.end_date.day))
for monthly_date in list(monthly_dates):

Copy link
Member

Choose a reason for hiding this comment

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

Revendo aqui hoje, pensei que apenas

      for monthly_date in rrule(
          freq=MONTHLY, 
          dtstart=self.start_date, 
          until=self.end_date + relativedelta(months=1)
      ):

poderia ser suficiente também, seria sucinto

Copy link
Member

Choose a reason for hiding this comment

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

Galera, aqui a gente vai ter problemas em todas as soluções quando o .start_date for no final do mês nos dias 29, 30 e 31. Como nem todo mês tem esses dias, o rrule() vai pular esses meses com menos dias que o mês do .start_date. Por isso, é necessário puxar o dtstart pro primeiro dia do mês de .start_date pra garantir que todos os meses serão gerados.

Seguindo a mesma linha da primeira sugestão da @trevineju, já que o rruleset é interessante mesmo:

Suggested change
end_date = self.end_date + relativedelta(months=1)
for monthly_date in rrule(
freq=MONTHLY, dtstart=self.start_date, until=end_date
):
monthly_dates = rruleset()
monthly_dates.rrule(rrule(MONTHLY, dtstart=self.start_date, until=self.end_date, bymonthday=[1]))
monthly_dates.rdate(dt(self.start_date.year, self.start_date.month, 1))
for monthly_date in monthly_dates:

O bymonthday faz com que todos as datas geradas sejam no primeiro dia do mês. Com isso, a gente garante que o mês final sempre entrará no conjunto (mesmo que o .end_date seja no dia 1 do mês) e não precisamos adicionar um mês a mais.

Mas aí geramos o problema do lado do .start_date. Se o .start_date for depois do primeiro dia do mês, o primeiro dia daquele mês não entrará no conjunto (ex: se .start_date for dia 01/03/2020, essa será a primeira data, mas se for 02/03/2020, a primeira data será apenas 01/04/2020). Assim, o .rdate() adicionando o primeiro dia do mês do .start_date resolve isso.

Isso tudo também poderia ser adaptado para a perspectiva do último dia do mês para que a lógica parecesse mais com o que a @janainamendes29 desenvolveu inicialmente, mas acho que a solução usando .start_date fica um pouco mais tranquila de implementar e entender.

E, por último, acho que seria bom a gente ter isso implementado no utils do projeto pra que qualquer pessoa possa usar sem precisar reimplementar sempre. Essa versão de iteração por mês e a versão de iteração por ano são bem comuns.

Copy link
Member

Choose a reason for hiding this comment

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

deixei uma issue #1287

@slfabio
Copy link
Collaborator

slfabio commented Sep 30, 2024

Boa tarde, @trevineju e @ogecece ,

a Janaína não está mais atuando no projeto, por isso criei um novo PR #1292, para subir as alterações do meu repositório.

@trevineju trevineju closed this Oct 2, 2024
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]: Maricá-RJ
4 participants