Comment joindre des URL absolues et relatives?

Réponses:

214

Vous devez utiliser urlparse.urljoin :

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

Avec Python 3 (où urlparse est renommé en urllib.parse ), vous pouvez l' utiliser comme suit :

>>> import urllib.parse
>>> urllib.parse.urljoin(url1, url2)
'http://127.0.0.1/test1/test4/test6.xml'
Cédric Julien
la source
5
Comment utilisons-nous urljoinavec 3 paramètres ou mode ou quelle bibliothèque recommandez-vous pour cela?
Mesut Tasci
@mesuutt essaie de faire une boucle et de joindre chaque partie avec l'URL précédemment jointe.
Cédric Julien
2
@ CédricJulien: une simple boucle ne fonctionnera pas, car tout chemin avec un /début sera "réinitialisé" et retournera schéma + netloc + lasturl:urlparse.urljoin('http://www.a.com/b/c/d', '/e') => 'http://www.a.com/e'
MestreLion
Si vous utilisez l'urljoin, il y a un problème. Par exemple urljoin('http://www.a.com/', '../../b/c.png'),, le résultat est 'http://www.a.com/../../b/c.png', mais pas http://www.a.com/b/c.png. Alors, y a-t-il une méthode pour obtenir http://www.a.com/b/c.png?
bigwind
1
Le lien vers la documentation Python 3 pointe vers la documentation Python 2, il doit être mis à jour dans la réponse, il s'agit de docs.python.org/3.6/library
Harsh
8

Si votre chemin relatif se compose de plusieurs parties, vous devez les joindre séparément, car urljoincela remplacerait le chemin relatif, pas le rejoindre. Le moyen le plus simple de le faire est d'utiliser 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'

Voir aussi: Comment joindre les composants d'un chemin lorsque vous construisez une URL en Python

pcv
la source
7
es = ['http://127.0.0.1', 'test1', 'test4', 'test6.xml']
base = ''
map(lambda e: urlparse.urljoin(base, e), es)
Centre commercial Shikhar
la source
3
Bon moyen de soutenir une liste de valeurs. Vous pouvez cependant supprimer votre effet secondaire (votre variable «de base») en utilisant une réduction. reduce(lambda a, b: urlparse.urljoin(a, b), es) Une carte est list[n] - to -> list[n]une réduction estlist[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'

Facile.

Talha Ashraf
la source
3

Pour python 3.0+, la bonne façon de joindre des URL est:

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

Vous pouvez utiliser reducepour réaliser la méthode de Shikhar d'une manière plus propre.

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

Notez qu'avec cette méthode, chaque fragment doit avoir une barre oblique de fin, sans barre oblique de début (pour indiquer qu'il s'agit d'un fragment de chemin joint). Ceci est plus correct / informatif, vous indiquant qu'il path1/s'agit d'un fragment de chemin URI, et non du chemin complet /path1/ou d'un inconnu path1, qui pourrait être l'un ou l'autre (et est traité comme un chemin complet).

Si vous avez besoin d'ajouter /à un fragment qui en manque, vous pouvez faire:

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

Pour en savoir plus sur la résolution d'URI, Wikipédia a quelques bons exemples.

mettre à jour

Remarques juste que Peter Perron a commenté réduire la réponse de Shikhar, mais je laisserai ceci ici pour montrer comment cela se fait.

Ryanjdillon
la source