-
-
Notifications
You must be signed in to change notification settings - Fork 409
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
Conversation
Código revisado. Nada a acescentar. |
vou revisar essa PR na quarta! |
There was a problem hiding this 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" |
There was a problem hiding this comment.
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.
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" |
) | ||
yield scrapy.FormRequest( | ||
method="GET", | ||
url=base_url, | ||
) |
There was a problem hiding this comment.
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
) | |
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, | |
) |
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() |
There was a problem hiding this comment.
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
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() |
yield scrapy.Request( | ||
gazette_url, | ||
method="GET", | ||
callback=self.parse_gazette, | ||
cb_kwargs={"gazette_item": gazette_item}, | ||
) |
There was a problem hiding this comment.
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
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}, | |
) |
end_date = self.end_date + relativedelta(months=1) | ||
for monthly_date in rrule( | ||
freq=MONTHLY, dtstart=self.start_date, until=end_date | ||
): |
There was a problem hiding this comment.
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.
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): |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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:
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deixei uma issue #1287
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. |
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:
Código da(s) spider(s)
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.rj_marica_ult.log
Uma coleta-teste por intervalo arbitrário foi feita. Os arquivos de
.log
e.csv
deste teste estão anexados na PR.rj_marica_interv.csv
rj_marica_interv.log
Uma coleta-teste completa foi feita. Os arquivos de
.log
e.csv
deste teste estão anexados na PR.completa.csv
completa.log
Verificações
.csv
gerados pela minha coleta conforme a documentação não encontrando problemas..log
gerados pela minha coleta conforme a documentação não encontrando problemas.Descrição
Criado spider para Maricá/RJ, conforme issues #1201