¿Cómo puedo anteponer el protocolo ‘http: //’ a una url cuando sea necesario?

Necesito analizar una URL. Actualmente estoy usando urlparse.urlparse () y urlparse.urlsplit ().

El problema es que no puedo obtener el “netloc” (host) de la URL cuando no está presente el esquema. Quiero decir, si tengo la siguiente URL:

www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/ref=sr_1_1?ie=UTF8&qid=1308060974&sr=8-1

No consigo el netloc: www.amazon.com

Según los documentos de python:

Siguiendo las especificaciones de syntax en RFC 1808, urlparse reconoce un netloc solo si es introducido correctamente por ‘//’. De lo contrario, se supone que la entrada es una URL relativa y, por lo tanto, comienza con un componente de ruta.

Por lo tanto, es de esta manera a propósito. Pero, todavía no sé cómo obtener el netloc de esa URL.

Creo que podría comprobar si el esquema está presente y, si no lo está, agregarlo y luego analizarlo. Pero esta solución no parece realmente buena.

Tienes una mejor idea?

EDIT: Gracias por todas las respuestas. Pero, no puedo hacer lo “comience con” lo que proponen Corey y otros. Si obtengo una URL con otro protocolo / esquema, lo estropearía. Ver:

Si obtengo esta URL:

ftp://something.com 

Con el código propuesto, agregaría “http: //” al inicio y lo estropearía.

La solución que encontré

 if not urlparse.urlparse(url).scheme: url = "http://"+url return urlparse.urlparse(url) 

Algo a tener en cuenta:

Primero hago una validación, y si no se da ningún esquema, considero que es http: //

La documentación tiene este ejemplo exacto, justo debajo del texto que pegaste. Agregando ‘//’ si no está allí obtendrá lo que desea. Si no sabe si tendrá el protocolo y ‘//’ puede usar una expresión regular (o simplemente ver si ya contiene ‘//’) para determinar si necesita agregarlo o no.

Su otra opción sería usar split (‘/’) y tomar el primer elemento de la lista que devuelve, que SOLO funcionará cuando la url no tenga protocolo o ‘//’.

EDITAR (agregando para futuros lectores): una expresión regular para detectar el protocolo sería algo así como re.match('(?:http|ftp|https)://', url)

Parece que necesitas especificar el protocolo para obtener netloc.

Añadiéndolo si no está presente podría verse así:

 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 

De los documentos:

Siguiendo las especificaciones de syntax en RFC 1808, urlparse reconoce un netloc solo si es introducido correctamente por ‘//’. De lo contrario, se supone que la entrada es una URL relativa y, por lo tanto, comienza con un componente de ruta.

Así que solo puedes hacer:

 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' 

Si el protocolo es siempre http , puedes usar solo una línea:

 return "http://" + url.split("://")[-1] 

Una mejor opción es usar el protocolo si pasa :

 return url if "://" in url else "http://" + url 

¿Ha considerado solo verificar la presencia de “http: //” al inicio de la URL y agregarlo si no está allí? Otra solución, suponiendo que la primera parte realmente es el netloc y no una parte de una URL relativa, es agarrar todo hasta la primera “/” y usarlo como el netloc.

Este trazador de líneas lo haría.

 netloc = urlparse('//' + ''.join(urlparse(url)[1:])).netloc