Web
In questa lezione dimostreremo come usare semplici funzioni Python per leggere dati dal Web. Questa lezione non sarà per nulla esaustiva, ma serve per dare degli esempi di cose semplici da fare in Python.
Errata: Per salvare le immagini, aprire il file in modalità 'wb'
. Le note al seguito sono aggiornate.
Url
Sul Web, le risorse sono identificate da un URL, Uniform Resource Locator. Un esempio di URL è http://en.wikipedia.org/wiki/Uniform_resource_locator
. Lo URL è simile al nome di un file ed è composto da tre parti: lo schema http://
, il nome del dominio en.wikipedia.org
e il nome della risorsa /wiki/Uniform_resource_locator
. L'URL diventa più complicato per siti dove l'utente può interagire come Google, dove lo URL contiene anche i parametri i ricerca. Per il momento focalizziamoci su URL semplici.
Accedere a URL
In Python si può accedere a molte pagine web direttamente usando la libreria urilib2
della librearia standard. Ad esempio, per scaricare una pagina dal sito di Python e stampare l'HTML bast fare:
import urllib2
f = urllib2.urlopen('http://python.org/')
print f.read()
Per scaricare un'immagine e salvarla su disco basta fare:
f = urllib2.urlopen(urlimmagine)
with open('python-logo.png', 'wb') as w:
w.write( f.read() )
Ad esempio, se si fa girare il codicie precedente con URL http://www.python.org/community/logos/python-logo.png, si può salvare l'immagine
Web Crawling
Per copiare interi siti Web, possiamo semplicemente seguire i link trovati su una pagina e copiare tutte le pagine a partire da una sorgente. Questo si chiama web crawling ed è fatto dai search engine per craersi una copia di Internet per eseguire la ricerca (come avevmo fatto sui libri). Ad esempio, un semplicissimo crawler inizia da una pagina scaricata con urllib2
, ne legge l'HTML e lo memorizza usando le classi introdotte in precedenta, lista i link, e mette i link in una lista da scaricare. Con gli ingredienti che abbiamo dato nel corso, scrivere una crawler è semplicissimo.
Unicode
Una cosa da notare è che tutti i siti Web possono avere testo scritto in qualunque. L' ASCII supporta solo i caratteri per la lingua inglese (senza accenti). Per lavorare sul Web ci serve un modo per codificare i caratteri presenti in tutti le lingue del mondo.
In Python, il tipo unicode
supporta la codica in qualunque lingua. VAriabili di tipo unicode
supportano le stesse operazioni delle stringhe, quindi il codice non cambia in modo significativo. Quello invece che cambia è come accedere a testo unicode
salvato in file (su disco o sul Web). Per salvare i caratteri dove accordarci su una codica, simile all'ASCII. Sfortunatamente, esistono tante varianti di unicode
cosa che rende frustrante lavorare su file in lingue diverse. Quella più comune però è chiamata UTF8, simile all'ASCII. In Python, possiamo leggere un file in formato unicode e riscriverlo specificando in modo esplicito la codifica.
# legge da un file utf8, memorizza in una variabile unicode
with open('filein.txt','r') as f:
text = f.read().decode('utf8')
# scrive una variabile unicode, in un file utf8
with open('fileout.txt','w') as f:
f.write(text.encode('utf8'))
APIs
Mentre è possibile accedere a pagine e immagini statiche usando urllib2
, molti siti moderni usano il Web solo come interfaccia per accedere a servizi. Esempi di questo tipo sono Google, Facebook o Twitter. Spesso questo compagnie offrono modo diretti per accedere ai dati dette API. API è in realtà un termine molto più generico – qui intendiamo specificatamente le API del Web. Ogni API è diversa e specifica al servizio a cui si riferisce.
Possiamo ad esempio accedere a Twitter usando la libreria twitter
scaricabile da http://pypi.python.org/pypi/twitter o meglio installabile usando pip install twitter
. Questa libreria dà accesso diretto ai dati di twitter e permette anche di mandare tweets da Python. Dopo aver installato la libreria e fatta l'autentizazione (come da instruzioni della libreria), possiamo vedere sia una porzione di tutti i tweet del mondo mandati in tempo reale, o leggere i tweet di una persona specifica, come Barack Obama. Qui di seguito facciamo vedere questi un esempio che visualizza lo stream dei dati twitter.
from twitter import TwitterStream, UserPassAuth, Twitter
# put a file twitter-pwd.txt with your
# username and password in differnt lines
with open('twitter-pwd.txt','r') as f:
lines = f.read().splitlines()
username = lines[0].strip()
password = lines[1].strip()
# open stream
twitter_stream = TwitterStream(auth=UserPassAuth(username,password))
# print stream
for tweet in twitter_stream.statuses.sample():
if 'delete' in tweet: continue # skip deleted
print tweet['user']['screen_name']
print ' ', tweet['text']
print ''
Ed infine un esempio che fa una ricerca su twitter for un determinato tag.
from twitter import Twitter
# perform a search
twitter_search = Twitter(domain="search.twitter.com")
# Search for the latest News on #berlusconi
search = twitter_search.search(q="#roma")
for tweet in search['results']:
print tweet['text']
print ''
Web Scraping
Le operazioni di prima di potevano fare anche usando l'interfaccia web. Quello che è interessante è fare analisis, anche semplici, dei dati usando programmi python. Per fare ciò possiamo usare l'utility twitter-log
installata con la libreria per salvare su disco un archivio dei dati di un utente twitter. Usando il codice seguente si può convertire questi dati in JSON, un formato per lo scambio dei dati. Non faremo questa conversione a lezione.
#! /usr/bin/env python -B
import json
names = [ 'BarackObama', 'Corriereit', 'MittRomney', 'repubblicait' ]
def convert(name):
def _blank(line):
return not line or line.isspace()
with open(name+'.log.txt','r') as f:
lines = f.read().decode('utf8').splitlines()
tweets = []
while lines:
while lines and _blank(lines[0]):
lines = lines[1:]
if not lines: break
print lines[0]
line, lines = lines[0], lines[1:]
name, id = tuple(line.split())
line, lines = lines[0], lines[1:]
_, _, month, day, time, _, year = tuple(line.split())
while lines and _blank(lines[0]):
lines = lines[1:]
text = ''
while (lines and
not (_blank(lines[0]) and
_blank(lines[1]))):
text += lines[0]
lines = lines[1:]
tweets += [ {
'name': name,
'id': id,
'time': time,
'date': day+'-'+month+'-'+year,
'text': text
} ]
with open(name+'.json','w') as f:
json.dump(tweets,f,indent=True)
for name in names:
convert(name)
Dopo questo possiamo fare un programmino semplice per vedere le parole più usate da un twitter user con il semplice programma
import json, string
names = [ 'BarackObama', 'Corriereit', 'MittRomney', 'repubblicait' ]
for name in names:
with open('twitter-log/'+name+'.json','r') as f:
tweets = json.load(f)
nlinks = 0
words = {}
for tweet in tweets:
text = tweet['text']
if 'http://' in text: nlinks += 1
for c in string.punctuation+'""':
text = text.replace(c,' ')
twords = text.lower().split()
for word in twords:
if word in words: words[word] += 1
else: words[word] = 1
print name, len(tweets)
print 'links:', nlinks
for word, count in words.items():
if count > 0.05 * len(tweets):
print ' ', word, count