Mi aplicación crea URI personalizados (¿o URL?) Para identificar objetos y resolverlos. El problema es que el módulo urlparse de Python se niega a analizar esquemas de URL desconocidos como analiza http.

Si no ajusto las listas de usos_ * de urlparse, obtengo esto:

>>> urlparse.urlparse("qqqq://base/id#hint")
('qqqq', '', '//base/id#hint', '', '', '')
>>> urlparse.urlparse("http://base/id#hint")
('http', 'base', '/id', '', '', 'hint')

Esto es lo que hago, y me pregunto si hay una mejor manera de hacerlo:

import urlparse

SCHEME = "qqqq"

# One would hope that there was a better way to do this
urlparse.uses_netloc.append(SCHEME)
urlparse.uses_fragment.append(SCHEME)

¿Por qué no hay mejor manera de hacer esto?

13
u0b34a0f6ae 13 sep. 2009 a las 19:10

6 respuestas

La mejor respuesta

Creo que el problema es que los URI no tienen un formato común después del esquema. Por ejemplo, mailto: urls no están estructurados de la misma manera que http: urls.

Usaría los resultados del primer análisis, luego sintetizaría una URL http y la analizaría nuevamente:

parts = urlparse.urlparse("qqqq://base/id#hint")
fake_url = "http:" + parts[2]
parts2 = urlparse.urlparse(fake_url)
3
Ned Batchelder 13 sep. 2009 a las 15:15

Puede usar la yurl biblioteca. A diferencia de Purl o Furl, no intenta corregir los errores de urlparse. Es nuevo compatible con la implementación RFC 3986.

>>> import yurl
>>> yurl.URL('qqqq://base/id#hint')
URLBase(scheme='qqqq', userinfo=u'', host='base', port='', path='/id', query='', fragment='hint')
0
homm 25 dic. 2013 a las 15:35

Intente eliminar el esquema por completo y comience con // netloc, es decir:

>>> SCHEME="qqqq"
>>> url="qqqq://base/id#hint"[len(SCHEME)+1:]
>>> url
'//base/id#hint'
>>> urlparse.urlparse(url)
('', 'base', '/id', '', '', 'hint')

No tendrá el esquema en el resultado de urlparse, pero de todos modos lo conoce.

También tenga en cuenta que Python 2.6 parece manejar esta url muy bien (aparte del fragmento):

$ python2.6 -c 'import urlparse; print urlparse.urlparse("qqqq://base/id#hint")'
ParseResult(scheme='qqqq', netloc='base', path='/id#hint', params='', query='', fragment='')
1
Joe Crobak 5 feb. 2011 a las 13:33

La pregunta parece estar desactualizada. Desde al menos Python 2.7 no hay problemas.

Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
>>> import urlparse
>>> urlparse.urlparse("qqqq://base/id#hint")
ParseResult(scheme='qqqq', netloc='base', path='/id', params='', query='', fragment='hint')
2
OrangeDog 20 ene. 2016 a las 14:33

También hay una biblioteca llamada furl que le da el resultado que desea:

>>>import furl
>>>f=furl.furl("qqqq://base/id#hint");
>>>f.scheme
'qqqq' 

>>> f.host
'base'  
>>> f.path
Path('/id')
>>>  f.path.segments
['id']
>>> f.fragment                                                                                                                                                                                                                                                                 
Fragment('hint')   
>>> f.fragmentstr                                                                                                                                                                                                                                                              
'hint'
3
sumid 4 jun. 2013 a las 21:22

También puede registrar un controlador personalizado con urlparse:

import urlparse

def register_scheme(scheme):
    for method in filter(lambda s: s.startswith('uses_'), dir(urlparse)):
        getattr(urlparse, method).append(scheme)

register_scheme('moose')

Esto agregará su esquema de URL a las listas:

uses_fragment
uses_netloc
uses_params
uses_query
uses_relative

La uri se tratará como http y devolverá correctamente la ruta, el fragmento, el nombre de usuario / contraseña, etc.

urlparse.urlparse('moose://username:password@hostname:port/path?query=value#fragment')._asdict()
=> {'fragment': 'fragment', 'netloc': 'username:password@hostname:port', 'params': '', 'query': 'query=value', 'path': '/path', 'scheme': 'moose'}
23
toothygoose 8 jul. 2011 a las 07:58