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

Adiciona spider base para o sistema replicável Atende, e spiders derivados para as cidades com D.O.s nesse sistema. #1046

Draft
wants to merge 40 commits into
base: main
Choose a base branch
from

Conversation

AlexJBSilva
Copy link
Contributor

@AlexJBSilva AlexJBSilva commented Dec 4, 2023

Checklist - Novo spider

  • Você executou uma extração completa do spider localmente e os dados retornados estavam corretos.
  • 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_count/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 o spider base para o sistema replicável Atende, e os spiders derivados para as cidades com D.O.s nesse sistema.
Através do mapeador ATENDE (PR #1043), foram identificadas 34 cidades com Diários Oficiais disponíveis.

Esse sistema apresenta 2 layouts de página: layout Tipo 1 e layout Tipo 2.

  • Tipo 1: 4 cidades
id name state_code observação
4303103 Cachoeirinha RS Spider ainda não foi testado.
4303509 Camaquã RS Spider ainda não foi testado. Resolve #1038.
4311304 Lagoa Vermelha RS Realizando ajustes na Classe Spider Base T1 devido à falta de padrão nos links do site dessa cidade.
3552403 Sumaré SP Não precisa de um novo spider.

Sumaré já possui um spider funcional e não precisará de um novo spider, pois os diários no sistema Atende (layout Tipo 1) não possuem todos os metadados (inclusive data de publicação).

  • Tipo 2: 30 cidades
id name state_code observação
4101408 Apucarana PR Spider ainda não foi testado.
4201307 Araquari SC Spider ainda não foi testado.
4101804 Araucária PR Log: pr_araucaria.log CSV: pr_araucaria.csv
4302105 Bento Gonçalves RS Spider ainda não foi testado.
4104204 Campo Largo PR Spider ainda não foi testado.
4104303 Campo Mourão PR Log: pr_campo_mourao.log CSV: pr_campo_mourao.csv
4304200 Candelária RS Spider ainda não foi testado.
3114501 Carmópolis de Minas MG Spider ainda não foi testado.
4104907 Castro PR Spider ainda não foi testado.
4105706 Clevelândia PR Spider ainda não foi testado.
4106308 Corbélia PR Spider ainda não foi testado.
4306403 Dois Irmãos RS Spider ainda não foi testado.
4307807 Estrela RS Spider ainda não foi testado.
4309209 Gravataí RS Log: rs_gravatai.log CSV: rs_gravatai.csv
4109302 Guaraniaçu PR Spider ainda não foi testado.
4309605 Horizontina RS Spider ainda não foi testado.
4112959 Juranda PR Spider ainda não foi testado.
4209508 Laurentino SC Spider ainda não foi testado.
4114005 Mamborê PR Spider ainda não foi testado.
3145604 Oliveira MG Spider ainda não foi testado.
4117453 Ouro Verde do Oeste PR Spider ainda não foi testado.
4313904 Panambi RS Spider ainda não foi testado.
4119152 Pinhais PR Spider ainda não foi testado.
4122206 Rio Branco do Sul PR Spider ainda não foi testado.
4317202 Santa Rosa RS Spider ainda não foi testado.
4124103 Santo Antônio da Platina PR Spider ainda não foi testado.
4318432 São João do Polêsine RS Spider ainda não foi testado.
4320701 Sobradinho RS Spider ainda não foi testado.
4127957 Tupãssi PR Spider ainda não foi testado.
4118451 Pato Bragado PR Spider ainda não foi testado.

Dos testes realizados com Araucária, Campo Mourão e Gravataí:

Extra: Automatizando a criação de Spiders derivados.

Seguindo a dica da @trevineju, fiz o script abaixo para criar os spiders utilizando o arquivo cidades_atende_t2.csv com as infomações de configuração:

# script.py
import csv
from datetime import datetime
from pathlib import Path

from unidecode import unidecode


class SpiderBuilder:
    def read_csv(self, file):
        rows = []
        with open(file, "r", encoding="utf-8") as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                rows.append(row)
        csvfile.close()
        return rows

    def format_str(self, name, state_code):
        name = unidecode(name).strip().lower().replace("-", " ").replace("'", "")
        state_code = unidecode(state_code).strip().lower()
        return name, state_code

    def blankspaces_to_underline(self, name):
        return name.replace(" ", "_")

    def to_pascal_case(self, name):
        return "".join(word for word in name.title() if not word.isspace())

    def get_spider_config(
        self, id, spider_name, class_name, start_date, city_subdomain, start_edition
    ):
        return f"""from datetime import date

from gazette.spiders.base.atende import BaseAtendeT2Spider


class {class_name}Spider(BaseAtendeT2Spider):
    TERRITORY_ID = "{id}"
    name = "{spider_name}"
    start_date = date({start_date.year}, {start_date.month}, {start_date.day})  # Edição {start_edition}
    city_subdomain = "{city_subdomain}"
"""

    def write_file(self, spider_name, spider_content):
        spiders_folder = Path("../gazette/spiders/")
        spider_path = spiders_folder.joinpath(
            spider_name.split("_", 1)[0], spider_name
        ).with_suffix(".py")
        # print (spider_path.resolve().absolute())
        # print (spider_content)
        with open(spider_path, "w", encoding="utf-8") as f:
            f.write(spider_content)

    def spider_from_cfg(self, config):
        name, state_code = self.format_str(config["name"], config["state_code"])
        state_plus_name = f"{state_code} {name}"
        spider_name = self.blankspaces_to_underline(state_plus_name)
        class_name = self.to_pascal_case(state_plus_name)
        start_date = datetime.strptime(config["start_date"], "%d/%m/%Y")
        content = self.get_spider_config(
            config["id"],
            spider_name,
            class_name,
            start_date,
            config["city_subdomain"],
            config["start_edition"],
        )
        self.write_file(spider_name, content)


if __name__ == "__main__":
    csv_file = "cidades_atende_t2.csv"
    sb = SpiderBuilder()
    spiders_cfg = sb.read_csv(csv_file)

    for config in spiders_cfg:
        sb.spider_from_cfg(config)

Para usar:

  1. Salve o script e o arquivo cidades_atende_t2.csv na pasta data: querido-diario/data_collection/data;
  2. Navegue até a pasta cd querido-diario/data_collection/data e execute o script python script.py.

rodps and others added 30 commits December 2, 2023 14:04
…cia na criação do spider base do sistema replicável Atende.
Essa versão implementa a classe 'BaseAtendeT2Spider' para buscar os
dirários nas páginas com layout 'Tipo 2', identificadas pelo Mapeador
Atende desenvolvido em okfn-brasil#1043.
para trabalhar com o spider base do sistema replicável 'Atende'.
Resolve okfn-brasil#430
Adiciona spider para Campo Mourão - PR.
spider base do sistema replicável 'Atende'.
de download na página de 'Detalhes da Edição' quando não encontrar na
página padrão (layout Tipo 2).
Caso conhecido: Araucária - PR (https://araucaria.atende.net/diariooficial)
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
…latina - PR.

Sistema replicável 'Atende' (layout Tipo 2).
… RS.

Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
Sistema replicável 'Atende' (layout Tipo 2).
os diários nas páginas do sistema replicável 'atende' com layout 'Tipo 1'.
Sistema replicável 'Atende' (layout Tipo 1).
Sistema replicável 'Atende' (layout Tipo 1).
Resolve okfn-brasil#1038
Conforme comentado em okfn-brasil#1038 (comment)
esse novo spider coleta apenas da edição 333 em diante.
Como falta a informação de data para muitas edições na página,
a estratégia foi incluir a verificação do número da edição para limitar
o download dos arquivos e salvar a data
`datetime.date.max` nos metadados para que a etapa de 'data processing'
realize a extração dessa informação.
original de Camaquã, para refletir o último dia antes da publicação da
edição 333 no novo site atende.net
Ajuste associado à issue okfn-brasil#1038
@AlexJBSilva AlexJBSilva changed the title Adiciona spider base para o sistema replicável Atende, e spiders derrivados para as cidades com D.O.s nesse sistema. Adiciona spider base para o sistema replicável Atende, e spiders derivados para as cidades com D.O.s nesse sistema. Dec 23, 2023
@trevineju
Copy link
Member

trevineju commented May 16, 2024

@AlexJBSilva muito obrigada pela PR!

Sei que ainda estava em rascunho, porém, tendo em vista as enchentes no Rio Grande do Sul, fizemos um esforço de priorizar a adição de municípios de lá e esta PR tem vários. Por isso, tomei a liberdade de seguir a partir de onde você parou.

Aqui você adiciona duas novas classes base e, como o "Layout 2" estava mais desenvolvido (você até anexou testes, enquanto o "Layout 1" não) e tem uma cobertura maior de municípios do RS, foquei nele.

Fiz uma PR (#1145) que puxa suas contribuições daqui e as finaliza lá. Optei por fazer isso e não revisar aqui pois, como disse acima, queria reduzir o escopo pra um sistema só por vez sem jogar fora o que você já tinha começado aqui (não queria perder o "Layout 1" e os demais municípios que já estão aqui).

Como acabei revisando vou deixar alguns feedbacks, mas mesmo eu não tenho certeza se precisa (visto que ainda era rascunho, pode ser só que você ia ajustar depois)

  1. Não precisa deixar um município por commit quando for essa situação de municípios padronizados. Pode adicionar vários em um só.

  2. Sei que não tínhamos outro caso para você se espelhar, mas não deixamos duas classes em um único arquivo. Adotei atende_layoutdois.py na minha revisão. Confesso que não sei se é um bom nome pro arquivo em si, porém ficou separado em dois (deixando sugestivo que o outro vai ser atende_layoutum.py), que é o que precisa.

  3. Você estava deixando parâmetros de requisição hardcoded na URL, como em
    /atende.php?rot=54015&aca=101&ajax=t&processo=loadPluginDiarioOficial e &parametro=%7B%22codigoPlugin%22%3A1,%22filtroPlugin%22%3A%7B%22pagina%22%3A%22{page}%22%7D%7D"
    Costumamos a usar o parâmetro formdata + requisição scrapy.FormRequest nesses casos.

  4. (e mais importante) Estava caminhando muito bem ❤️ Fora alguns detalhes de organização (tanto é que meus 2 dos 3 feedbacks acima eram mais questão de organização mesmo), as ordem das requisições e as lógicas de coleta dos metadados tavam ótimas.

  • Você deixou alguns ifs de verificações mas não cai em nenhum caso que precisasse, por isso tirei. Porém, eu foquei em 10 municípios e você tava adicionando 30. Pode ser algum caso que ainda iria aparecer, mas podemos ter uma dinâmica incremental, de ir adicionando melhorias na base conforme formos cobrindo mais casos.

Muito obrigada pela contribuição

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.

[Manutenção] Camaquã-RS
3 participants