Skip to content

Python web scraper#4

Open
FilippoMarletta wants to merge 70 commits intoUNICT-DMI:masterfrom
FilippoMarletta:py_scraper
Open

Python web scraper#4
FilippoMarletta wants to merge 70 commits intoUNICT-DMI:masterfrom
FilippoMarletta:py_scraper

Conversation

@FilippoMarletta
Copy link

@FilippoMarletta FilippoMarletta commented Mar 25, 2026

Relates to UNICT-Quality-Development/qd-projects#46

Implementazione del web scraper Python per l'estrazione dei dati OPIS relativi agli anni accademici dal 2021/2022 al 2024/2025. Lo scraper interroga le API pubbliche di SmartEdu UniCT (https://public.smartedu.unict.it/EnqaDataViewer) e popola il database seguendo la struttura definita in opis-manager-core.

Features

  • Configurazione con DevContainers
  • Retry automatica su errori HTTP 429 e 5xx (3 tentativi, backoff esponenziale)
  • Parallelizzazione del fetch delle schede OPIS tramite ThreadPoolExecutor (3 worker di default), con gestione delle eccezioni per thread per evitare che un singolo fallimento blocchi l'elaborazione
  • Sistema di Logging
  • Unit Tests
  • Debug Mode configurabile
  • Pipeline CI: linting con Black, type checking con Pyright (modalità standard), test con pytest (coverage minima 80%)

Note

Dati Schede OPIS estratti dalla API (se presenti)

  • totale_schede: Totale questionari compilati dai frequentanti.
  • totale_schede_nf: Totale dei questionari compilati dai non frequentanti.
  • fc: Numero di studenti fuori corso.
  • inatt_nf: Numero di inattivi non frequentanti.
  • domande: Array delle risposte ai questionari dei frequentanti.
  • domande_nf: Array delle risposte ai questionari dei non frequentanti.
  • motivo_nf: Motivi della non frequenza.
  • sugg: Suggerimenti dei frequentanti.
  • sugg_nf: Suggerimenti dei non frequentanti.
  • femmine: Numero di studentesse frequentanti.
  • femmine_nf: Numero di studentesse non frequentanti.
  • inatt: Numero di inattivi frequentanti.
  • eta: Statistiche sulle fasce d'età.
  • anno_iscr: Anno di iscrizione.
  • num_studenti: Statistica sul numero medio di studenti.
  • ragg_uni: Statistiche sul domicilio o sul tempo impiegato per arrivare in sede.
  • studio_gg: Statistiche sulle ore di studio giornaliere.
  • studio_tot: Statistiche sulle ore di studio totali.

Problema — codici GOMP alfanumerici
Alcune attività hanno un activityCode alfanumerico (es. "A3688"). La colonna codice_gomp nel database è di tipo INT, rendendo impossibile l'inserimento di questi record. Tali attività vengono attualmente saltate con un warning in fase di elaborazione. Per risolvere definitivamente il problema sarebbe necessaria una migration che cambi il tipo della colonna in VARCHAR.

Problema — Suddivisione insegnamenti in canali
Le API non forniscono dati espliciti per i canali. Nello specifico:

  • channel -> sempre null.

  • part_code -> sempre null.

  • part_name (nome_modulo a DB) -> contiene una stringa se l'insegnamento è diviso in moduli (es. "PROGRAMMAZIONE 2" o "LABORATORIO"), altrimenti è null.

    Workaround
    Ho gestito l'assegnazione dei canali ai record duplicati di Insegnamento in questo modo:

    1. Raggruppamento in set univoci: Per definire il numero di canali, l'algoritmo raggruppa gli Insegnamenti costruendo dei "set" univoci basati sul nome_modulo (o su un modulo unico se il campo è null). Ogni set completo compone un canale.
    2. Assegnazione progressiva: Ai canali così formati viene assegnato un valore numerico progressivo ("1", "2", ..., "n").
    3. Gestione del canale unico: Se al termine del raggruppamento risulta esistere un solo canale (un solo set), il campo canale viene impostato a "no".

    Limitazioni: Questa suddivisione logica permette di strutturare correttamente i dati e risolvere i problemi di visualizzazione a frontend. Tuttavia, vista la totale assenza di identificativi lato API, non è garantito che le associazioni modulo-canale rispecchino al 100% la realtà accademica (non abbiamo dati per sapere se un modulo specifico appartiene fisicamente al canale 1 o al canale 2).

Problema di performance — Lentezza API sorgenti
Le API risultano estremamente lente nei tempi di risposta. Un'esecuzione dello scraper richiede circa 24 ore per recuperare i questionari OPIS di un singolo anno accademico (2021/2022).

Mitigations
Per cercare di rendere l'esecuzione più efficiente sono state introdotte le seguenti ottimizzazioni:

  • Esecuzione parallela: Sfruttato il modulo concurrent.futures.ThreadPoolExecutor per processare le singole materie in multithreading.
  • Gestione del carico (Throttling): Introdotto un delay controllato tra le richieste principali per non sovraccaricare il server sorgente ed evitare timeout o blocchi dell'IP a causa delle richieste parallele.

Tuttavia i tempi rimangono comunque molto lunghi.

…ed code and enhancing data aggregation logic
@Helias
Copy link
Member

Helias commented Mar 25, 2026

Did you test it with the current OPIS-Manager app?

@FilippoMarletta
Copy link
Author

I tested it using a local database initialized with the migrations from opis-manager-core.

@Helias
Copy link
Member

Helias commented Mar 26, 2026

I added the same lint.yml file in the main branch to see if the pipeline starts here
please solve merge conflicts

@Helias Helias closed this Mar 26, 2026
@Helias Helias reopened this Mar 26, 2026
@Helias
Copy link
Member

Helias commented Mar 26, 2026

please solve merge conflict

@FilippoMarletta
Copy link
Author

How should I proceed with the CD pipeline?

@Helias
Copy link
Member

Helias commented Mar 26, 2026

the pipeline is fine, I am testing the PR, I am getting some errors also for MATEMATCA E INFORMATICA

image

ACCADEMIC_YEARS = [2021, 2022, 2023, 2024]
DELAY = 1.0

MAX_WORKERS = 3
Copy link
Member

Choose a reason for hiding this comment

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

I noticed that untl 10 is fine, I would put 10 as default

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.

2 participants