对不起,这到底是什么?
>>> import urllib.parse
>>> base = 'http://example.com'
>>> urllib.parse.urljoin(base, 'abc:123')
'http://example.com/abc:123'
>>> urllib.parse.urljoin(base, '123:abc')
'123:abc'
>>> urllib.parse.urljoin(base + '/', './123:abc')
'http://example.com/123:abc'
python3.7 文档说:
在版本3.5中进行了更改:更新了行为以匹配RFC 3986中定义的语义。
该RFC的哪一部分实施了这种疯狂行为,以及是否应将其视为错误?
答案 0 :(得分:1)
此行为正确且与其他实现一致,如RFC3986所示:
包含冒号(例如“ this:that”)的路径段不能用作相对路径引用的第一段,因为它会被误认为是方案名称。在这样的段之前必须加上一个点段(例如,“ ./ this:that”),以作为相对路径引用。
已经在另一个post中进行了讨论:
URI路径中允许使用冒号。但是在用冒号写相对URI路径时需要小心,因为这样使用时不允许使用它:
<a href="tag:sample">
在这种情况下,标记将被解释为URI的方案。相反,您需要这样写:
<a href="./tag:sample">
urljoin
的使用函数urljoin
只是将两个参数都视为URL(没有任何假定)。它要求它们的方案相同或第二个方案代表相对URI路径。否则,它仅返回第二个参数(尽管恕我直言,它应该引发错误)。通过查看source of urljoin,您可以更好地理解逻辑。
def urljoin(base, url, allow_fragments=True):
"""Join a base URL and a possibly relative URL to form an absolute
interpretation of the latter."""
...
bscheme, bnetloc, bpath, bparams, bquery, bfragment = \
urlparse(base, '', allow_fragments)
scheme, netloc, path, params, query, fragment = \
urlparse(url, bscheme, allow_fragments)
if scheme != bscheme or scheme not in uses_relative:
return _coerce_result(url)
解析器例程urlparse
的结果如下:
>>> from urllib.parse import urlparse
>>> urlparse('123:abc')
ParseResult(scheme='123', netloc='', path='abc', params='', query='', fragment='')
>>> urlparse('abc:123')
ParseResult(scheme='', netloc='', path='abc:123', params='', query='', fragment='')
>>> urlparse('abc:a123')
ParseResult(scheme='abc', netloc='', path='a123', params='', query='', fragment='')