Как объединить абсолютные и относительные URL-адреса?


103

У меня два URL-адреса:

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

Как я могу получить абсолютный URL для url2?



Ответы:


216

Вы должны использовать urlparse.urljoin :

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

С Python 3 (где urlparse переименован в urllib.parse ) вы можете использовать его следующим образом :

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

5
Как мы используем urljoinс 3 или параметрами режима или какую библиотеку вы порекомендуете для этого?
Месут Таши

@mesuutt пытается создать цикл и соединить каждую часть с ранее присоединенным URL.
Cédric Julien

2
@ CédricJulien: простой цикл не будет работать, так как любой путь с ведущим /будет "сброшен" и вернет схему + netloc + lasturl:urlparse.urljoin('http://www.a.com/b/c/d', '/e') => 'http://www.a.com/e'
MestreLion

При использовании urljoin возникает проблема. Например, urljoin('http://www.a.com/', '../../b/c.png')результат есть 'http://www.a.com/../../b/c.png', но нет http://www.a.com/b/c.png. Итак, есть ли способ получить http://www.a.com/b/c.png?
bigwind 02

1
Ссылка на документацию Python 3 указывает на документацию Python 2, ее необходимо обновить в ответе, это docs.python.org/3.6/library/…
Harsh

8

Если ваш относительный путь состоит из нескольких частей, вы должны соединить их по отдельности, так urljoinкак относительный путь будет заменен, а не присоединен к нему. Самый простой способ сделать это - использовать 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'

См. Также: Как объединить компоненты пути при создании URL-адреса в Python


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

3
Хороший способ поддержать список ценностей. Вы можете удалить свой побочный эффект (вашу «базовую» переменную), используя сокращение. reduce(lambda a, b: urlparse.urljoin(a, b), es) Карта - list[n] - to -> list[n]это сокращениеlist[n] - to -> a calculated value
Питер Перрон

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

Просто.


3

Для python 3.0+ правильный способ присоединения URL-адресов:

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

1

Вы можете использовать reduceметод Шихара более чистым способом.

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

Обратите внимание, что при использовании этого метода каждый фрагмент должен иметь завершающую косую черту без ведущей косой черты (чтобы указать, что это присоединяемый фрагмент пути). Это более правильно / информативно, говоря вам, что path1/это фрагмент пути URI, а не полный путь /path1/или неизвестный path1, который может быть любым (и обрабатывается как полный путь).

Если вам нужно добавить /фрагмент, которого нет, вы можете сделать:

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

Чтобы узнать больше о разрешении URI, в Википедии есть несколько хороших примеров.

Обновить

Просто замечает, что Питер Перрон прокомментировал сокращение ответа Шихара, но я оставлю это здесь, чтобы продемонстрировать, как это делается.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.