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: //

È stato utile?

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top