Analizar los URI personalizados con urlparse (Python)

Mi aplicación crea URIs personalizados (o URLs) 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?

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

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

 parts = urlparse.urlparse("qqqq://base/id#hint") fake_url = "http:" + parts[2] parts2 = urlparse.urlparse(fake_url) 

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 

El uri será tratado 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'} 

También hay una biblioteca llamada furl que te da el resultado que deseas:

 >>>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' 

La pregunta parece estar desactualizada. Como 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') 

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 urlparse, pero de todos modos conoce el esquema.

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='') 

Puedes usar la biblioteca yurl . A diferencia de purl o furl, no intenta arreglar errores 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')