我的应用程序创建自定义URI(或URL?)来识别对象并解决它们。问题是Python的urlparse模块拒绝解析未知的URL方案,就像解析http一样。
如果我不调整urlparse的uses_ *列表,我会得到这个:
>>> urlparse.urlparse("qqqq://base/id#hint")
('qqqq', '', '//base/id#hint', '', '', '')
>>> urlparse.urlparse("http://base/id#hint")
('http', 'base', '/id', '', '', 'hint')
以下是我的工作,我想知道是否有更好的方法:
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)
为什么没有更好的方法来做到这一点?
答案 0 :(得分:23)
您还可以使用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')
这会将您的网址方案附加到列表中:
uses_fragment
uses_netloc
uses_params
uses_query
uses_relative
然后将uri视为类似http,并将正确返回路径,片段,用户名/密码等。
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'}
答案 1 :(得分:3)
我认为问题是URI在方案之后并不都具有通用格式。例如,mailto:urls的结构与http:urls。
的结构不同我会使用第一个解析的结果,然后合成一个http url并再次解析它:
parts = urlparse.urlparse("qqqq://base/id#hint")
fake_url = "http:" + parts[2]
parts2 = urlparse.urlparse(fake_url)
答案 2 :(得分:3)
还有一个名为furl的库可以为您提供所需的结果:
>>>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'
答案 3 :(得分:2)
这个问题似乎已经过时了。至少Python 2.7没有问题。
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')
答案 4 :(得分:1)
尝试完全删除该方案,并从// netloc开始,即:
>>> SCHEME="qqqq"
>>> url="qqqq://base/id#hint"[len(SCHEME)+1:]
>>> url
'//base/id#hint'
>>> urlparse.urlparse(url)
('', 'base', '/id', '', '', 'hint')
您不会在urlparse结果中使用该方案,但无论如何您都知道该方案。
另请注意,Python 2.6似乎处理这个url就好了(除了片段):
$ python2.6 -c 'import urlparse; print urlparse.urlparse("qqqq://base/id#hint")'
ParseResult(scheme='qqqq', netloc='base', path='/id#hint', params='', query='', fragment='')
答案 5 :(得分:0)
您可以使用yurl库。与purl或furl不同,它不会尝试修复urlparse错误。它与RFC 3986实现兼容。
>>> import yurl
>>> yurl.URL('qqqq://base/id#hint')
URLBase(scheme='qqqq', userinfo=u'', host='base', port='', path='/id', query='', fragment='hint')