Come posso preparare il protocollo "http: //" a un URL quando necessario? [duplicare
-
27-10-2019 - |
Domanda
Questa domanda ha già una risposta qui:
Devo analizzare un URL. Attualmente sto usando Urlparse.urlparse () e urlparse.urlsplit ().
Il problema è che non riesco a ottenere il "netloc" (host) dall'URL quando non è presente lo schema. Voglio dire, se ho il seguente URL:
www.amazon.com/programming-python-mark-lutz/dp/0596158106/ref=sr_1_1?ie=utf8&qid=1308060974&sr=8-1
Non riesco a ottenere il netloc: www.amazon.com
Secondo Python Docs:
Seguendo le specifiche di sintassi in RFC 1808, Urlparse riconosce un netloc solo se è correttamente introdotto da '//'. Altrimenti si presume che l'input sia un URL relativo e quindi inizi con un componente del percorso.
Quindi, è così apposta. Ma ancora non so come ottenere il netloc da quell'URL.
Penso che potrei verificare se lo schema è presente, e se non lo è, quindi aggiungerlo e poi analizzarlo. Ma questa soluzione non sembra davvero buona.
Hai un'idea migliore?
MODIFICARE:Grazie per tutte le risposte. Ma non posso fare la cosa "startwith" che è proposta da Corey e altri. BeCuse, se ricevo un URL con altri protocolli/schemi, lo sballlerei. Vedere:
Se ottengo questo URL:
ftp://something.com
Con il codice proposto, aggiungerei "http: //" all'inizio e lo sbaglierei.
La soluzione che ho trovato
if not urlparse.urlparse(url).scheme:
url = "http://"+url
return urlparse.urlparse(url)
Qualcosa da notare:
Prima faccio un po 'di convalida e se non viene dato alcun schema lo considero http: //
Soluzione
La documentazione ha questo esatto esempio, appena sotto il testo che hai incollato. Aggiungendo '//' Se non è lì otterrai quello che vuoi. Se non sai se avrà il protocollo e '//' puoi usare un regex (o anche solo vedere se contiene già '//') per determinare se è necessario aggiungerlo o meno.
La tua altra opzione sarebbe quella di utilizzare Split ('/') e prendere il primo elemento dell'elenco che restituisce, che funzionerà solo quando l'URL non ha protocollo o '//'.
EDIT (aggiungendo per i futuri lettori): un regex per rilevare il protocollo sarebbe qualcosa di simile re.match('(?:http|ftp|https)://', url)
Altri suggerimenti
Sembra che tu debba specificare il protocollo per ottenere netloc.
Aggiungendolo se non è presente potrebbe apparire così:
import urlparse
url = 'www.amazon.com/Programming-Python-Mark-Lutz'
if '//' not in url:
url = '%s%s' % ('http://', url)
p = urlparse.urlparse(url)
print p.netloc
Dai documenti:
Seguendo le specifiche di sintassi in RFC 1808, Urlparse riconosce un netloc solo se è correttamente introdotto da '//'. Altrimenti si presume che l'input sia un URL relativo e quindi inizi con un componente del percorso.
Quindi puoi solo fare:
In [1]: from urlparse import urlparse
In [2]: def get_netloc(u):
...: if not u.startswith('http'):
...: u = '//' + u
...: return urlparse(u).netloc
...:
In [3]: get_netloc('www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/ref=sr_1_1?ie=UTF8&qid=1308060974&sr=8-1')
Out[3]: 'www.amazon.com'
In [4]: get_netloc('http://www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/ref=sr_1_1?ie=UTF8&qid=1308060974&sr=8-1')
Out[4]: 'www.amazon.com'
In [5]: get_netloc('https://www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/ref=sr_1_1?ie=UTF8&qid=1308060974&sr=8-1')
Out[5]: 'www.amazon.com'
Se il protocollo è sempre http Puoi usare solo una riga:
return "http://" + url.split("://")[-1]
Un'opzione migliore è di Usa il protocollo se è passato:
return url if "://" in url else "http://" + url
Hai preso in considerazione la possibilità di verificare la presenza di "http: //" all'inizio dell'URL e aggiungerlo se non è lì? Un'altra soluzione, supponendo che la prima parte sia davvero il netloc e non parte di un URL relativo, è quella di prendere tutto fino al primo "/" e usarlo come netloc.
Questo fodera lo farebbe.
netloc = urlparse('//' + ''.join(urlparse(url)[1:])).netloc