2009-09-13 24 views
13

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

Si No ajusto urlparse de listas uses_ * me sale esto:

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

Aquí 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 una mejor manera de hacer esto?

+0

urlparse también toma otro parametro, no estoy en eso no hace ninguna diferencia. (Ejemplo: 'urlparse.urlparse (" qqqq: // base/id # hint "," http ")' – u0b34a0f6ae

+0

Creo que esta pregunta (o sus respuestas, dependiendo de cómo la mire) [está desactualizada] (http : //stackoverflow.com/a/34902870/476716). – OrangeDog

Respuesta

3

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

me gustaría utilizar los resultados del primer análisis sintáctico, luego sintetizar una URL HTTP y analizar de nuevo:

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

Opino mi propia solución a esta: Tendría que hacer este viaje de ida y vuelta todo el tiempo en mi módulo personalizado de URL. – u0b34a0f6ae

+0

Bastante bien: no me gustaba confiar en las partes internas del módulo, pero los ingenieros razonables pueden diferir! –

1

intente eliminar el esquema completo, y comenzar 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 conoce el esquema de todos modos.

También tenga en cuenta que Python 2.6 parece manejar esta url 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='') 
23

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 añadirá su esquema de URL a las listas:

uses_fragment 
uses_netloc 
uses_params 
uses_query 
uses_relative 

El uri se tratará como http-like y devolverá correctamente el camino, fragmento, nombre de usuario/contraseña, etc.

urlparse.urlparse('moose://username:[email protected]:port/path?query=value#fragment')._asdict() 
=> {'fragment': 'fragment', 'netloc': 'username:[email protected]:port', 'params': '', 'query': 'query=value', 'path': '/path', 'scheme': 'moose'} 
+0

Pero la consulta todavía no se analiza correctamente ... Gracias de todos modos. –

+2

bien, corrigió el ejemplo para incluir también el análisis de cadena de consulta – toothygoose

+0

No se puede votar más de una vez :(¡Gracias! –

3

También hay biblioteca llamada furl que le da resultado deseado:

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

Usted puede utilizar yurl biblioteca. A diferencia de Purl o Furl, no intenta arreglar errores urlparse. Es nuevo compatible con la implementación de RFC 3986.

>>> import yurl 
>>> yurl.URL('qqqq://base/id#hint') 
URLBase(scheme='qqqq', userinfo=u'', host='base', port='', path='/id', query='', fragment='hint') 
2

Parece que la pregunta está 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') 
+0

Quería respaldar esto más, a partir del 26/04/2016, también analiza más allá de los conceptos básicos que se muestran arriba: 'weird_scheme = 'qqq: // username: [email protected]/some/path? params = key # frag_ment''. Luego analiza y muestra username: 'urlparse (weird_scheme) .username # 'username'' o show query: ' urlparse (weird_scheme) .query) # 'params = key'' – knickum