urllib.parse — Разбор URL-адреса на компоненты


Данный модуль определяет стандартный интерфейс для разбиения строк унифицированного указателя ресурсов (URL) на компоненты (схема адресации, сетевое расположение, путь и т. д.), чтобы объединить компоненты обратно в строку URL и преобразовать «относительный URL» в абсолютный URL-адрес с «базовым URL-адресом»

Модуль был разработан в соответствии с RFC Интернета по относительным унифицированным указателям ресурсов. Он поддерживает следующие URL схемы: file, ftp, gopher, hdl, http, https, imap, mailto, mms, news, nntp, prospero, rsync, rtsp, rtspu, sftp, shttp, sip, sips, snews, svn, svn+ssh , telnet, wais, ws, wss.

Модуль urllib.parse определяет функции, которые делятся на две большие категории: парсинг URL и закавычивание URL. Они подробно описаны в следующих разделах.

Парсинг URL

Функции парсинга URL-адресов сосредоточены на разделении строки URL-адреса на её компоненты или на объединении компонентов URL-адреса в строку URL-адреса.

urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)

Разбирает URL-адрес на шесть компонентов, вернув именованный кортеж из 6 элементов. Соответствует общей структуре URL-адреса: scheme://netloc/path;parameters?query#fragment. Каждый элемент кортежа представляет собой строку, возможно, пустую. Компоненты не разбиваются на более мелкие части (например, местоположение в сети представляет собой одну строку), и % экранирования не раскрываются. Указанные выше разделители не являются частью результата, за исключением ведущей косой черты в компоненте path, которая сохраняется, если присутствует. Например:

>>> from urllib.parse import urlparse
>>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
>>> o   # doctest: +NORMALIZE_WHITESPACE
ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> o.scheme
'http'
>>> o.port
80
>>> o.geturl()
'http://www.cwi.nl:80/%7Eguido/Python.html'

Следуя спецификациям синтаксиса RFC 1808, urlparse распознает netloc, только если он правильно представлен с помощью «//». В противном случае предполагается, что ввод является относительным URL-адресом и, таким образом, начинается с компонента пути.

>>> from urllib.parse import urlparse
>>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html')
ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> urlparse('www.cwi.nl/%7Eguido/Python.html')
ParseResult(scheme='', netloc='', path='www.cwi.nl/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> urlparse('help/Python.html')
ParseResult(scheme='', netloc='', path='help/Python.html', params='',
            query='', fragment='')

Аргумент scheme дает схему адресации по умолчанию, которая будет использоваться только в том случае, если URL-адрес не указывает её. Он должен быть того же типа (текст или байты), что и urlstring, за исключением того, что всегда разрешено значение по умолчанию '', которое при необходимости автоматически преобразуется в b''.

Если у аргумента allow_fragments значение ложь, идентификаторы фрагментов не распознаются. Вместо этого они анализируются как часть пути, параметров или компонента запроса, а fragment устанавливается на пустую строку в возвращаемом значении.

Возвращаемое значение — именованный кортеж, что означает, что к его элементам можно получить доступ по индексу или как именованным атрибутам, которые следующие:

Атрибут Индекс Значение Значение, если его нет
scheme 0 Спецификатор схемы URL параметр scheme
netloc 1 Часть сетевого расположения пустая строка
path 2 Иерархический путь пустая строка
params 3 Параметры последнего элемента пути пустая строка
query 4 Компонент запроса пустая строка
fragment 5 Идентификатор фрагмента пустая строка
username   Имя пользователя None
password   Пароль None
hostname   Имя хоста (нижний регистр) None
port   Номер порта как целое число, если имеется None

Чтение атрибута port вызовет ValueError, если в URL-адресе указан недопустимый порт. См. раздел Структурированные результаты парсинга для получения дополнительной информации об объекте результата.

Несовпадающие квадратные скобки в атрибуте netloc вызовут ValueError.

Символы в атрибуте netloc, которые разлагаются при нормализации NFKC (как используется кодировкой IDNA) на любой из /, ?, #, @ или :, будут вызывать ValueError. Если URL-адрес разобран перед парсингом, ошибки не возникнет.

Как и в случае со всеми именованными кортежами, у подкласса есть несколько дополнительных методов и атрибутов, которые особенно полезны. Один из таких методов — _replace(). Метод _replace() вернёт новый объект ParseResult, заменив указанные поля новыми значениями.

>>> from urllib.parse import urlparse
>>> u = urlparse('//www.cwi.nl:80/%7Eguido/Python.html')
>>> u
ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> u._replace(scheme='http')
ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')

Изменено в версии 3.2: Добавлены возможности парсинга URL-адресов IPv6.

Изменено в версии 3.3: Теперь фрагмент парсится для всех схем URL (если allow_fragment не является ложным) в соответствии с RFC 3986. Раньше существовал белый список схем, поддерживающих фрагменты.

Изменено в версии 3.6: Номера портов вне допустимого диапазона теперь вызывают ValueError, а не возвращают None.

Изменено в версии 3.8: Символы, которые влияют на парсинг netloc при NFKC нормализации, теперь будут вызывать ValueError.

urllib.parse.parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')

Парсинг строки запроса, заданную как строковый аргумент (данные типа application/x-www-form-urlencoded). Данные возвращаются в виде словаря. Ключи словаря — это уникальные имена переменных запроса, а значения — это списки значений для каждого имени.

Необязательный аргумент keep_blank_values — это флаг, указывающий, следует ли обрабатывать пустые значения в запросах с процентной кодировкой как пустые строки. Истинное значение указывает, что пробелы должны быть оставлены как пустые строки. Значение ложь по умолчанию указывает, что пустые значения должны игнорироваться и обрабатываться так, как если бы они не были включены.

Необязательный аргумент strict_parsing — это флаг, указывающий, что делать с ошибками парсинга. Если ложь (по умолчанию), ошибки игнорируются. Если истина, ошибки вызывают исключение ValueError.

Необязательные параметры encoding и errors указывают, как декодировать последовательности, закодированные в процентах, в символы Юникод, как это принято методом bytes.decode().

Необязательный аргумент max_num_fields — максимальное количество полей для чтения. Если установлено, то выдает ValueError, если прочитано более max_num_fields полей.

Необязательный аргумент separator — это символ, используемый для разделения аргументов запроса. По умолчанию используется &.

Используйте функцию urllib.parse.urlencode() (с параметром doseq, установленным на True) для преобразования таких словарей в строки запроса.

Изменено в версии 3.2: Добавлены параметры encoding и errors.

Изменено в версии 3.8: Добавлен параметр max_num_fields.

Изменено в версии 3.8.8: Добавлен параметр separator со значением по умолчанию &. Версии Python до Python 3.8.8 позволяли использовать как ;, так и & в качестве разделителя параметров запроса. Это было изменено, чтобы разрешить только один ключ-разделитель, с & в качестве разделителя по умолчанию.

urllib.parse.parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')

Разбор строки запроса, заданную как строковый аргумент (данные типа application/x-www-form-urlencoded). Данные возвращаются в виде списка пар имён и значений.

Необязательный аргумент keep_blank_values — это флаг, указывающий, следует ли обрабатывать пустые значения в запросах с процентной кодировкой как пустые строки. Истинное значение указывает, что пробелы должны быть оставлены как пустые строки. Значение ложь по умолчанию указывает, что пустые значения должны игнорироваться и обрабатываться так, как если бы они не были включены.

Необязательный аргумент strict_parsing — это флаг, указывающий, что делать с ошибками парсинга. Если ложь (по умолчанию), ошибки игнорируются. Если истина, ошибки вызывают исключение ValueError.

Необязательные параметры encoding и errors определяют, как декодировать последовательности, закодированные в процентах, в символы Юникод, как это принято методом bytes.decode().

Необязательный аргумент max_num_fields — максимальное количество полей для чтения. Если установлено, то выдает ValueError, если прочитано более max_num_fields полей.

Необязательный аргумент separator — это символ, используемый для разделения аргументов запроса. По умолчанию это &.

Используйте функцию urllib.parse.urlencode() для преобразования таких списков пар в строки запроса.

Изменено в версии 3.2: Добавлены параметры encoding и errors.

Изменено в версии 3.8: Добавлен параметр max_num_fields.

Изменено в версии 3.8.8: Добавлен параметр separator со значением по умолчанию &. Версии Python до Python 3.8.8 позволяли использовать как ;, так и & в качестве разделителя параметров запроса. Это было изменено, чтобы разрешить только один ключ-разделитель, с & в качестве разделителя по умолчанию.

urllib.parse.urlunparse(parts)

Создать URL-адрес из кортежа, возвращенного urlparse(). Аргумент parts может быть любым итеративным из шести элементов. Это может привести к немного другому, но эквивалентному URL-адресу, если URL-адрес, который был проанализирован изначально, имел ненужные разделители (например, ? с пустым запросом; RFC утверждает, что они эквивалентны).

urllib.parse.urlsplit(urlstring, scheme='', allow_fragments=True)

Похожа на urlparse(), но не разделяет параметры из URL-адреса. Обычно её следует использовать вместо urlparse(), если требуется более свежий синтаксис URL, позволяющий применять параметры к каждому сегменту части path URL (см. RFC 2396). Отдельная функция нужна для разделения сегментов пути и параметров. Функция возвращает именованный кортеж из 5 элементов:

(addressing scheme, network location, path, query, fragment identifier).

Возвращаемое значение — именованный кортеж, его элементы могут быть доступны по индексу или как именованные атрибуты:

Атрибут Индекс Значение Значение, если его нет
scheme 0 Спецификатор схемы URL параметр scheme
netloc 1 Часть сетевого расположения пустая строка
path 2 Иерархический путь пустая строка
query 3 Компонент запроса пустая строка
fragment 4 Идентификатор фрагмента пустая строка
username   Имя пользователя None
password   Пароль None
hostname   Имя хоста (нижний регистр) None
port   Номер порта как целое число, если имеется None

Чтение атрибута port вызовет ValueError, если в URL-адресе указан недопустимый порт. См. раздел Структурированные результаты парсинга для получения дополнительной информации об объекте результата.

Несовпадающие квадратные скобки в атрибуте netloc вызовут ValueError.

Символы в атрибуте netloc, которые разбираются при NFKC нормализации (как используется кодировкой IDNA) на любой из /, ?, #, @ или :, будут вызывать ValueError. Если URL-адрес разобран перед парсингом, ошибки не возникнет.

Изменено в версии 3.6: Номера портов вне допустимого диапазона теперь вызывают ValueError, а не возвращают None.

Изменено в версии 3.8: Символы, которые влияют на парсинг netloc при нормализации NFKC, теперь будут вызывать ValueError.

urllib.parse.urlunsplit(parts)

Объединяет элементы кортежа, возвращённые urlsplit(), в полный URL- адрес в виде строки. Аргумент parts может быть любым итеративным из пяти элементов. Это может привести к немного другому, но эквивалентному URL- адресу, если URL-адрес, который был распарсен изначально, содержал ненужные разделители (например, знак ? с пустым запросом; RFC утверждает, что они эквивалентны).

urllib.parse.urljoin(base, url, allow_fragments=True)

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

>>> from urllib.parse import urljoin
>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
'http://www.cwi.nl/%7Eguido/FAQ.html'

У аргумента allow_fragments то же значение и значение по умолчанию, что и для urlparse().

Примечание

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

>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html',
...         '//www.python.org/%7Eguido')
'http://www.python.org/%7Eguido'

Если вы не хотите такого поведения, предварительно обработайте url с помощью urlsplit() и urlunsplit(), удалив возможные части scheme и netloc.

Изменено в версии 3.5: Поведение обновлено в соответствии с семантикой, определённой в RFC 3986.

urllib.parse.urldefrag(url)

Если url содержит идентификатор фрагмента, возвращает изменённую версию url без идентификатора фрагмента и идентификатор фрагмента в виде отдельной строки. Если в url нет идентификатора фрагмента, возвращает url без изменений и пустую строку.

Возвращаемое значение — именованный кортеж, его элементы могут быть доступны по индексу или как именованные атрибуты:

Атрибут Индекс Значение Значение, если его нет
url 0 URL без фрагмента пустая строка
fragment 1 Идентификатор фрагмента пустая строка

См. раздел Структурированные результаты парсинга для получения дополнительной информации об объекте результата.

Изменено в версии 3.2: Результат — это структурированный объект, а не простой кортеж из двух элементов.

urllib.parse.unwrap(url)

Извлечь URL-адрес из обёрнутого URL-адреса (т. е. строки в формате <URL:scheme://host/path>, <scheme://host/path>, URL:scheme://host/path или scheme://host/path). Если url не является обёрнутым URL-адресом, он возвращается без изменений.

Парсинг байтов в кодировке ASCII

Функции парсинга URL-адреса изначально были разработаны для работы только с символьными строками. На практике полезно иметь возможность манипулировать правильно закавыченными и закодированными URL-адресами как последовательностями ASCII байтов. Соответственно, все функции парсинга URL в этом модуле работают с объектами bytes и bytearray в дополнение к объектам str.

Если переданы данные str, результат также будет содержать только данные str. Если переданы данные bytes или bytearray, результат будет содержать только данные bytes.

Попытка смешать данные str с bytes или bytearray в одном вызове функции приведет к возникновению TypeError, а попытка передать значения байтов, отличных от ASCII, вызовет UnicodeDecodeError.

Чтобы упростить преобразование объектов результата между str и bytes, все возвращаемые значения функций парсинга URL предоставляют либо метод encode() (когда результат содержит данные str), либо метод decode() (когда результат содержит данные bytes). Сигнатуры этих методов соответствуют сигнатурам соответствующих методов str и bytes (за исключением того, что кодировка по умолчанию — 'ascii', а не 'utf-8'). Каждый создаёт значение соответствующего типа, которое содержит данные bytes (для методов encode()) или данные str (для методов decode()).

Приложениям, которым необходимо работать с URL-адресами, потенциально неправильно закавыченными, которые могут содержать данные, отличные от ASCII, необходимо будет выполнить собственное декодирование с байтов на символы перед вызовом методов парсинга URL.

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

Изменено в версии 3.2: Функции парсинга URL теперь принимают байтовые последовательности в кодировке ASCII

Структурированные результаты парсинга

Объекты результата из функций urlparse(), urlsplit() и urldefrag() являются подклассами типа tuple. Эти подклассы добавляют атрибуты, перечисленные в документации для этих функций, поддержку кодирования и декодирования, описанную в предыдущем разделе, а также дополнительный метод:

urllib.parse.SplitResult.geturl()

Возвращает повторно объединённую версию исходного URL-адреса в виде строки. Она может отличаться от исходного URL-адреса тем, что схема может быть нормализована к нижнему регистру, а пустые компоненты могут быть отброшены. В частности, будут удалены пустые параметры, запросы и идентификаторы фрагментов.

Для результатов urldefrag() будут удалены только идентификаторы пустых фрагментов. Для результатов urlsplit() и urlparse() все отмеченные изменения будут внесены в URL-адрес, возвращаемый этим методом.

Результат этого метода остается неизменным, если он передается обратно через исходную функцию парсинга:

>>> from urllib.parse import urlsplit
>>> url = 'HTTP://www.Python.org/doc/#'
>>> r1 = urlsplit(url)
>>> r1.geturl()
'http://www.Python.org/doc/'
>>> r2 = urlsplit(r1.geturl())
>>> r2.geturl()
'http://www.Python.org/doc/'

Следующие классы предоставляют реализации структурированных результатов парсинга при работе с объектами str:

class urllib.parse.DefragResult(url, fragment)

Класс для результатов urldefrag(), содержащих данные str. Метод encode() возвращает экземпляр DefragResultBytes.

Добавлено в версии 3.2.

class urllib.parse.ParseResult(scheme, netloc, path, params, query, fragment)

Класс для результатов urlparse(), содержащих данные str. Метод encode() возвращает экземпляр ParseResultBytes.

class urllib.parse.SplitResult(scheme, netloc, path, query, fragment)

Класс для результатов urlsplit(), содержащих данные str. Метод encode() возвращает экземпляр SplitResultBytes.

Следующие классы предоставляют реализации результатов парсинга при работе с объектами bytes или bytearray:

class urllib.parse.DefragResultBytes(url, fragment)

Класс для результатов urldefrag(), содержащих данные bytes. Метод decode() возвращает экземпляр DefragResult.

Добавлено в версии 3.2.

class urllib.parse.ParseResultBytes(scheme, netloc, path, params, query, fragment)

Класс для результатов urlparse(), содержащих данные bytes. Метод decode() возвращает экземпляр ParseResult.

Добавлено в версии 3.2.

class urllib.parse.SplitResultBytes(scheme, netloc, path, query, fragment)

Класс для результатов urlsplit(), содержащих данные bytes. Метод decode() возвращает экземпляр SplitResult.

Добавлено в версии 3.2.

Закавычивание URL

Функции закавычивания URL-адресов сосредоточены на получении данных программой и обеспечении их безопасности для использования в качестве компонентов URL- адресов путём заключения в кавычки специальных символов и соответствующего кодирования текста, отличного от ASCII. Они также поддерживают отмену этих операций для воссоздания исходных данных из содержимого компонента URL-адреса, если задача ещё не охвачена функциями парсинга URL-адреса, указанными выше.

urllib.parse.quote(string, safe='/', encoding=None, errors=None)

Заменяет специальные символы в string с помощью escape-последовательности %xx. Буквы, цифры и символы '_.-~' никогда не закавычиваются. По умолчанию функция предназначена для закавычивания раздела пути URL-адреса. Необязательный параметр safe определяет дополнительные символы ASCII, которые не следует заключать в кавычки, — его значение по умолчанию — '/'.

string может быть str или bytes.

Изменено в версии 3.7: Перемещено с RFC 2396 на RFC 3986 для закавычивания строк URL. «~» теперь включёно в множество незарезервированных символов.

Необязательные параметры encoding и errors определяют, как поступать с символами, отличными от ASCII, как это принято методом str.encode(). encoding по умолчанию 'utf-8'. errors по умолчанию 'strict', что означает, что неподдерживаемые символы вызывают UnicodeEncodeError. encoding и errors не должны предоставляться, если string является bytes, или если вызвано TypeError.

Обратите внимание, что quote(string, safe, encoding, errors) эквивалентна quote_from_bytes(string.encode(encoding, errors), safe).

Пример: quote('/El Niño/') дает '/El%20Ni%C3%B1o/'.

urllib.parse.quote_plus(string, safe='', encoding=None, errors=None)

Подобно quote(), но также заменяет пробелы знаками плюс, как требуется для закавычивания значений HTML-формы при создании строки запроса для перехода в URL-адрес. Знаки плюса в исходной строке экранируются, если они не включены в safe. Он также не имеет safe по умолчанию для '/'.

Пример: quote_plus('/El Niño/') дает '%2FEl+Ni%C3%B1o%2F'.

urllib.parse.quote_from_bytes(bytes, safe='/')

Подобен quote(), но принимает объект bytes, а не str, и не выполняет кодирование строки в байты.

Пример: quote_from_bytes(b'a&\xef') дает 'a%26%EF'.

urllib.parse.unquote(string, encoding='utf-8', errors='replace')

Заменяет escape-последовательности %xx их односимвольными эквивалентами. Необязательные параметры encoding и errors указывают, как декодировать последовательности, закодированные в процентах, в символы Юникода, как это принято методом bytes.decode().

string должен быть str.

encoding по умолчанию 'utf-8'. errors по умолчанию 'replace', что означает, что недопустимые последовательности заменяются символом- заполнителем.

Пример: unquote('/El%20Ni%C3%B1o/') дает '/El Niño/'.

urllib.parse.unquote_plus(string, encoding='utf-8', errors='replace')

Подобно unquote(), но также заменяет знаки плюса пробелами, как требуется для отмены кавычек в значениях HTML-форм.

string должен быть str.

Пример: unquote_plus('/El+Ni%C3%B1o/') дает '/El Niño/'.

urllib.parse.unquote_to_bytes(string)

Заменяет escape-последовательности %xx их однооктетными эквивалентами и возвращает объект bytes.

string может быть str или bytes.

Если это str, неэкранированные символы, отличные от ASCII, в string кодируются в байты UTF-8.

Пример: unquote_to_bytes('a%26%EF') дает b'a&\xef'.

urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors = None, quote_via = quote_plus)

Преобразовать объект сопоставления или последовательность двухэлементных кортежей, которые могут содержать объекты str или bytes, в текстовую строку ASCII с процентной кодировкой. Если результирующая строка должна использоваться как data для операции POST с функцией urlopen(), то её следует закодировать в байтах, иначе это приведёт к TypeError.

Результирующая строка представляет собой серию пар key=value, разделенных символами '&', где как key, так и value заключены в кавычки с использованием функции quote_via. По умолчанию quote_plus() используется для закавычивания значений, что означает, что пробелы заключаются в кавычки как символ '+', а символы «/» кодируются как %2F, что соответствует стандарту для GET запросов (application/x-www-form-urlencoded). Альтернативная функция, которую можно передать как quote_via — это quote(), которая будет кодировать пробелы как %20 и не кодировать символы «/». Для максимального контроля над тем, что указано, используйте quote и укажите значение для safe.

Когда в качестве аргумента query используется последовательность двухэлементных кортежей, первый элемент каждого кортежа является ключом, а второй — значением. Элемент значения сам по себе может быть последовательностью, и в этом случае, если необязательный параметр doseq вычисляется как True, отдельные пары key=value, разделенные '&', генерируются для каждого элемента последовательности значений для ключа. Порядок параметров в закодированной строке будет соответствовать порядку кортежей параметров в последовательности.

Параметры safe, encoding и errors передаются в quote_via (параметры encoding и errors передаются, только если элементом запроса является str).

Чтобы отменить этот процесс кодирования, в этом модуле предусмотрены parse_qs() и parse_qsl() для парсинга строк запроса в структурах данных Python.

Обратитесь к примерам urllib, чтобы узнать, как метод urlencode можно использовать для генерации строки запроса для URL- адреса или данных для POST.

Изменено в версии 3.2: Параметр запроса поддерживает байты и строковые объекты.

Добавлено в версии 3.5: Параметр quote_via.

См.также

RFC 3986 — Универсальные идентификаторы ресурсов
Текущий стандарт (STD66). Любые изменения в модуле urllib.parse должен ему соответствовать. Могли наблюдаться определенные отклонения, которые есть в основном для целей обратной совместимости и для некоторых де-факто требования к парсингу, которые обычно наблюдаются в основных браузерах.
RFC 2732 — Формат буквальных адресов IPv6 в URL-адресах.
Определяет требования к парсингу URL-адресов IPv6.
RFC 2396 — Универсальные идентификаторы ресурсов (URI): общий синтаксис
Документ, определяющий общие синтаксические требования для Универсальных Ресурсных Имён (URN) и Унифицированные Указатели Ресурсов (URL).
RFC 2368 — Схема URL mailto.
Требования к парсингу для схем URL mailto.
RFC 1808 — Относительные унифицированные указатели ресурсов
Запрос комментариев включает правила присоединения к абсолютному и к относительному URL-адресу, включая изрядное количество «аномальных примеров», которые регулируют рассмотрение пограничных случаев.
RFC 1738 — Унифицированные указатели ресурсов (URL)
Определяет формальный синтаксис и семантику абсолютных URL-адресов.