Bagaimana cara menggabungkan url absolut dan relatif?

Jawaban:

214

Anda harus menggunakan urlparse.urljoin :

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

Dengan Python 3 (di mana urlparse diubah namanya menjadi urllib.parse ) Anda dapat menggunakannya sebagai berikut :

>>> import urllib.parse
>>> urllib.parse.urljoin(url1, url2)
'http://127.0.0.1/test1/test4/test6.xml'
Cédric Julien
sumber
5
Bagaimana kami menggunakan urljoindengan 3 atau parameter mode atau pustaka mana yang Anda rekomendasikan untuk ini?
Mesut Tasci
@mesuutt mencoba membuat loop dan menggabungkan setiap bagian dengan URL yang telah digabungkan sebelumnya.
Cédric Julien
2
@ CédricJulien: loop sederhana tidak akan berfungsi, karena jalur apa pun dengan awalan /akan "mereset" dan mengembalikan skema + netloc + lasturl:urlparse.urljoin('http://www.a.com/b/c/d', '/e') => 'http://www.a.com/e'
MestreLion
Jika menggunakan urljoin, ada masalah. Misalnya, urljoin('http://www.a.com/', '../../b/c.png')hasilnya adalah 'http://www.a.com/../../b/c.png', tetapi tidak http://www.a.com/b/c.png. Jadi, apakah ada metode untuk mendapatkannya http://www.a.com/b/c.png?
bigwind
1
Tautan ke dokumentasi Python 3 mengarah ke dokumentasi Python 2, perlu diperbarui dalam jawaban, itu adalah docs.python.org/3.6/library/…
Harsh
8

Jika jalur relatif Anda terdiri dari beberapa bagian, Anda harus menggabungkannya secara terpisah, karena urljoinakan menggantikan jalur relatif, bukan menggabungkannya. Cara termudah untuk melakukannya adalah dengan menggunakan 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'

Lihat juga: Cara menggabungkan komponen jalur saat Anda membuat URL dengan Python

pcv
sumber
7
es = ['http://127.0.0.1', 'test1', 'test4', 'test6.xml']
base = ''
map(lambda e: urlparse.urljoin(base, e), es)
Shikhar Mall
sumber
3
Cara yang bagus untuk mendukung daftar nilai. Anda dapat menghilangkan efek samping (variabel "dasar" Anda) dengan menggunakan pengurangan. reduce(lambda a, b: urlparse.urljoin(a, b), es) Peta adalah list[n] - to -> list[n]A mengurangi adalahlist[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'

Sederhana.

Talha Ashraf
sumber
3

Untuk python 3.0+, cara yang benar untuk menggabungkan url adalah:

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

Anda dapat menggunakan reducemetode Shikhar dengan cara yang lebih bersih.

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

Perhatikan bahwa dengan metode ini, setiap fragmen harus memiliki garis miring ke depan, tanpa garis miring ke depan (untuk menunjukkan bahwa itu adalah fragmen jalur yang digabungkan). Ini lebih tepat / informatif, memberi tahu Anda bahwa itu path1/adalah fragmen jalur URI, dan bukan jalur lengkap /path1/atau tidak diketahuipath1 , yang bisa jadi (dan diperlakukan sebagai jalur lengkap).

Jika Anda perlu menambahkan /fragmen yang kurang, Anda dapat melakukan:

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

Untuk mempelajari lebih lanjut tentang resolusi URI, Wikipedia memiliki beberapa contoh bagus.

memperbarui

Hanya pemberitahuan Peter Perron berkomentar tentang pengurangan pada jawaban Shikhar, tapi saya akan meninggalkan ini di sini untuk mendemonstrasikan bagaimana hal itu dilakukan.

ryanjdillon.dll
sumber