Creare una pipeline di web scraping con i servizi AWS
Cos’è il web scraping e perché ci serve
Il web scraping è una tecnica utilizzata per estrarre i dati sottostanti di una pagina web. Questi dati sono generalmente costituiti dai file di testo HTML/CSS/JavaScript e da altre risorse, come le immagini, i video e i font a cui fanno riferimento, che un browser utilizza per visualizzare quella specifica pagina web. I dati raccolti vengono poi salvati in file o in un database per essere elaborati ulteriormente.
In TeleportHQ, siamo costantemente alla ricerca di modi per migliorare le nostre capacità di generazione del codice a partire da wireframe o progetti ad alta definizione. Poiché questo processo fa ampio uso del machine learning, abbiamo bisogno di notevoli quantità di dati selezionati su cui lavorare. Il dataset RICO è stato sufficiente per iniziare con le pagine native per dispositivi mobili, ma abbiamo ritenuto che valesse la pena impegnarci a creare un dataset di pagine web proprietario, per diversi motivi:
- Esistono pochissimi dataset pubblici che soddisfano i nostri requisiti di qualità
- Controllo sui dati: possiamo specificare esattamente quali informazioni recuperare dai siti web
- Scalabilità: con il progredire della ricerca, avremo bisogno di quantità sempre maggiori di dati
- Organizzazione e accessibilità: offrire un modo rapido e semplice per accedere ai dati
Come funziona?
Lo scraping di una pagina web prevede due passaggi: il recupero e l'estrazione dei dati. Il recupero consiste nello scaricare una pagina, ovvero il codice HTML iniziale e tutte le risorse a cui fa riferimento: è esattamente ciò che fa un browser quando visualizziamo la pagina. Pertanto, il crawling è una componente fondamentale dello scraping web: recuperiamo le pagine per elaborarle in seguito. Nel nostro caso, il crawling viene eseguito con Puppeteer, una libreria per Node che mette a disposizione un'API di alto livello per controllare Chrome o Chromium. Avviando Chromium in modalità headless, possiamo recuperare una pagina web e usarla per estrarre i dati.
Esistono molti modi per estrarre dati da un sito web, ma nel nostro caso utilizziamo una tecnica chiamata parsing del DOM. Quando una pagina web viene caricata, il browser crea un Document Object Model della pagina, che viene poi utilizzato per visualizzarla sullo schermo. Il modello DOM HTML è strutturato come un albero di oggetti, che può essere analizzato per recuperare le informazioni necessarie.
Per ogni elemento del DOM recuperiamo un elenco di attributi che forniscono informazioni su dimensioni, posizione, colore e molto altro.
I primi problemi
Dopo aver lavorato con il dataset dei siti web, abbiamo notato che molti siti al suo interno causavano problemi, come la sovrapposizione dei riquadri o la visualizzazione di pagine 404.
La sovrapposizione dei riquadri era causata da elementi invisibili o fuori dall'area visualizzata, caricati nel DOM ma non mostrati fino al verificarsi di un determinato evento. Non stiamo dicendo che questi siti siano progettati male, ma avrebbero potuto causare incongruenze durante l'addestramento di un modello di machine learning. La pagina 404 compariva perché il browser riusciva a comunicare con il server, ma il server non trovava ciò che era stato richiesto. Il DOM della pagina 404 viene comunque caricato e la pagina analizzata, ma non è possibile estrarne informazioni utili.
Un classificatore di machine learning in soccorso
La soluzione che abbiamo trovato è stata creare un classificatore di machine learning che ci restituisse la probabilità che un sito web fosse adatto all'uso. Abbiamo iniziato annotando manualmente i siti web in diverse categorie, adottando un punto di vista oggettivo e seguendo alcuni criteri, come: «I riquadri si sovrappongono?» oppure «La pagina contiene informazioni sufficienti?». Per semplificare il processo, abbiamo creato un'applicazione web personalizzata con R Shiny, dotata di una visualizzazione specifica per annotare i dati, un elemento alla volta.
Abbiamo poi usato le annotazioni come dati di addestramento per il nostro modello XGBoost e, dopo averlo testato, abbiamo ottenuto un'accuratezza dell'85%. Per la distribuzione abbiamo usato SageMaker, soprattutto perché la libreria XGBoost era troppo grande per essere inclusa in un container Lambda.
Probabilità medie che i siti web siano buoni in relazione al numero di elementi nel DOM
Probabilità su 200.000 siti web
Scalabilità
La prima versione del Web Scraper era un'applicazione Node.js che utilizzava chiamate asincrone per parallelizzare il processo di analisi. È stato un buon inizio e ci ha permesso di analizzare rapidamente i nostri primi siti web. Tuttavia, quando abbiamo provato a parallelizzare il lavoro, abbiamo subito incontrato i limiti hardware del nostro computer locale. La RAM si esauriva rapidamente e la CPU non riusciva a gestire il carico. Per aumentare la potenza di elaborazione, abbiamo deciso di spostare l'analizzatore su un'istanza EC2 m4.4xlarge di AWS, dotata di 16 vCPU e 64 GB di RAM. Questo è stato fatto esclusivamente per aumentare la velocità di analisi.
Il principale svantaggio di questo approccio era che tutto doveva essere fatto manualmente: l'inserimento dei siti web, la creazione delle funzionalità, l'esecuzione delle inferenze del modello di machine learning, il caricamento su S3 al termine di ogni operazione e molto altro. Una soluzione a questo problema consisteva nel creare una pipeline che eseguisse automaticamente tutte queste operazioni e le organizzasse per renderle più accessibili. Inoltre, AWS Lambda supporta un gran numero di funzioni concorrenti, consentendoci di analizzare più siti web al minuto.
Struttura della pipeline
La pipeline contiene due tipi di elementi: processori e archiviazione. I processori sono funzioni Lambda attivate da determinati eventi; l'archiviazione è costituita dal database NoSQL DynamoDB e da un bucket S3. DynamoDB contiene informazioni di alto livello sui siti web, come il dominio, la pagina o l'ora in cui il sito è stato analizzato. Il bucket S3 è organizzato in tre cartelle:
- Multi-site-CSV: contiene file CSV con più siti web da analizzare
- Meta: contiene le informazioni su un sito web necessarie per l'analisi
- Data: contiene i risultati dell'analizzatore, ovvero uno screenshot e un file JSON con tutte le informazioni estratte dal DOM
Punto di partenza
Per avviare il processo, dobbiamo inserire uno o più siti web. Possiamo farlo in due modi. Il primo consiste nell'accedere a un endpoint passando l'URL come parametro della richiesta. In questo modo verrà analizzato solo il sito web specificato e la risposta restituirà il suo nome in S3. Il secondo consiste nel caricare un file CSV nella cartella «multi-site-CSV» con tutti i siti web da analizzare.
Trigger Lambda
Nella pipeline ci sono 3 funzioni Lambda che ne alimentano il funzionamento.
La prima Lambda è la funzione «CSV-split», che si attiva ogni volta che viene caricato un file CSV nella cartella «multi-site-CSV». Suddivide il file CSV di grandi dimensioni in file più piccoli, ciascuno contenente informazioni su un sito web, e li carica nella cartella «meta» di S3.
La seconda Lambda è il fulcro della pipeline: la funzione «parse-added». Questa Lambda contiene il parser ed è la risorsa che richiede più risorse. Si attiva ogni volta che viene caricato un nuovo file CSV nella cartella «meta» e analizza il sito web corrispondente. Se l'analisi riesce, restituisce uno screenshot, un file JSON e un elenco di link interni, che verranno utilizzati in seguito nella pipeline per l'analisi ricorsiva. Aggiorna quindi il database per il sito web corrispondente e carica i due file nella cartella «data» del bucket S3. Se l'analisi non riesce, gli elementi in S3 e nel database vengono eliminati per evitare incongruenze.
La terza e ultima funzione Lambda gestisce la parte di machine learning della pipeline. Si attiva ogni volta che viene caricato un file JSON nella cartella «data» e utilizza i dati contenuti nel JSON per eseguire l'ingegneria delle caratteristiche. Invia poi una richiesta, contenente le caratteristiche, all'endpoint SageMaker, che restituisce la probabilità che il sito web sia valido. Se la probabilità è sufficientemente alta, carica un file CSV con tutti i link interni del sito web corrispondente nella cartella «multi-site-CSV». Il caricamento attiva la prima Lambda, dando così origine a un ciclo.
Risultati
Prestazioni
Le prestazioni sono migliorate notevolmente nel corso dello sviluppo. L'applicazione Node.js analizzava in media 20 siti web al minuto. Dopo il passaggio a EC2 e alcune altre ottimizzazioni, siamo riusciti a portare la velocità di analisi a 240 siti web al minuto. Tuttavia, questo risultato non è nulla in confronto ai 4500 siti web al minuto raggiunti utilizzando AWS Lambda.
Cosa possiamo fare con i dati?
Uno dei percorsi che abbiamo scelto di intraprendere è il rilevamento di oggetti negli screenshot delle pagine web. Le informazioni estratte dai siti web ci hanno fornito tutto ciò di cui avevamo bisogno per iniziare.
A sinistra - Previsione / A destra - Valore di riferimento
Il nostro obiettivo è rilevare con elevata precisione gli elementi di una pagina web. Utilizziamo le coordinate di ciascun elemento (superiore, sinistra, larghezza e altezza) per calcolare i riquadri corrispondenti e poi impiegarli per addestrare il modello di apprendimento automatico. I dati estratti dal DOM per l’esempio qui sopra erano incoerenti e, di conseguenza, venivano visualizzati elementi invisibili oppure, al contrario, alcuni elementi non venivano rilevati. Poiché abbiamo utilizzato siti web di qualità per l’addestramento, il modello è riuscito a dedurre anche la posizione di quegli elementi (il paragrafo con l’immagine di sfondo nella parte superiore della pagina) e a ignorare quelli invisibili (gli elementi sul lato sinistro).
Inizialmente abbiamo classificato ogni elemento come testo o immagine, ma man mano che lo sviluppo procede ci occuperemo anche di altri tag HTML, come tabelle, elenchi o campi di input.
Conclusioni
Il numero di dataset web accessibili al pubblico e curati è molto limitato, e i pochi disponibili contengono un numero ristretto di dati. Questo lavoro preparatorio ci ha permesso di acquisire autonomia e di controllare con precisione la qualità e la quantità dei nostri dati. Inoltre, un importante vantaggio aggiuntivo è la possibilità di ricostruire dinamicamente, in poche ore, nuovi dataset aggiornati e migliorati. Se sei un ricercatore e desideri accedere ai nostri dati, non esitare a contattarci.
Durante la creazione abbiamo anche imparato molto sul nostro settore e sulle tecnologie alla base. Queste conoscenze ci hanno fornito un contesto più ampio per capire come orientare la nostra ricerca sull’automazione del processo di realizzazione delle interfacce utente.
Come sempre, siamo molto interessati a confrontarci con altri appassionati su questo argomento. Se ti interessa il nostro lavoro, non esitare a contattarci tramite uno dei nostri canali social, elencati nel piè di pagina di questo sito.
Commenti
Non ci sono ancora commenti. Sii il primo a condividere le tue opinioni.