Pregunta

Esta pregunta ya tiene una respuesta aquí:

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 puedo obtener el netloc: www.amazon.com

Según Python Docs:

Después de las especificaciones de sintaxis 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.

Entonces, es así a propósito. Pero, todavía no sé cómo obtener el NetLoc de esa URL.

Creo que podría verificar si el esquema está presente, y si no lo está, entonces agréguelo y luego analizarlo. Pero esta solución no parece realmente buena.

Tienes una mejor idea?

EDITAR:Gracias por todas las respuestas. Pero, no puedo hacer lo de "Inicio con" que Corey y otros proponen Corey. Porque, si obtengo una URL con otro protocolo/esquema, lo arruinaría. Ver:

Si obtengo esta URL:

ftp://something.com

Con el código propuesto, agregaría "http: //" al inicio y lo arruinarí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 algo de validación, y si no se da ningún esquema, considero que es http: //

¿Fue útil?

Solución

La documentación tiene este ejemplo exacto, justo debajo del texto que pegó. Agregar '//' Si no es, obtendrá lo que desea. Si no sabe si tendrá el protocolo y '//' puede usar una regex (o incluso ver si ya contiene '//') para determinar si necesita o no 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 (Agregar para futuros lectores): una regex para detectar el protocolo sería algo así como re.match('(?:http|ftp|https)://', url)

Otros consejos

Parece que necesita especificar el protocolo para obtener NetLoc.

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

Después de las especificaciones de sintaxis 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.

Entonces 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 Use el protocolo si pasó:

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

¿Has considerado solo verificar la presencia de "http: //" al comienzo de la URL y agregarla si no está allí? Otra solución, suponiendo que la primera parte realmente sea NetLoc y no parte de una URL relativa, es simplemente tomar todo hasta el primer "/" y usarlo como NetLoc.

Este revestimiento lo haría.

netloc = urlparse('//' + ''.join(urlparse(url)[1:])).netloc
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top