Python: путаница с urljoin

Я пытаюсь сформировать URL-адреса из разных частей, и у меня возникают проблемы с пониманием поведения этого метода. Например:

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') # just a tad / after 'more'
'http://some/more/thing'
urljoin('http://some/more/', '/thing')
'http://some/thing'

Можете ли вы объяснить точное поведение этого метода?

3 ответа

Решение

Лучший способ (для меня) думать об этом - это первый аргумент, base это как страница, на которой вы находитесь в вашем браузере. Второй аргумент url является ссылкой якоря на этой странице. Результатом является окончательный URL-адрес, на который вы будете перенаправлены при нажатии.

>>> urljoin('some', 'thing')
'thing'

Это имеет смысл дать мое описание. Хотя можно надеяться, что база включает в себя схему и домен.

>>> urljoin('http://some', 'thing')
'http://some/thing'

Если вы на какой-то vhost, и есть такой якорь, как <a href='thing'>Foo</a> тогда ссылка приведет вас к http://some/thing

>>> urljoin('http://some/more', 'thing')
'http://some/thing'

Мы на some/more здесь, так что относительная связь thing приведет нас к /some/thing

>>> urljoin('http://some/more/', 'thing') # just a tad / after 'more'
'http://some/more/thing'

Здесь мы не на some/more, мы на some/more/ который отличается Теперь наша относительная ссылка приведет нас к some/more/thing

>>> urljoin('http://some/more/', '/thing')
'http://some/thing'

И наконец. Если на some/more/ и ссылка на /thing, вы будете связаны с some/thing,

urllib.parse.urljoin(база, URL)

Если URL-адрес является абсолютным URL-адресом (т. Е. Начинается с //, http: //, https: //,...), имя и / или схема хоста URL-адреса будут присутствовать в результате. Например:

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

в противном случае urllib.parse.urljoin(база, URL) будет

Создайте полный ("абсолютный") URL, комбинируя "базовый URL" (базовый) с другим URL (URL). Неформально при этом используются компоненты базового URL-адреса, в частности схема адресации, местоположение в сети и (часть) пути, для предоставления отсутствующих компонентов в относительном URL-адресе.

>>> 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'
>>>

он захватывает путь первого параметра (base), удаляет деталь после последнего / и присоединяется ко второму параметру (url).

Если url начинается с /, он соединяет схему и netloc базы с url

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

Одна картинка стоит тысячи слов.

      $ python3
Python 3.11.4 (main, Jun 20 2023, 17:23:00) [Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> 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'

Лучшая практика :

Используйте параметр «base» с косой чертой («/») и не начинайте параметр «url» с косой черты («/»).

Другие вопросы по тегам