urlparse - Divide un URL nei suoi componenti

Scopo Divide un URL nei suoi componenti
Versione Python 1.4 e successivo

Il modulo urllparse fornisce funzioni per dividere un URL nei suoi compondenti, così come sono definiti dalle relative specifiche RFC

Elaborazione

Il valore restituito dalla funzione urlparse() è un oggetto che appare come una tupla di 6 elementi

from urlparse import urlparse

parsed = urlparse('http://netloc/path;parameters?query=argument#fragment')
print parsed

Le parti di URL disponibili attraverso l'interfaccia della tupla sono lo schema (scheme), la locazione di rete (netloc), il percorso (path), i parametri (params), la query (query) ed il frammento (fragment)

$ python urlparse_urlparse.py

ParseResult(scheme='http', netloc='netloc', path='/path', params='parameters', query='query=argument', fragment='fragment')

Sebbene il valore di ritorno si comporta come una tuple in realtà è una namedtuple, una sottoclasse di tuple che supporta l'accesso alle parti di URL tramite attributi nominali in luogo degli indici. La qual cosa è particolarmente utile se, come me (Doug Hellmann - n.d.t.) non si riesce a ricordare l'ordine dell'indice. Oltre a facilitare la vita del programmatore, l'API per gli attributi offre accesso a parecchi valori non disponibili tramite l'API della tuple.

from urlparse import urlparse
parsed = urlparse('http://user:pass@NetLoc:80/path;parameters?query=argument#fragment')
print 'scheme  :', parsed.scheme
print 'netloc  :', parsed.netloc
print 'path    :', parsed.path
print 'params  :', parsed.params
print 'query   :', parsed.query
print 'fragment:', parsed.fragment
print 'username:', parsed.username
print 'password:', parsed.password
print 'hostname:', parsed.hostname, '(netloc in minuscolo)'
print 'port    :', parsed.port

Gli attributi username e password sono disponibili quando presenti nell'URL mentre valgono None quando non ci sono. hostname ha lo stesso valore di netloc, tutto minuscolo. Il valore di port viene convertito in un intero, se presente, ed a None in caso contrario.

$ python urlparse_urlparseattrs.py

scheme  : http
netloc  : user:pass@NetLoc:80
path    : /path
params  : parameters
query   : query=argument
fragment: fragment
username: user
password: pass
hostname: netloc (netloc in minuscolo)
port    : 80

La funzione urlsplit() è alternativa ad urlparse(). Si comporta in modo leggermente diverso visto che non divide i parametri dall'URL. Questo è utile per gli URL che seguono le specifiche RFC 2396, che supportano parametri per ciascun segmento del percorso (path)

from urlparse import urlsplit
parsed = urlsplit('http://user:pass@NetLoc:80/path;parameters/path2;parameters2?query=argument#fragment')
print parsed
print 'scheme  :', parsed.scheme
print 'netloc  :', parsed.netloc
print 'path    :', parsed.path
print 'query   :', parsed.query
print 'fragment:', parsed.fragment
print 'username:', parsed.username
print 'password:', parsed.password
print 'hostname:', parsed.hostname, '(netloc in minuscolo)'
print 'port    :', parsed.port

Visto che i parametri non sono stati divisi, la API della tupla mostrerà 5 elementi invece che 6, e non c'è l'attributo params

$ python urlparse_urlsplit.py

SplitResult(scheme='http', netloc='user:pass@NetLoc:80', path='/path;parameters/path2;parameters2', query='query=argument', fragment='fragment')
scheme  : http
netloc  : user:pass@NetLoc:80
path    : /path;parameters/path2;parameters2
query   : query=argument
fragment: fragment
username: user
password: pass
hostname: netloc (netloc in minuscolo)
port    : 80

Per dividere semplicemente l'identificatore del frammento dall'URL, qualora occorresse trovare il nome base della pagina da un URL, si usa urldefrag()

from urlparse import urldefrag
original = 'http://netloc/path;parameters?query=argument#fragment'
print original
url, fragment = urldefrag(original)
print url
print fragment

Il valore ritornato è una tupla che contiene l'URL di base ed il frammento.

$ python urlparse_urldefrag.py

http://netloc/path;parameters?query=argument#fragment
http://netloc/path;parameters?query=argument
fragment

Ricostruire

Ci sono diversi modi per ricostruire in una singola stringa un URL diviso. L'oggetto URL elaborato ha un metodo geturl().

from urlparse import urlparse
original = 'http://netloc/path;parameters?query=argument#fragment'
print 'ORIGINALE:', original
parsed = urlparse(original)
print 'ELABORATO:', parsed.geturl()

geturl() funziona solo su di oggetti ritornati da urlparse() oppure urlsplit().

$ python urlparse_geturl.py

ORIGINALE: http://netloc/path;parameters?query=argument#fragment
ELABORATO: http://netloc/path;parameters?query=argument#fragment

Se si ha una normale tupla di valori si può usare urlunparse() per combinarne gli elementi in un URL

from urlparse import urlparse, urlunparse
original = 'http://netloc/path;parameters?query=argument#fragment'
print 'ORIGINALE:', original
parsed = urlparse(original)
print 'ELABORATO:', type(parsed), parsed
t = parsed[:]
print 'TUPLA    :', type(t), t
print 'NUOVO    :', urlunparse(t)

Mentre i valori ritornati da urlparse() possono essere usati come tupla, in questo esempio viene esplicitamente creata una nuova tupla per mostrare che urlunparse() funziona anche con normali tuple.

$ python urlparse_urlunparse.py

ORIGINALE: http://netloc/path;parameters?query=argument#fragment
ELABORATO:  ParseResult(scheme='http', netloc='netloc', path='/path', params='parameters', query='query=argument', fragment='fragment')
TUPLA    :  ('http', 'netloc', '/path', 'parameters', 'query=argument', 'fragment')
NUOVO    : http://netloc/path;parameters?query=argument#fragment

Se l'URL in input comprende anche parti superflue, esse possono essere ignorate dalla versione ricostruita dell'URL.

from urlparse import urlparse, urlunparse
original = 'http://netloc/path;?#'
print 'ORIGINALE:', original
parsed = urlparse(original)
print 'ELABORATO:', type(parsed), parsed
t = parsed[:]
print 'TUPLA    :', type(t), t
print 'NUOVO    :', urlunparse(t)

In questo caso, parameters, query, e fragment sono tutti mancanti nell'URL originale. Il nuovo URL non sembra uguale all'originale, ma è equivalente in base allo standard

$ python urlparse_urlunparseextra.py

ORIGINALE: http://netloc/path;?#
ELABORATO:  ParseResult(scheme='http', netloc='netloc', path='/path', params='', query='', fragment='')
TUPLA    :  ('http', 'netloc', '/path', '', '', '')
NUOVO    : http://netloc/path

Unire

Oltre all'elaborazione dell'URL, urlparse comprende anche urljoin() per costruire URL assoluti da un frammento relativo

from urlparse import urljoin
print urljoin('http://www.example.com/path/file.html', 'anotherfile.html')
print urljoin('http://www.example.com/path/file.html', '../anotherfile.html')

In questo esempio, la porzione relativa del percorso ("../") viene presa in considerazione quanto viene calcolato il secondo URL.

$ python urlparse_urljoin.py

http://www.example.com/path/anotherfile.html
http://www.example.com/anotherfile.html

Vedere anche:

urlparse
La documentazione della libreria standard per questo modulo
urllib2
API alternativa per accedere ad URL remoti
urllib
Ottiene il contenuto di una risorsa identificata da un URL