2010-01-25 2 views

답변

9

>>> 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 모듈은 플랫폼에 따라 다르지만 슬래시 만 사용하는 파일 경로의 경우에는 posixpath,normpath을 사용할 수 있습니다.

+0

반대로 : 두 번째 매개 변수에 '/'이 오는 경우'ftp : //domain.com /../ .. '을 반환합니다. 수정. –

2

os 모듈에서 채택 "- os.path는 명시 적으로 posixpath를 사용하여 사용자의 경우 posixpath 또는 ntpath 모듈 중 하나입니다.

>>> import posixpath 
    >>> posixpath.normpath("https://stackoverflow.com/a/b/../c") 
    '/a/c' 
    >>> 
+2

'posixpath.normpath'는 후행 슬래시를 제거하고 두 개의 초기 슬래시를 허용하는 것과 같이 도움이되지 않습니다. 빈 경로를'.'로 대체합니다. –

2

어느 urljoinposixpath.normpath 제대로 일을 할. urljoin은 사용자가 무언가와 조인하도록 강제하며 절대 경로 또는 과도한 ..을 올바르게 처리하지 않습니다. posixpath.normpath은 여러 개의 슬래시를 축소하고 후행 슬래시를 제거합니다. 두 가지 모두 URL이 수행해서는 안되는 작업입니다.


다음 함수 RFC 3986에 따른 올바른 방법으로 S 및 ...들 모두 취급 URL을 완전히 해결한다.

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을 해석 할 때 만들 수있는 고려 사항에 대한 자세한 내용은 a similar answer I wrote earlier on the subject를 참조하십시오.

관련 문제