> **Источник:** https://python-all.ru/3.15/library/urllib.parse.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# `urllib.parse` – Разбор URL на компоненты

**Исходный код:** [Lib/urllib/parse.py](https://python-all.ru/src/3.15/Lib/urllib/parse.py)

---

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

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

**Особенность реализации CPython:** Включение схемы URL `itms-services` может помешать приложению пройти проверку Apple App Store для macOS и iOS. Обработка схемы `itms-services` всегда удаляется на iOS; на macOS она *может* быть удалена, если CPython был собран с опцией [`--with-app-store-compliance`](https://python-all.ru/3.15/using/configure.html#cmdoption-with-app-store-compliance).

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

Функции этого модуля используют устаревший термин `netloc` (или `net_loc`), который был введён в [**RFC 1808**](https://python-all.ru/3.15/library/urllib.parse.html). Однако этот термин был заменён [**RFC 3986**](https://python-all.ru/3.15/library/urllib.parse.html), который ввёл термин `authority`. Использование `netloc` сохранено для обратной совместимости.

## Разбор URL

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

#### `urllib.parse.urlsplit(urlstring, scheme=None, allow_fragments=True, *, missing_as_none=False)`

Разбирает URL на пять компонентов и возвращает [именованный кортеж](https://python-all.ru/3.15/glossary.html#term-named-tuple) [`SplitResult`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.SplitResult) или [`SplitResultBytes`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.SplitResultBytes). Это соответствует общей структуре URL: `scheme://netloc/path?query#fragment`. Каждый элемент кортежа – строка, возможно пустая, или `None`, если *missing\_as\_none* равен true. Неопределённые компоненты представляются пустой строкой (по умолчанию) или `None`, если *missing\_as\_none* равен true. Разделители, показанные выше, не входят в результат, за исключением начального слэша в компоненте *path*, который сохраняется, если присутствует.

Кроме того, свойство netloc разбивается на следующие дополнительные атрибуты, добавляемые к возвращаемому объекту: username, password, hostname и port.

Процентно-кодированные последовательности не декодируются.

Например:

```pycon
>>> from urllib.parse import urlsplit
>>> urlsplit("scheme://netloc/path?query#fragment")
SplitResult(scheme='scheme', netloc='netloc', path='/path',
            query='query', fragment='fragment')
>>> o = urlsplit("http://docs.python.org:80/3/library/urllib.parse.html?"
...              "highlight=params#url-parsing")
>>> o
SplitResult(scheme='http', netloc='docs.python.org:80',
            path='/3/library/urllib.parse.html',
            query='highlight=params', fragment='url-parsing')
>>> o.scheme
'http'
>>> o.netloc
'docs.python.org:80'
>>> o.hostname
'docs.python.org'
>>> o.port
80
>>> o._replace(fragment="").geturl()
'http://docs.python.org:80/3/library/urllib.parse.html?highlight=params'
>>> urlsplit("http://docs.python.org?")
SplitResult(scheme='http', netloc='docs.python.org', path='',
            query='', fragment='')
>>> urlsplit("http://docs.python.org?", missing_as_none=True)
SplitResult(scheme='http', netloc='docs.python.org', path='',
            query='', fragment=None)
```

Следуя спецификациям синтаксиса в [**RFC 1808**](https://python-all.ru/3.15/library/urllib.parse.html), `urlsplit()` распознает netloc только если он правильно обозначен через ‘//’. В противном случае считается, что входные данные являются относительным URL и, следовательно, начинаются с компонента пути.

```pycon
>>> from urllib.parse import urlsplit
>>> urlsplit('//www.cwi.nl:80/%7Eguido/Python.html')
SplitResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            query='', fragment='')
>>> urlsplit('www.cwi.nl/%7Eguido/Python.html')
SplitResult(scheme='', netloc='', path='www.cwi.nl/%7Eguido/Python.html',
            query='', fragment='')
>>> urlsplit('help/Python.html')
SplitResult(scheme='', netloc='', path='help/Python.html',
            query='', fragment='')
>>> urlsplit('help/Python.html', missing_as_none=True)
SplitResult(scheme=None, netloc=None, path='help/Python.html',
            query=None, fragment=None)
```

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

Если аргумент *allow\_fragments* равен false, идентификаторы фрагментов не распознаются. Вместо этого они разбираются как часть пути или строки запроса, а `fragment` устанавливается в `None` или пустую строку (в зависимости от значения *missing\_as\_none*) в возвращаемом значении.

Возвращаемое значение – это [именованный кортеж](https://python-all.ru/3.15/glossary.html#term-named-tuple), что означает, что к его элементам можно обращаться по индексу или по именованным атрибутам, которые:

| Атрибут | Индекс | Значение | Значение, если отсутствует |
| --- | --- | --- | --- |
| `scheme` | 0 | Спецификатор схемы URL | параметр *scheme* или пустая строка [\[1\]](https://python-all.ru/3.15/library/urllib.parse.html#id5) |
| `netloc` | 1 | Сетевое расположение | `None` или пустая строка [\[1\]](https://python-all.ru/3.15/library/urllib.parse.html#id5) |
| `path` | 2 | Иерархический путь | пустая строка |
| `query` | 3 | Компонент запроса | `None` или пустая строка [\[1\]](https://python-all.ru/3.15/library/urllib.parse.html#id5) |
| `fragment` | 4 | Идентификатор фрагмента | `None` или пустая строка [\[1\]](https://python-all.ru/3.15/library/urllib.parse.html#id5) |
| `username` |  | Имя пользователя | `None` |
| `password` |  | Пароль | `None` |
| `hostname` |  | Имя хоста (в нижнем регистре) | `None` |
| `port` |  | Номер порта как целое число, если указан | `None` |

\[1\]

([1](https://python-all.ru/3.15/library/urllib.parse.html#id1),[2](https://python-all.ru/3.15/library/urllib.parse.html#id2),[3](https://python-all.ru/3.15/library/urllib.parse.html#id3),[4](https://python-all.ru/3.15/library/urllib.parse.html#id4))

В зависимости от значения аргумента *missing\_as\_none*.

Чтение атрибута `port` возбуждает [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError), если в URL указан недопустимый порт. Дополнительную информацию об объекте результата см. в разделе [Результаты структурированного разбора](https://python-all.ru/3.15/library/urllib.parse.html#urlparse-result-object).

Непарные квадратные скобки в атрибуте `netloc` возбуждают [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError).

Символы в атрибуте `netloc`, которые при NFKC-нормализации (используемой в кодировке IDNA) раскладываются в любой из `/`, `?`, `#`, `@` или `:`, возбуждают [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError). Если URL разложен до разбора, ошибка не возникнет.

В соответствии с некоторыми положениями [спецификации WHATWG](https://python-all.ru/3.15/library/urllib.parse.html), которая обновляет [**RFC 3986**](https://python-all.ru/3.15/library/urllib.parse.html), начальные управляющие символы C0 и пробелы удаляются из URL. Символы `\n`, `\r` и табуляции `\t` удаляются из URL на любой позиции.

Как и все именованные кортежи, подкласс имеет несколько дополнительных методов и атрибутов, которые особенно полезны. Один из таких методов – `_replace()`. Метод `_replace()` возвращает новый объект [`SplitResult`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.SplitResult), заменяя указанные поля новыми значениями.

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

> **Предупреждение**
>
> `urlsplit()` не выполняет проверку. Подробнее см. [безопасность разбора URL](https://python-all.ru/3.15/library/urllib.parse.html#url-parsing-security).

Изменено в версии 3.2: Добавлена возможность разбора URL с IPv6.

Изменено в версии 3.3: Фрагмент теперь разбирается для всех схем URL (если *allow\_fragments* не равен false), в соответствии с [**RFC 3986**](https://python-all.ru/3.15/library/urllib.parse.html). Ранее существовал список разрешённых схем, поддерживающих фрагменты.

Изменено в версии 3.6: Номера портов вне диапазона теперь возбуждают [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError) вместо возврата `None`.

Изменено в версии 3.8: Символы, влияющие на разбор netloc при NFKC-нормализации, теперь возбуждают [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError).

Изменено в версии 3.10: Символы ASCII перевода строки и табуляции удаляются из URL.

Изменено в версии 3.12: Начальные управляющие символы C0 и пробелы (по WHATWG) удаляются из URL.

Изменено в версии 3.15: Добавлен параметр *missing\_as\_none*.

#### `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* – это флаг, указывающий, следует ли обрабатывать пустые значения в процентно-кодированных запросах как пустые строки. Значение True означает, что пустые значения должны сохраняться как пустые строки. Значение False по умолчанию означает, что пустые значения игнорируются и считаются отсутствующими.

Необязательный аргумент *strict\_parsing* – это флаг, указывающий, что делать с ошибками разбора. Если False (по умолчанию), ошибки молча игнорируются. Если True, ошибки возбуждают исключение [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError).

Необязательные параметры *encoding* и *errors* определяют, как декодировать процентно-кодированные последовательности в символы Unicode, как это принимается методом [`bytes.decode()`](https://python-all.ru/3.15/library/stdtypes.html#bytes.decode).

Необязательный аргумент *max\_num\_fields* – это максимальное количество полей для чтения. Если он задан, то при чтении более *max\_num\_fields* полей возбуждается [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError).

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

Для преобразования таких словарей в строки запроса используется функция [`urllib.parse.urlencode()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlencode) (с параметром `doseq`, установленным в `True`).

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

Изменено в версии 3.8: Добавлен параметр *max\_num\_fields*.

Изменено в версии 3.10: Добавлен параметр *separator* со значением по умолчанию `&`. В версиях Python до 3.10 допускалось использование как `;`, так и `&` в качестве разделителя параметров запроса. Теперь разрешён только один ключ-разделитель, и по умолчанию используется `&`.

Устарело с версии 3.14: Приём объектов с ложными значениями (например, `0` и `[]`), за исключением пустых строк, байтоподобных объектов и `None`, теперь считается устаревшим.

#### `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* – это флаг, указывающий, следует ли обрабатывать пустые значения в процентно-кодированных запросах как пустые строки. Значение True означает, что пустые значения должны сохраняться как пустые строки. Значение False по умолчанию означает, что пустые значения игнорируются и считаются отсутствующими.

Необязательный аргумент *strict\_parsing* – это флаг, указывающий, что делать с ошибками разбора. Если False (по умолчанию), ошибки молча игнорируются. Если True, ошибки возбуждают исключение [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError).

Необязательные параметры *encoding* и *errors* определяют, как декодировать процентно-кодированные последовательности в символы Unicode, как это принимается методом [`bytes.decode()`](https://python-all.ru/3.15/library/stdtypes.html#bytes.decode).

Необязательный аргумент *max\_num\_fields* – это максимальное количество полей для чтения. Если он задан, то при чтении более *max\_num\_fields* полей возбуждается [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError).

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

Используйте функцию [`urllib.parse.urlencode()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlencode) для преобразования таких списков пар в строки запроса.

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

Изменено в версии 3.8: Добавлен параметр *max\_num\_fields*.

Изменено в версии 3.10: Добавлен параметр *separator* со значением по умолчанию `&`. В версиях Python до 3.10 допускалось использование как `;`, так и `&` в качестве разделителя параметров запроса. Теперь разрешён только один ключ-разделитель, и по умолчанию используется `&`.

#### `urllib.parse.urlunsplit(parts)`

#### `urllib.parse.urlunsplit(parts, *, keep_empty)`

Собирает URL из кортежа, возвращаемого [`urlsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlsplit). Аргумент *parts* может быть любым итерабельным объектом из пяти элементов.

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

Если *keep\_empty* равен true, пустые строки сохраняются в результате (например, `?` для пустого запроса), опускаются только компоненты `None`. Это позволяет восстановить URL, который был разобран с опцией `missing_as_none=True`. По умолчанию *keep\_empty* равен true, если *parts* является результатом вызова [`urlsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlsplit) с `missing_as_none=True`.

Изменено в версии 3.15: Добавлен параметр *keep\_empty*.

#### `urllib.parse.urlparse(urlstring, scheme=None, allow_fragments=True, *, missing_as_none=False)`

Это похоже на [`urlsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlsplit), но дополнительно разделяет компонент *path* на *path* и *params*. Эта функция возвращает [именованный кортеж](https://python-all.ru/3.15/glossary.html#term-named-tuple) из 6 элементов [`ParseResult`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.ParseResult) или [`ParseResultBytes`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.ParseResultBytes). Его элементы те же, что и в результате `urlsplit()`, за исключением того, что *params* вставляется на индекс 3 между *path* и *query*.

Эта функция основана на устаревших [**RFC 1738**](https://python-all.ru/3.15/library/urllib.parse.html) и [**RFC 1808**](https://python-all.ru/3.15/library/urllib.parse.html), в которых *params* указывался как основной компонент URL. В более современном синтаксисе URL параметры могут применяться к каждому сегменту части *path* (см. [**RFC 3986**](https://python-all.ru/3.15/library/urllib.parse.html)). Вместо `urlparse()` обычно следует использовать [`urlsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlsplit). Для разделения сегментов пути и параметров требуется отдельная функция.

#### `urllib.parse.urlunparse(parts)`

#### `urllib.parse.urlunparse(parts, *, keep_empty)`

Объединяет элементы кортежа, возвращаемого [`urlparse()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlparse), в полный URL в виде строки. Аргумент *parts* может быть любым итерабельным объектом из шести элементов.

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

Если *keep\_empty* равен true, пустые строки сохраняются в результате (например, `?` для пустого запроса), опускаются только компоненты `None`. Это позволяет восстановить URL, который был разобран с опцией `missing_as_none=True`. По умолчанию *keep\_empty* равен true, если *parts* является результатом вызова [`urlparse()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlparse) с `missing_as_none=True`.

Изменено в версии 3.15: Добавлен параметр *keep\_empty*.

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

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

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

Аргумент *allow\_fragments* имеет то же значение и значение по умолчанию, что и для [`urlsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlsplit).

> **Примечание**
>
> Если *url* является абсолютным URL (то есть начинается с `//` или `scheme://`), то имя хоста и/или схема из *url* будут присутствовать в результате. Например:
>
> ```pycon
> >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html',
> ...         '//www.python.org/%7Eguido')
> 'http://www.python.org/%7Eguido'
> ```
>
> Если такое поведение нежелательно, предварительно обработайте *url* с помощью [`urlsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlsplit) и [`urlunsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlunsplit), удалив возможные части *scheme* и *netloc*.

> **Предупреждение**
>
> Поскольку абсолютный URL может быть передан в качестве параметра `url`, в целом **небезопасно** использовать `urljoin` с контролируемым злоумышленником `url`. Например, в `urljoin("https://website.com/users/", username)`, если `username` может содержать абсолютный URL, результатом `urljoin` будет этот абсолютный URL.

Изменено в версии 3.5: Поведение обновлено в соответствии с семантикой, определённой в [**RFC 3986**](https://python-all.ru/3.15/library/urllib.parse.html).

#### `urllib.parse.urldefrag(url, *, missing_as_none=False)`

Если *url* содержит идентификатор фрагмента, возвращает изменённую версию *url* без идентификатора фрагмента, а сам идентификатор фрагмента – как отдельную строку. Если идентификатора фрагмента в *url* нет, возвращает *url* без изменений и пустую строку (по умолчанию) или `None`, если *missing\_as\_none* равен true.

Возвращаемое значение – [именованный кортеж](https://python-all.ru/3.15/glossary.html#term-named-tuple), его элементы доступны по индексу или как именованные атрибуты:

| Атрибут | Индекс | Значение | Значение, если отсутствует |
| --- | --- | --- | --- |
| `url` | 0 | URL без фрагмента | пустая строка |
| `fragment` | 1 | Идентификатор фрагмента | `None` или пустая строка [\[3\]](https://python-all.ru/3.15/library/urllib.parse.html#id7) |

\[[3](https://python-all.ru/3.15/library/urllib.parse.html#id6)\]

В зависимости от значения аргумента *missing\_as\_none*.

См. раздел [Структурированные результаты разбора](https://python-all.ru/3.15/library/urllib.parse.html#urlparse-result-object) для получения дополнительной информации об объекте результата.

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

Изменено в версии 3.15: Добавлен параметр *missing\_as\_none*.

#### `urllib.parse.unwrap(url)`

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

## Безопасность разбора URL

API [`urlsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlsplit) и [`urlparse()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlparse) не выполняют **валидацию** входных данных. Они могут не вызывать ошибки на входных данных, которые другие приложения считают недопустимыми. Они также могут успешно обработать некоторые входные данные, которые в других местах не считаются URL. Их цель – практическая функциональность, а не чистота.

Вместо того чтобы вызывать исключение при необычном вводе, они могут вернуть некоторые части компонентов как пустые строки или `None` (в зависимости от значения аргумента *missing\_as\_none*). Или компоненты могут содержать больше, чем, возможно, следовало бы.

Мы рекомендуем пользователям этих API, если значения могут использоваться где-либо с последствиями для безопасности, писать защитный код. Выполните некоторую проверку в своем коде, прежде чем доверять возвращенной составной части. Имеет ли `scheme` смысл? Разумен ли `path`? Нет ли чего-то странного в `hostname`? и т.д.

Что составляет URL – не общепринятое определение. Разные приложения имеют разные потребности и желаемые ограничения. Например, живая [спецификация WHATWG](https://python-all.ru/3.15/library/urllib.parse.html) описывает, что требуется пользовательским веб-клиентам, таким как веб-браузер. В то время как [**RFC 3986**](https://python-all.ru/3.15/library/urllib.parse.html) является более общим. Эти функции включают некоторые аспекты обоих, но не могут считаться совместимыми ни с одним из них. API и существующий пользовательский код с ожиданиями определенного поведения предшествуют обоим стандартам, что заставляет нас быть очень осторожными с изменениями поведения API.

## Разбор ASCII-кодированных байтов

Функции разбора URL изначально были разработаны для работы только с символьными строками. На практике полезно иметь возможность манипулировать правильно экранированными и закодированными URL как последовательностями ASCII байтов. Соответственно, все функции разбора URL в этом модуле работают с объектами [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes) и [`bytearray`](https://python-all.ru/3.15/library/stdtypes.html#bytearray) в дополнение к объектам [`str`](https://python-all.ru/3.15/library/stdtypes.html#str).

Если передаются данные [`str`](https://python-all.ru/3.15/library/stdtypes.html#str), результат также будет содержать только данные `str`. Если передаются данные [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.15/library/stdtypes.html#bytearray), результат будет содержать только данные `bytes`.

Попытка смешать данные [`str`](https://python-all.ru/3.15/library/stdtypes.html#str) с [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.15/library/stdtypes.html#bytearray) в одном вызове функции приведет к возникновению [`TypeError`](https://python-all.ru/3.15/library/exceptions.html#TypeError), а попытка передать не-ASCII байтовые значения вызовет [`UnicodeDecodeError`](https://python-all.ru/3.15/library/exceptions.html#UnicodeDecodeError).

Чтобы упростить преобразование объектов результатов между [`str`](https://python-all.ru/3.15/library/stdtypes.html#str) и [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#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-кодированные последовательности байтов

## Структурированные результаты разбора

Объекты результатов функций [`urlsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlsplit), [`urlparse()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlparse) и [`urldefrag()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urldefrag) являются подклассами типа [`tuple`](https://python-all.ru/3.15/library/stdtypes.html#tuple). Эти подклассы добавляют атрибуты, перечисленные в документации этих функций, поддержку кодирования и декодирования, описанную в предыдущем разделе, а также дополнительный метод:

#### `urllib.parse.SplitResult.geturl()`

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

Для результатов [`urldefrag()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urldefrag) будут удалены только пустые идентификаторы фрагментов. Для результатов [`urlsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlsplit) и [`urlparse()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlparse) все отмеченные изменения будут применены к URL, возвращаемому этим методом.

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

```python
>>> 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/'
>>> r3 = urlsplit(url, missing_as_none=True)
>>> r3.geturl()
'http://www.Python.org/doc/#'
```

Следующие классы предоставляют реализации структурированных результатов разбора при работе с объектами [`str`](https://python-all.ru/3.15/library/stdtypes.html#str):

#### `class urllib.parse.DefragResult(url, fragment)`

Конкретный класс для результатов [`urldefrag()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urldefrag), содержащих данные [`str`](https://python-all.ru/3.15/library/stdtypes.html#str). Метод `encode()` возвращает экземпляр [`DefragResultBytes`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.DefragResultBytes).

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

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

Конкретный класс для результатов [`urlparse()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlparse), содержащих данные [`str`](https://python-all.ru/3.15/library/stdtypes.html#str). Метод `encode()` возвращает экземпляр [`ParseResultBytes`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.ParseResultBytes).

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

Конкретный класс для результатов [`urlsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlsplit), содержащих данные [`str`](https://python-all.ru/3.15/library/stdtypes.html#str). Метод `encode()` возвращает экземпляр [`SplitResultBytes`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.SplitResultBytes).

Следующие классы предоставляют реализации результатов разбора при работе с объектами [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.15/library/stdtypes.html#bytearray):

#### `class urllib.parse.DefragResultBytes(url, fragment)`

Конкретный класс для результатов [`urldefrag()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urldefrag), содержащих данные [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes). Метод `decode()` возвращает экземпляр [`DefragResult`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.DefragResult).

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

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

Конкретный класс для результатов [`urlparse()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlparse), содержащих данные [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes). Метод `decode()` возвращает экземпляр [`ParseResult`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.ParseResult).

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

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

Конкретный класс для результатов [`urlsplit()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.urlsplit), содержащих данные [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes). Метод `decode()` возвращает экземпляр [`SplitResult`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.SplitResult).

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

## Экранирование URL

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

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

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

*string* может быть либо объектом [`str`](https://python-all.ru/3.15/library/stdtypes.html#str), либо объектом [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes).

Изменено в версии 3.7: Перенесено из [**RFC 2396**](https://python-all.ru/3.15/library/urllib.parse.html) в [**RFC 3986**](https://python-all.ru/3.15/library/urllib.parse.html) для экранирования строк URL. Символ "~" теперь включён в набор незарезервированных символов.

Необязательные параметры *encoding* и *errors* задают способ обработки не-ASCII символов, как это принимается методом [`str.encode()`](https://python-all.ru/3.15/library/stdtypes.html#str.encode). Параметр *encoding* по умолчанию равен `'utf-8'`. Параметр *errors* по умолчанию равен `'strict'`, что означает, что неподдерживаемые символы вызывают исключение [`UnicodeEncodeError`](https://python-all.ru/3.15/library/exceptions.html#UnicodeEncodeError). Параметры *encoding* и *errors* не должны передаваться, если *string* является объектом [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes), иначе будет вызвано исключение [`TypeError`](https://python-all.ru/3.15/library/exceptions.html#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()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.quote), но также заменяет пробелы на знаки плюс, что требуется для экранирования значений HTML-форм при формировании строки запроса для URL. Знаки плюс в исходной строке экранируются, если они не включены в *safe*. Кроме того, значение по умолчанию для *safe* не равно `'/'`.

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

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

Как [`quote()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.quote), но принимает объект [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes) вместо [`str`](https://python-all.ru/3.15/library/stdtypes.html#str) и не выполняет кодирование строки в байты.

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

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

Заменяет управляющие последовательности `%xx` на соответствующий одиночный символ. Необязательные параметры *encoding* и *errors* задают способ декодирования процентно-кодированных последовательностей в символы Unicode, как это принимается методом [`bytes.decode()`](https://python-all.ru/3.15/library/stdtypes.html#bytes.decode).

*string* может быть либо объектом [`str`](https://python-all.ru/3.15/library/stdtypes.html#str), либо объектом [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes).

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

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

Изменено в версии 3.9: Параметр *string* теперь поддерживает объекты bytes и str (ранее только str).

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

Как [`unquote()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.unquote), но также заменяет знаки плюс на пробелы, что требуется для восстановления значений HTML-форм.

*string* должен быть строкой [`str`](https://python-all.ru/3.15/library/stdtypes.html#str).

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

#### `urllib.parse.unquote_to_bytes(string)`

Заменяет управляющие последовательности `%xx` на соответствующий одиночный октет и возвращает объект [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes).

*string* может быть либо объектом [`str`](https://python-all.ru/3.15/library/stdtypes.html#str), либо объектом [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes).

Если это строка [`str`](https://python-all.ru/3.15/library/stdtypes.html#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)`

Преобразует объект отображения (mapping) или последовательность кортежей из двух элементов, которые могут содержать объекты [`str`](https://python-all.ru/3.15/library/stdtypes.html#str) или [`bytes`](https://python-all.ru/3.15/library/stdtypes.html#bytes), в процентно-кодированную ASCII-строку. Если результирующая строка должна использоваться как данные *data* для операции POST с функцией [`urlopen()`](https://python-all.ru/3.15/library/urllib.request.html#urllib.request.urlopen), то её следует закодировать в байты; в противном случае это приведёт к ошибке [`TypeError`](https://python-all.ru/3.15/library/exceptions.html#TypeError).

Результирующая строка состоит из последовательности пар `key=value`, разделённых символами `'&'`, при этом и *ключ*, и *значение* экранируются с помощью функции *quote\_via*. По умолчанию для экранирования значений используется [`quote_plus()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.quote_plus), то есть пробелы заменяются на символ `'+'`, а символы '/' кодируются как `%2F`, что соответствует стандарту для GET-запросов (`application/x-www-form-urlencoded`). Альтернативная функция, которую можно передать как *quote\_via* – это [`quote()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.quote), которая кодирует пробелы как `%20` и не кодирует символы '/'. Для максимального контроля над тем, что экранируется, используйте `quote` и задайте значение для *safe*.

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

Параметры *safe*, *encoding* и *errors* передаются в функцию *quote\_via* (параметры *encoding* и *errors* передаются только когда элемент запроса является [`str`](https://python-all.ru/3.15/library/stdtypes.html#str)).

Для обращения этого процесса кодирования в модуле предусмотрены [`parse_qs()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.parse_qs) и [`parse_qsl()`](https://python-all.ru/3.15/library/urllib.parse.html#urllib.parse.parse_qsl), которые преобразуют строки запроса в структуры данных Python.

Обратитесь к [примерам urllib](https://python-all.ru/3.15/library/urllib.request.html#urllib-examples), чтобы узнать, как метод `urllib.parse.urlencode()` может использоваться для формирования строки запроса URL или данных для POST-запроса.

Изменено в версии 3.2: параметр *query* теперь поддерживает объекты bytes и string.

Изменено в версии 3.5: добавлен параметр *quote\_via*.

Устарело с версии 3.14: Приём объектов с ложными значениями (например, `0` и `[]`), за исключением пустых строк, байтоподобных объектов и `None`, теперь считается устаревшим.

> **См. также**
>
> **[WHATWG](https://python-all.ru/3.15/library/urllib.parse.html) – URL Living Standard**
>
> Рабочая группа по стандарту URL, которая определяет URL, домены, IP-адреса, формат application/x-www-form-urlencoded и их API.
>
> **[**RFC 3986**](https://python-all.ru/3.15/library/urllib.parse.html) – Uniform Resource Identifiers**
>
> Это текущий стандарт (STD66). Любые изменения в модуле urllib.parse должны ему соответствовать. Могут наблюдаться некоторые отклонения, которые в основном обусловлены обратной совместимостью и некоторыми фактическими требованиями парсинга, обычно встречающимися в основных браузерах.
>
> **[**RFC 2732**](https://python-all.ru/3.15/library/urllib.parse.html) – Формат литеральных IPv6-адресов в URL.**
>
> В нём описываются требования к парсингу IPv6 URL.
>
> **[**RFC 2396**](https://python-all.ru/3.15/library/urllib.parse.html) – Uniform Resource Identifiers (URI): Generic Syntax**
>
> Документ, описывающий общие синтаксические требования как для Uniform Resource Names (URN), так и для Uniform Resource Locators (URL).
>
> **[**RFC 2368**](https://python-all.ru/3.15/library/urllib.parse.html) – Схема URL mailto.**
>
> Требования к парсингу схем URL mailto.
>
> **[**RFC 1808**](https://python-all.ru/3.15/library/urllib.parse.html) – Relative Uniform Resource Locators**
>
> Этот документ (RFC) включает правила объединения абсолютного и относительного URL, включая значительное количество «Аномальных примеров», которые определяют обработку граничных случаев.
>
> **[**RFC 1738**](https://python-all.ru/3.15/library/urllib.parse.html) – Uniform Resource Locators (URL)**
>
> В нём описывается формальный синтаксис и семантика абсолютных URL.
