Làm thế nào để nối các url tuyệt đối và tương đối?


102

Tôi có hai url:

url1 = "http://127.0.0.1/test1/test2/test3/test5.xml"
url2 = "../../test4/test6.xml"

Làm cách nào để có được một url tuyệt đối cho url2?



Câu trả lời:


212

Bạn nên sử dụng urlparse.urljoin :

>>> import urlparse
>>> urlparse.urljoin(url1, url2)
'http://127.0.0.1/test1/test4/test6.xml'

Với Python 3 (nơi urlparse được đổi tên thành urllib.parse ), bạn có thể sử dụng nó như sau:

>>> import urllib.parse
>>> urllib.parse.urljoin(url1, url2)
'http://127.0.0.1/test1/test4/test6.xml'

5
Cách chúng tôi sử dụng urljoinvới các tham số 3 hoặc chế độ hoặc bạn đề xuất thư viện nào cho việc này?
Mesut Tasci

@mesuutt cố gắng tạo một vòng lặp và nối từng phần với URL đã tham gia trước đó.
Cédric Julien

2
@ CédricJulien: một vòng lặp đơn giản sẽ không hoạt động, vì bất kỳ đường dẫn nào có đầu /sẽ "đặt lại" và trả về lược đồ + netloc + lasturl:urlparse.urljoin('http://www.a.com/b/c/d', '/e') => 'http://www.a.com/e'
MestreLion

Nếu sử dụng urljoin, có một vấn đề. Ví dụ, urljoin('http://www.a.com/', '../../b/c.png')kết quả là 'http://www.a.com/../../b/c.png', nhưng không http://www.a.com/b/c.png. Vì vậy, có bất kỳ phương pháp để có được http://www.a.com/b/c.png?
bigwind

1
Liên kết đến tài liệu Python 3 trỏ đến tài liệu Python 2, nó cần được cập nhật trong câu trả lời, đó là docs.python.org/3.6/library/…
Harsh

8

Nếu đường dẫn tương đối của bạn bao gồm nhiều phần, bạn phải nối chúng riêng biệt, vì urljoinsẽ thay thế đường dẫn tương đối chứ không phải nối nó. Cách dễ nhất để làm điều đó là sử dụng posixpath.

>>> import urllib.parse
>>> import posixpath
>>> url1 = "http://127.0.0.1"
>>> url2 = "test1"
>>> url3 = "test2"
>>> url4 = "test3"
>>> url5 = "test5.xml"
>>> url_path = posixpath.join(url2, url3, url4, url5)
>>> urllib.parse.urljoin(url1, url_path)
'http://127.0.0.1/test1/test2/test3/test5.xml'

Xem thêm: Cách nối các thành phần của đường dẫn khi bạn đang xây dựng URL bằng Python


7
es = ['http://127.0.0.1', 'test1', 'test4', 'test6.xml']
base = ''
map(lambda e: urlparse.urljoin(base, e), es)

3
Cách tốt để hỗ trợ một danh sách các giá trị. Bạn có thể loại bỏ tác dụng phụ (biến "cơ sở" của bạn) bằng cách sử dụng giảm mặc dù. reduce(lambda a, b: urlparse.urljoin(a, b), es) Một bản đồ là list[n] - to -> list[n]Một giảm làlist[n] - to -> a calculated value
Peter Perron

4
>>> from urlparse import urljoin
>>> url1 = "http://www.youtube.com/user/khanacademy"
>>> url2 = "/user/khanacademy"
>>> urljoin(url1, url2)
'http://www.youtube.com/user/khanacademy'

Đơn giản.


3

Đối với python 3.0+, cách chính xác để nối các url là:

from urllib.parse import urljoin
urljoin('https://10.66.0.200/', '/api/org')
# output : 'https://10.66.0.200/api/org'

1

Bạn có thể sử dụng reduceđể đạt được phương pháp của Shikhar một cách sạch sẽ hơn.

>>> import urllib.parse
>>> from functools import reduce
>>> reduce(urllib.parse.urljoin, ["http://moc.com/", "path1/", "path2/", "path3/"])
'http://moc.com/path1/path2/path3/'

Lưu ý rằng với phương pháp này, mỗi phân đoạn phải có dấu gạch chéo về phía trước, không có dấu gạch chéo phía trước (để chỉ ra rằng đó là một đoạn đường dẫn đang được nối). Điều này chính xác hơn / nhiều thông tin hơn, cho bạn biết rằng đó path1/là một đoạn đường dẫn URI, không phải là đường dẫn đầy đủ /path1/hoặc không xác định path1, có thể là một trong hai (và được coi là đường dẫn đầy đủ).

Nếu bạn cần thêm /vào một phân đoạn thiếu nó, bạn có thể làm:

uri = uri if uri.endswith("/") else f"{uri}/"

Để tìm hiểu thêm về độ phân giải URI, Wikipedia có một số ví dụ hay.

cập nhật

Chỉ cần nhận thấy Peter Perron đã nhận xét về việc giảm câu trả lời của Shikhar, nhưng tôi sẽ để điều này ở đây sau đó để chứng minh cách điều đó được thực hiện.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.