• Non ci sono risultati.

Result = Pipeline.handleRequest(inputData)

Questo codice rende complesso il debugging dell’inizializzazione degli stadi, quindi solitamente si preferisce fare uso di variabili per ogni singolo stadio, ma questo provoca la necessità di costruire gli stadi “dall’ultimo al primo”:

Stage3 = LastStage()

Stage2 = MiddleStage(Stage3) Stage1 = FirstStage(Stage2)

Result = Stage1.handleRequest(inputData)

Un’interfaccia fluida [30] permette di collegare gli stadi in ordine, mettendo a disposizione del codice simile alla prosa scritta, semplice da leggere e con minori difficoltà nel debugging. Purtroppo dato che la struttura della catena è analoga ad una singly linked list[g], ogni aggiunta (effettuata in coda) ha costo computazionale O(n) con n numero degli stadi già presenti in coda.

Stage3 = LastStage() Stage2 = MiddleStage() Stage1 = FirstStage() Pipeline = Stage1

.then(Stage2) .then(Stage3)

Result = Pipeline.handleRequest(inputData)

5.5 Progettazione dell’architettura

L’architettura della componente è stata pensata come se fosse una “catena di montaggio”, in cui ogni componente dell’architettura interviene sul risultato finale, arricchendolo.

In Figura 7 si espone uno schema esemplificativo della procedura seguita dall’architettura per l’elaborazione dei dati:

Figura 7: Schema esemplificativo del funzionamento dell’architettura

In grigio sono contrassegnati gli stadi implementati da un mio collega, facendo uso dell’astrazione offerta dal Pipeline Pattern.

In questo elaborato si dettaglieranno le rimanenti classi, sviluppate nell’ambito dello stage.

5.5.1 Classi e moduli

5.5.1.1 Pipeline principale

La pipeline è costituita da nove moduli Python principali (più quelli implementati dal mio collega), a cui si aggiungono alcuni moduli contenenti funzioni di utilità. Qui di seguito riporto le classi ed i moduli implementati.

5.5.1.1.1 Moduli di utilità

La pipeline principale fa uso di alcuni moduli di utilità che elenco qui sotto, completi di descrizione.

• RequestBuilder: Modulo che consente di costruire una richiesta a Google, dato un URL ed un dizionario di parametri;

• GoogleAPIErrors: Modulo di utilità che contiene gli errori sollevati da Google API, comprensivo funzionalità per la gestione di tali errori;

• GoogleAPIRequestProcessor: Modulo di utilità per la gestione delle risposte da Google API, fa uso di GoogleAPIErrors per la gestione degli errori ritornati da Google ed eventualmente per ripetere l’operazione richiesta;

• Config: Un modulo contenente la configurazione della pipeline.

5.5.1.1.2 Classi

• Stage: Classe astratta che funge da interfaccia per tutti gli stadi della pipeline;

• PrepareStage: Classe inserita per preparare il record di database su cui salvare i dati estratti dallo scraper. Data la natura database-centric dell’architettura esistente e la necessità di usare la base di dati per venire a conoscenza dello stato di completamento della procedura, questo stadio deve stare in testa alla catena;

• GoogleAPIStage: Classe che implementa le operazioni di ricerca diretta su Google Places. Questo stadio effettua una richiesta di ricerca per nome preciso dell’azienda a Google ed elabora la risposta;

• FuzzyGoogleAPIStage: Classe che implementa le operazioni di ricerca fuzzy su Google Places.

Questo stadio effettua una richiesta di ricerca testuale a Google ed elabora la risposta, restituendo

allo stadio successivo il risultato più simile alla richiesta ricevuta. Nel caso venisse usato insieme a GoogleAPIStage, FuzzyGoogleAPIStage deve essere lo stadio successivo a GoogleAPIStage;

• GoogleAPIDetailsStage: Classe che implementa le operazioni di estrazione dei dettagli dell’a-zienda da Google Places. Questo stadio deve essere lo stadio successivo a GoogleAPIStage e/o FuzzyGoogleAPIStage;

• WebsiteScreenshotStage: Classe che, facendo uso di un browser manovrato in maniera automatica, estrae uno screenshot della home page del sito internet aziendale. Per fare ciò deve essere presente un sito internet nei dati in input, che solitamente sono forniti da GoogleAPIDetailsStage;

• LogoScraperStage: Classe che avvia una Chain of Responsibility per l’estrazione del logo azien-dale da un sito web. Necessita di un sito web nel dizionario dato in input, solitamente fornito da GoogleAPIDetailsStage;

• WebsiteScrapingStage: Classe che avvia una nuova pipeline per l’estrazione di dati anagrafici dal sito web aziendale fornito. Necessita di un sito web nel dizionario dato in input, solitamente fornito da GoogleAPIDetailsStage;

• DBSaveStage: Si occupa del salvataggio in Database di tutti i dati ricavati dagli stadi precedenti.

5.5.1.2 Bypassers

Questo pacchetto costituisce degli elementi usati per superare alcuni ostacoli che un web crawler/scraper automatico può incontrare, questo pacchetto contiene le seguenti classi:

• RedirectBypasser: permette di seguire i redirect creati con JavaScript, nella forma

<script>window.location="http://sito.org";</script>

• FrameBypasser: permette di ricavare l’URL contenuto all’interno di frame HTML4;

• BypasserToLogoStageAdapter: permette di adattare l’output dei bypassers per potersi interfacciare correttamente con la Chain Of Responsibility usata per estrarre i loghi dai siti web. In questo modo è possibile riusare i bypassers con il modulo WebCrawler.

5.5.1.3 Chain of Responsibility per lo scraping dei loghi

Questa chain of responsibility è costituita da undici classi principali, più un modulo di utilità, esposti qui sotto.

5.5.1.3.1 Moduli di utilità

• ImageSaver: Modulo di utilità usato per scaricare un’immagine da un URL e salvarla in un file temporaneo, ritornando il percorso e l’estensione di tale file.

5.5.1.3.2 Classi

• LogoScrapingStage: Classe astratta che funge da interfaccia per tutti gli stadi della Chain of Responsibility;

• CSSLogoScraper: Questa classe implementa la ricerca di un logo aziendale tramite analisi dei fogli stile CSS trovati all’interno del sito web;

• ImgAltCompanyNameLogoScraper: Questa classe implementa la ricerca di un logo aziendale analizzando gli attributi alt dei tag <img ...>, alla ricerca della ragione sociale dell’azienda, effettuando una ricerca fuzzy;

• ImgAltLogoScraper: Questa classe implementa la ricerca di un logo aziendale analizzando gli attributi alt dei tag <img ...>, alla ricerca della parola “logo”;

• ImgClassLogoScraper: Classe che implementa la ricerca di un logo aziendale analizzando gli attributi class dei tag <img ...> alla ricerca della parola “logo”;

• ImgIdLogoScraper: Classe che implementa la ricerca di un logo aziendale analizzando gli attributi id dei tag <img ...> alla ricerca della parola “logo”;

• ImgSrcLogoScraper: Classe che implementa la ricerca di un logo aziendale analizzando l’attributo src dei tag <img ...> alla ricerca di nomi di file contenenti la parola “logo”;

• LdJsonLogoScraper: Questa classe implementa la ricerca di un logo tramite analisi dei microdata Ld+JSON, precisamente il campo “logo”;

• LinkIconLogoScraper: Classe che implementa la ricerca di un logo tramite analisi delle favicon;

• OpenGraphLogoScraper: Questa classe implementa la ricerca di un logo tramite l’analisi dei tag OpenGraph creati da Facebook;

• TwitterTagLogoScraper: Questa classe implementa la ricerca di un logo tramite l’analisi dei tag legati alle Twitter Cards.

5.5.1.4 Web Crawler

Questo pacchetto contiene i crawler utilizzati, in forma di stadio di pipeline, per l’esplorazione dei siti web aziendali, alla ricerca di una pagina dedicata ai contatti aziendali. Questi crawler fanno uso del pacchetto Bypassers per poter superare gli ostacoli che possono essere incontrati nella navigazione.

5.5.1.4.1 Classi

• SitemapDetectorStage: Questa classe si occupa dell’analisi del file robots.txt per rilevare l’eventuale presenza di Sitemap XML all’interno del sito web;

• SitemapCrawlerStage: Classe che si occupa dell’esplorazione della sitemap, se disponibile, alla ricerca di una pagina dedicata ai contatti aziendali;

• WebsiteLinkCrawler: Utilizzata in caso non esista una sitemap XML, questa classe implementa un crawler di link che esplora il sito web aziendale alla ricerca di una pagina dedicata ai contatti aziendali.

5.5.1.5 Page Scrapers

Questo pacchetto contiene, in forma di stadio di pipeline, gli scraper usati sulle pagine dei contatti rilevate dagli stadi del Web Crawler.

• PhoneScraper: Questa classe si occupa dell’implementazione della ricerca di numeri telefonici;

• VATScraper: Classe che si occupa dell’implementazione della ricerca di partite IVA all’interno dei siti aziendali;

• EmailScraper: Classe che implementa la ricerca di indirizzi email all’interno dei siti web aziendali;

• SocialScraper: Questa classe implementa la ricerca di link ai social media;

• AddressScraper: Questa classe implementa la ricerca di indirizzi geografici all’interno dei siti web aziendali.

5.5.1.6 Scraper del Catasto

Questo pacchetto contiene, in forma di stadi di pipeline, gli elementi usati per lo scraping del catasto nazionale italiano.

• DownloadStage: Questa classe si occupa della navigazione e dello scaricamento di dati dal catasto, tramite una sessione automatizzata di Google Chrome. Lo scaricamento del file XML contenente la visura catastale sarebbe stato implementato qui. Per ora si occupa solo di recuperare alcuni dati come la categoria di un edificio e la collocazione (foglio, particella, subalterno) di tale edificio, disponibili senza effettuare una visura catastale;

• DecryptStage: Dato che le visure catastali scaricare dall’Agenzia delle Entrate sono firmate digital-mente in un file con estensione p7m, è necessario estrarre le informazioni XML da tale file. Questo è compito di questa classe;

• XMLAnalysisStage: Questa classe si occupa dell’analisi e della ricerca di determinati campi all’interno dei file XML per poterli inserire all’interno di una struttura chiave/valore;

• LandRegisterSaveStage: Questa classe si occupa del salvataggio delle informazioni in database.

A questi va aggiunto uno stadio non usato nell’architettura finale.

• CacheAnalysisStage: Questo stadio era usato per scopi di testing per l’applicazione di un’eventuale cache in cui venissero memorizzati a medio termine i dati ricavati dallo scraping del catasto. Questo stadio è stato lasciato come linea guida per l’eventuale realizzazione di una View Django che controlli l’età di un dato memorizzato.

Documenti correlati