Scopo | Divide un URL nei suoi componenti |
Versione Python | 1.4 e successivo |
A partire dal 1 gennaio 2021 le versioni 2.x di Python non sono piu' supportate. Ti invito a consultare la corrispondente versione 3.x dell'articolo per le versioni 3.x di Python
Il modulo urllparse fornisce funzioni per dividere un URL nei suoi compondenti, così come sono definiti dalle relative specifiche RFC
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
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
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