101 votes

Python: confusions avec urljoin

Je suis en train d'essayer de former des URL à partir de différentes pièces, et j'ai du mal à comprendre le comportement de cette méthode. Par exemple:

Python 3.x

from urllib.parse import urljoin

>>> urljoin('some', 'thing')
'thing'
>>> urljoin('http://some', 'thing')
'http://some/thing'
>>> urljoin('http://some/more', 'thing')
'http://some/thing'
>>> urljoin('http://some/more/', 'thing') # juste un / de plus après 'more'
'http://some/more/thing'
urljoin('http://some/more/', '/thing')
'http://some/thing'

Pouvez-vous expliquer le comportement exact de cette méthode?

125voto

sberry Points 28742

La meilleure façon (pour moi) de penser à cela est que le premier argument, base, est comme la page sur laquelle vous vous trouvez dans votre navigateur. Le deuxième argument url est le href d'une ancre sur cette page. Le résultat est l'URL finale vers laquelle vous serez dirigé si vous cliquez.

>>> urljoin('quelque', 'chose')
'chose'

Cela a du sens étant donné ma description. Bien que l'on espère que la base inclut un schéma et un domaine.

>>> urljoin('http://quelque', 'chose')
'http://quelque/chose'

Si vous êtes sur un vhost "quelque", et qu'il y a une ancre comme [Foo](chose), alors le lien vous mènera à http://quelque/chose

>>> urljoin('http://quelque/encore', 'chose')
'http://quelque/chose'

Ici, nous sommes sur quelque/encore, donc un lien relatif de chose nous mènera à /quelque/chose

>>> urljoin('http://quelque/encore/', 'chose') # juste un peu / après 'encore'
'http://quelque/encore/chose'

Ici, nous ne sommes pas sur quelque/encore, mais sur quelque/encore/ ce qui est différent. Maintenant, notre lien relatif nous mènera à quelque/encore/chose

>>> urljoin('http://quelque/encore/', '/chose')
'http://quelque/chose'

Et enfin. Si vous êtes sur quelque/encore/ et que le href est vers /chose, vous serez lié à quelque/chose.

9voto

Bar Horing Points 524

urllib.parse.urljoin(base, url)

Si l'URL est absolue (c'est-à-dire qu'elle commence par //, http://, https://, ...), le nom d'hôte et/ou le schéma de l'URL seront présents dans le résultat. Par exemple:

urljoin('https://www.google.com', '//www.microsoft.com') 'https://www.microsoft.com'

sinon, urllib.parse.urljoin(base, url) fera

Construire une URL complète ("absolue") en combinant une "URL de base" (base) avec une autre URL (url). Informellement, cela utilise les composants de l'URL de base, en particulier le schéma d'adressage, l'emplacement du réseau et (une partie) du chemin, pour fournir les composants manquants dans l'URL relative.

urlparse('http://a/b/c/d/e') ParseResult(scheme='http', netloc='a', path='/b/c/d/e', params='', query='', fragment='') urljoin('http://a/b/c/d/e', 'f') 'http://a/b/c/d/f' urlparse('http://a/b/c/d/e/') ParseResult(scheme='http', netloc='a', path='/b/c/d/e/', params='', query='', fragment='') urljoin('http://a/b/c/d/e/', 'f') 'http://a/b/c/d/e/f'

il récupère le chemin du premier paramètre (base), enlève la partie après le dernier / et le joint avec le deuxième paramètre (url).

Si l'URL commence par /, il joint le schéma et le netloc de base avec l'URL

>>>urljoin('http://a/b/c/d/e', '/f')
'http://a/f'

3voto

crazygit Points 131

Une image vaut mille mots.

$ python3
Python 3.11.4 (main, 20 juin 2023, 17:23:00) [Clang 14.0.3 (clang-1403.0.22.14.1)] sur darwin
Tapez "help", "copyright", "credits" ou "license" pour plus d'informations.
>>>
>>> from urllib.parse import urljoin
>>> urljoin("http://a/b", "c/d")
'http://a/c/d'
>>> urljoin("http://a/b", "/c/d")
'http://a/c/d'
>>> urljoin("http://a/b/", "c/d")
'http://a/b/c/d'
>>> urljoin("http://a/b/", "/c/d")
'http://a/c/d'

La meilleure pratique est:

Utilisez le paramètre "base" avec un slash final ("/"), et évitez de commencer le paramètre "url" par un slash ("/").

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X