我试图使用os.normpath
将http://example.com/a/b/c/../
转换为http://example.com/a/b/
,但在Windows上它不起作用,因为它会将斜杠转换为反斜杠。
以下是如何操作的步骤:
>>> 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
。
urljoin
和posixpath.normpath
都不能正确地完成工作。 urljoin
强制你连接某些东西,并且无法正确处理绝对路径或过多的..
。 posixpath.normpath
折叠多个斜杠并删除尾部斜杠,这些都是URL不应该做的事情。 .
和 ..
,符合RFC 3986的要求。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)
>>> resolve_url("http://example.com/dir/../../thing/.")
'http://example.com/thing/'
关于解析URL时需要考虑的问题,更多信息请参见我之前在该主题上撰写的类似答案。
从os模块采用“ - os.path是模块posixpath或ntpath之一”,在您的情况下明确使用posixpath。
>>> import posixpath
>>> posixpath.normpath("/a/b/../c")
'/a/c'
>>>
posixpath.normpath
会做一些不太有用的事情,例如删除尾部斜杠并允许双斜杠开头。还会将空路径替换为.
。 - Tom Viner
/
,它将返回ftp://domain.com/../..
。进行修正。 - Josh Lee