2009-09-13 7 views
13

Meine Anwendung erstellt benutzerdefinierte URIs (oder URLs?), Um Objekte zu identifizieren und sie zu lösen. Das Problem ist, dass das URL-Modul von Python es ablehnt, unbekannte URL-Schemata zu analysieren, wie es http analysiert.Benutzerdefinierte URIs mit URL parse (Python) analysieren

Wenn ich nicht urlparse der uses_ * Listen einstellen ich dieses:

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

Hier ist, was ich tue, und ich frage mich, ob es einen besseren Weg, es zu tun:

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) 

Warum gibt es keinen besseren Weg, dies zu tun?

+0

urlparse nimmt auch einen anderen param, ich bin nicht, dass es keinen Unterschied macht. (Beispiel: 'urlparse.urlparse (" qqqq: // base/id # hinweis "," http ")' – u0b34a0f6ae

+0

Ich glaube diese Frage (oder es ist Antworten, je nachdem, wie Sie es betrachten) [ist veraltet] (http (http://stackoverflow.com/a/34902870/476716). – OrangeDog

Antwort

3

Ich denke, das Problem ist, dass URIs nicht alle ein gemeinsames Format nach dem Schema haben. Zum Beispiel sind mailto: urls nicht wie http: urls strukturiert.

würde ich die Ergebnisse des ersten Parse verwenden, dann eine HTTP-URL synthetisieren und sie analysiert wieder:

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

Ich bevorzuge meine eigene Workaround zu diesem, ich würde diese Rundreise die ganze Zeit in meinem benutzerdefinierten URL-Modul tun müssen. – u0b34a0f6ae

+0

Fair genug: Ich mochte nicht verlassen auf Interna des Moduls, aber ich vernünftige Ingenieure können sich unterscheiden! –

1

Versuchen Sie, das Programm vollständig zu entfernen, und beginnt mit // Netloc, das heißt:

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

Sie werden nicht das Schema in der URLparse Ergebnis haben, aber Sie kennen das Schema sowieso.

Beachten Sie auch, dass Python 2.6 scheint diese URL einfach gut (abgesehen von dem Fragment) zu handhaben:

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

Sie können auch einen benutzerdefinierten Handler mit urlparse registrieren:

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

Dies wird anhängen Ihr URL-Schema zu den Listen:

uses_fragment 
uses_netloc 
uses_params 
uses_query 
uses_relative 

Die uri wird dann als http-like behandelt und korrekt liefern den Pfad, ein Fragment, Benutzername/Passwort usw.

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

Aber Abfrage wird noch nicht richtig geparst ... Danke trotzdem. –

+2

ok, behoben das Beispiel auch Abfrage String-Analyse enthalten – toothygoose

+0

Kann nicht mehr als einmal upvote :(Danke! –

3

Es gibt auch Bibliothek namens furl was gibt Ihnen gewünschte Ergebnis:

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

Sie yurl Bibliothek verwenden können. Im Gegensatz zu Purl oder Furl, versuchen Sie nicht, URL-Fehler zu beheben. Es ist neu kompatibel mit RFC 3986 Implementierung.

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

Die Frage scheint veraltet zu sein. Seit mindestens Python 2.7 gibt es keine Probleme.

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

Wollte dies weiter untermauern, ab dem 26.04.2016, analysiert auch die oben genannten Grundlagen: 'weird_scheme = 'qqq: // benutzername: [email protected]/some/path? params = schlüssel # frag_ment'' Dann parsen und zeigen username: 'urlparse (weird_scheme) .username # 'benutzername'' oder show query: ' urlparse (weird_scheme) .query) # 'params = key'' – knickum