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