2010-01-25 12 views

Trả lời

9

Sau đây là cách để làm điều đó

>>> 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/'  

Hãy nhớ rằng urljoin xem xét một path/thư mục tất cả cho đến khi cuối cùng / - sau này là tên file, nếu có.

Ngoài ra, không thêm hàng đầu / vào tham số thứ hai, nếu không bạn sẽ không nhận được kết quả mong đợi.

os.path mô-đun phụ thuộc vào nền tảng nhưng đối với đường dẫn tệp chỉ sử dụng dấu gạch chéo nhưng không phải URL bạn có thể sử dụng posixpath,normpath.

+0

Ngược lại: Nếu tham số thứ hai có '/' hàng đầu, nó sẽ trả về 'ftp: //domain.com /../ ..'. Sửa chữa. –

2

được sử dụng từ mô-đun os "- os.path là một trong các mô-đun posixpath, hoặc ntpath", trong trường hợp của bạn rõ ràng sử dụng posixpath.

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

'posixpath.normpath' thực hiện những điều vô ích như xóa dấu gạch chéo và cho phép dấu gạch chéo kép ban đầu. Cũng thay thế đường dẫn trống bằng '.'. –

2

Cả urljoin cũng không posixpath.normpath thực hiện công việc đúng. urljoin buộc bạn phải tham gia với một thứ gì đó và không xử lý chính xác đường dẫn tuyệt đối hoặc quá nhiều ... posixpath.normpath thu hẹp nhiều dấu gạch chéo và xóa dấu gạch chéo, cả hai đều là những thứ mà URL không nên thực hiện.


Chức năng sau đây giải quyết URL hoàn toàn, xử lý cả . s và .. s, trong một cách chính xác theo 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) 

Sau đó, bạn có thể gọi nó trên URL hoàn chỉnh như sau.

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

Để biết thêm thông tin về các cân nhắc phải được thực hiện khi giải quyết URL, hãy xem a similar answer I wrote earlier on the subject.

Các vấn đề liên quan