2009-09-13 10 views
13

La mia applicazione crea URI personalizzati (o URL?) Per identificare gli oggetti e risolverli. Il problema è che il modulo urlparse di Python si rifiuta di analizzare schemi URL sconosciuti come se analizzi http.Analizza gli URI personalizzati con urlparse (Python)

Se non regolare di urlparse uses_ * liste ottengo questo:

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

Ecco quello che faccio, e mi chiedo se c'è un modo migliore per farlo:

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) 

Perché non esiste un modo migliore per farlo?

+0

urlparse richiede anche un altro parametro, sto notin che non fa alcuna differenza. (Esempio: 'urlparse.urlparse (" qqqq: // base/id # hint "," http ")' – u0b34a0f6ae

+0

Credo che questa domanda (o le sue risposte, a seconda di come la si guarda) [non è aggiornata] (http : //stackoverflow.com/a/34902870/476716). – OrangeDog

risposta

3

Penso che il problema sia che gli URI non hanno tutti un formato comune dopo lo schema. Ad esempio, mailto: urls non sono strutturati come http: urls.

vorrei utilizzare i risultati del primo parse, poi sintetizzare un URL HTTP e analizzare di nuovo:

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

Perfeziono la mia soluzione alternativa a questo, dovrei fare questo roundtrip tutto il tempo nel mio modulo URL personalizzato. – u0b34a0f6ae

+0

Abbastanza corretto: non mi piace fare affidamento sui componenti interni del modulo, ma i tecnici ragionevoli possono differire! –

1

provare a rimuovere lo schema del tutto, e iniziare con // netloc, vale a dire:

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

Non si avrà lo schema nel risultato urlparse, ma si conosce lo schema comunque.

Si noti inoltre che Python 2.6 sembra gestire questo URL bene (a parte il frammento):

$ python2.6 -c 'import urlparse; print urlparse.urlparse("qqqq://base/id#hint")' 
ParseResult(scheme='qqqq', netloc='base', path='/id#hint', params='', query='', fragment='') 
23

È possibile anche registrare un gestore personalizzato 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') 

Questo aggiungerà il vostro schema URL alle liste:

uses_fragment 
uses_netloc 
uses_params 
uses_query 
uses_relative 

L'URI verrà quindi trattato come http-like e sarà correttamente restituire il percorso, frammento, username/password ecc

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

Ma la query non viene ancora analizzata correttamente ... Grazie comunque. –

+2

ok, corretto l'esempio per includere anche l'analisi stringa parsing – toothygoose

+0

Impossibile aggiornare più di una volta :(Grazie! –

3

C'è anche libreria chiamata furl che ti dà risultato desiderato:

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

È possibile utilizzare yurl biblioteca. A differenza di Purl o Furl, non prova a correggere bug urlparse. È nuovo compatibile con l'implementazione RFC 3986.

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

La domanda sembra non essere aggiornata. Dal momento che almeno Python 2.7 non ci sono problemi.

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

Volevo eseguire il backup ulteriormente, dal 26/04/2016; inoltre analizza oltre le informazioni di base sopra riportate: 'weird_scheme = 'qqq: // username: [email protected]/some/path? params = key # frag_ment''. Quindi analizzare e mostrare username: 'urlparse (weird_scheme) .username # 'username'' o mostra query: ' urlparse (weird_scheme) .query) # 'params = chiave'' – knickum