Як приєднатись до абсолютних та відносних URL-адрес?


102

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

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

Як я можу отримати абсолютний URL для url2?



Відповіді:


213

Слід використовувати 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
Як ми використовуємо urljoin3 чи параметри режиму або яку бібліотеку ви рекомендуєте для цього?
Mesut Tasci

@mesuutt спробуйте зробити цикл і з'єднайте кожну частину з раніше приєднаною URL-адресою.
Седрик Жульєн

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

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.