5

我尝试使用os.normpath以转换http://example.com/a/b/c/../为,http://example.com/a/b/但它在 Windows 上不起作用,因为它确实将斜杠转换为反斜杠。

4

3 回答 3

8

这是如何做到的

>>> import urlparse
>>> urlparse.urljoin("ftp://domain.com/a/b/c/d/", "../..")
'ftp://domain.com/a/b/'
>>> urlparse.urljoin("ftp://domain.com/a/b/c/d/e.txt", "../..")
'ftp://domain.com/a/b/'    

请记住,urljoin考虑一个路径/目录直到最后一个/- 之后是文件名,如果有的话。

另外,不要/在第二个参数中添加前导,否则不会得到预期的结果。

os.path模块依赖于平台,但对于仅使用斜杠而不是 URL 的文件路径,您可以使用posixpath,normpath.

于 2010-01-25T09:33:59.870 回答
7

既不正确urljoin也不posixpath.normpath正确地完成工作urljoin强迫你加入某些东西,并且不能..正确处理绝对路径或过多的 s。posixpath.normpath折叠多个斜杠并删除尾部斜杠,这两者都是 URL 不应该做的事情。


以下函数根据RFC 3986.以正确的方式完全解析 URL,同时处理s 和s 。..

try:
    # Python 3
    from urllib.parse import urlsplit, urlunsplit
except ImportError:
    # Python 2
    from urlparse import urlsplit, urlunsplit

def resolve_url(url):
    parts = list(urlsplit(url))
    segments = parts[2].split('/')
    segments = [segment + '/' for segment in segments[:-1]] + [segments[-1]]
    resolved = []
    for segment in segments:
        if segment in ('../', '..'):
            if resolved[1:]:
                resolved.pop()
        elif segment not in ('./', '.'):
            resolved.append(segment)
    parts[2] = ''.join(resolved)
    return urlunsplit(parts)

然后,您可以在完整的 URL 上调用它,如下所示。

>>> resolve_url("http://example.com/dir/../../thing/.")
'http://example.com/thing/'

有关解析 URL 时必须考虑的更多信息,请参阅我之前就该主题写的类似答案

于 2016-11-10T21:19:35.097 回答
2

从 os 模块采用“-os.path 是模块 posixpath 或 ntpath”之一,在您的情况下明确使用 posixpath。

   >>> import posixpath
    >>> posixpath.normpath("/a/b/../c")
    '/a/c'
    >>> 
于 2010-01-25T09:37:47.507 回答