149 lines
5.8 KiB
Markdown
149 lines
5.8 KiB
Markdown
# Anche i robot navigano il web
|
|
~web scraping, estrarre informazioni da Internet~
|
|
|
|
##cosa c'e' sull'Internet
|
|
|
|
- informazioni
|
|
- servizi
|
|
- persone che ne fruiscono
|
|
|
|
### Informazioni
|
|
Le informazioni descrivono la realta' in cui viviamo e sono la base su cui prendiamo delle decisioni. Sono facili da quantificare. Sono facili da manipolare.
|
|
|
|
#### Tipi di informazione che si trova sull' Internet
|
|
|
|
(in ordine dalla piu' alla meno rara)
|
|
- edita o elaborata (libri, film, tracce musicali, articoli di un blog) - alto valore intrinseco.
|
|
- non elaborata (informazioni metereologiche, post su facebook, indirizzo e recapito di una attività commerciale) - basso valore intrinseco.
|
|
- metainformazione - (log di un server web/DNS) - valore intrinseco nullo
|
|
|
|
#### Manipolazione
|
|
|
|
La manipolazione dell'informazione la carica di valore, la spiega, la rende fruibile. Invormazioni di tipo diverso necessitano tipi diversi di manipolazione per acquistare valore intrinseco.
|
|
|
|
Ad esempio un log di Apache (server web):
|
|
|
|
```64.242.88.10 - - [07/Mar/2004:16:05:49 -0800] "GET /twiki/bin/edit/Main/Double_bounce_sender?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846```
|
|
|
|
per assumere significato deve essere contestualizzato con altre informazioni su:
|
|
- utente a cui corrisponde l'indirizzo IP
|
|
- contenuti a cui corrisponde il percorso
|
|
- altri log a cui associarlo per riprodurre la history di navigazione dell'utente
|
|
|
|
### Manipolare l'informazione
|
|
*storiella:
|
|
Giangiorgino si sveglia tutte le mattine per andare a prendere lo stesso treno che -di tanto in tanto- non arriva alla stazione per l'orario previsto.
|
|
Quando questo succede Giangiorgino deve correre per prendere un autobus e due tram se vuole sperare di arrivare a destinazione entro la stessa ora -cosa che solitamente non riesce a fare-.
|
|
Giangiorgino, pensandoci su, capisce di avere le seguenti opzioni:
|
|
- svegliarsi mezz'ora prima ogni giorno
|
|
- scaricare l'ultima App Trenissimissimo che gli invia ogni ora di ogni giorno notifiche in tempo reale sullo stato dei 36 treni circolanti sulla tratta
|
|
- **manipolare l'informazione*** - scrivere un programma che ogni giorno decide sulla base dello stato dei treni l'ora a cui puntare la sveglia
|
|
|
|
Ecco quindi che il processo ripetitivo di:
|
|
|
|
- a una data ora visitare il sito trenissimissimo.com
|
|
- verificare lo stato di percorrenza del treno
|
|
- scegliere il percorso ottimale
|
|
- fissare la sveglia di conseguenza
|
|
|
|
Può essere facilmente delegato a un bot, un processo che una volta avviato è in grado di proseguire la sua esecuzione senza l'intervento di un umano.
|
|
|
|
Per fare questo è necessario individuare le risorse accessibili tramite la rete che rendano disponibile, in formato più o meno elaborato le informazioni sullo stato dei treni in circolazione. (Giangiorgino ha già controllato, il sito trenissimissimo.com fornisce questo servizio)
|
|
|
|
|
|
####Premessa
|
|
|
|
|
|
Il sito da cui andremo ad estrarre le informazioni e' il seguente:
|
|
|
|
```http://viaggiatreno.it/vt_pax_internet/mobile```
|
|
|
|
Possiamo quindi iniziare a navigarlo tramite un browser (preferibilmente firefox o chromium/chrome) per farci un idea sul suo funzionamento. E' molto utile in questa fase usare gli strumenti inclusi nel browser come
|
|
|
|
Il network monitor di firefox:
|
|
https://developer.mozilla.org/it/docs/Tools/Network_Monitor
|
|
|
|
Oppure l'equivalente per Chrome:
|
|
https://developers.google.com/web/tools/chrome-devtools/network-performance/resource-loading
|
|
|
|
|
|
|
|
####Prerequisiti
|
|
|
|
|
|
- browser web
|
|
- python ~2.7 con i seguenti moduli installati *(durante il workshop vi aiuteremo durante l'installazione)*
|
|
- ```requests``` che ci permette di gestire le chiamate HTTP[s] e di estrarne il codice HTML
|
|
- ```beautifulsoup``` (bs4) che ci permette di operare selezioni all'interno del codice estratto
|
|
|
|
|
|
####Documentazione
|
|
|
|
- http://docs.python-requests.org/en/master/
|
|
- https://www.crummy.com/software/BeautifulSoup/bs4/doc/
|
|
|
|
|
|
####Esecuzione
|
|
|
|
Il punto di partenza e' quindi creare un nuovo file che chiameremo `scraper.py` con il seguente contenuto:
|
|
|
|
# importiamo il modulo requests
|
|
import requests
|
|
|
|
|
|
# modifichiamo gli header in modo da simulare una richiesta proveniente da un browser web (in questo caso firefox) per evitare possibili ban
|
|
headers = requests.utils.default_headers()
|
|
headers.update({"User-Agent": "Mozilla/5.0"})
|
|
|
|
# effettuiamo la richiesta
|
|
r = requests.get('http://viaggiatreno.it/vt_pax_internet/mobile', headers=headers)
|
|
|
|
# stampiamo il risultato
|
|
print(r.text)
|
|
|
|
salviamo il file ed eseguiamolo:
|
|
|
|
$ python scraper.py
|
|
|
|
in modo da vedere il codice html estratto dalla pagina.
|
|
|
|
Una volta fatto questo torniamo sul sito ed effettuiamo una ricerca per stazione, tenendo aperto il network monitor del browser. Dopodiche', cerceremo di riprodurre la stessa ricerca utilizzando python:
|
|
|
|
#! /usr/bin/env python
|
|
import requests
|
|
from bs4 import BeautifulSoup
|
|
|
|
headers = requests.utils.default_headers()
|
|
headers.update({"User-Agent": "Mozilla/5.0"})
|
|
|
|
data = {
|
|
|
|
'codiceStazione': 'S01700Milano+Centrale',
|
|
'lang': 'IT',
|
|
}
|
|
|
|
r = requests.post('http://viaggiatreno.it/vt_pax_internet/mobile/stazione', headers=headers, data=data)
|
|
|
|
print(r.text.encode('utf-8'))
|
|
|
|
Ora che abbiamo il codice html della risposta alla nostra ricerca, possiamo usare beautifulsoup per estrarre solo le informazioni relative ai treni:
|
|
|
|
#! /usr/bin/env python
|
|
import requests
|
|
from bs4 import BeautifulSoup
|
|
|
|
headers = requests.utils.default_headers()
|
|
headers.update({"User-Agent": "Mozilla/5.0"})
|
|
|
|
data = {
|
|
'codiceStazione': 'S01700Milano+Centrale',
|
|
'lang': 'IT',
|
|
}
|
|
|
|
r = requests.post('http://viaggiatreno.it/vt_pax_internet/mobile/stazione', headers=headers, data=data)
|
|
|
|
soup = BeautifulSoup(r.text, 'html.parser')
|
|
treni = soup.find_all("div", class_="bloccorisultato")
|
|
|
|
for treno in treni:
|
|
print(treno) |