urllib.request.md
1> **Источник:** https://python-all.ru/3.1/library/urllib.request.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 20.5. `urllib.request` – Расширяемая библиотека для открытия URL89Модуль `urllib.request` определяет функции и классы, которые помогают открывать URL (в основном HTTP) в сложном мире – базовая и дайджест-аутентификация, перенаправления, куки и многое другое.1011Модуль `urllib.request` определяет следующие функции:1213#### `urllib.request.urlopen(url, data=None[, timeout])`1415Открывает URL *url*, который может быть строкой или объектом [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request).1617> **Предупреждение**18>19> HTTPS-запросы не выполняют никакой проверки сертификата сервера.2021Параметр *data* может быть строкой, указывающей дополнительные данные для отправки на сервер, или `None`, если такие данные не нужны. В настоящее время только HTTP-запросы используют *data*; HTTP-запрос будет POST вместо GET, если указан параметр *data*. *data* должен быть буфером в стандартном формате *application/x-www-form-urlencoded*. Функция [`urllib.parse.urlencode()`](https://python-all.ru/3.1/library/urllib.parse.html#urllib.parse.urlencode) принимает отображение или последовательность из двух кортежей и возвращает строку в этом формате.2223Необязательный параметр *timeout* задает таймаут в секундах для блокирующих операций, таких как попытка подключения (если не указан, используется глобальная настройка таймаута по умолчанию). Это на самом деле работает только для HTTP, HTTPS и FTP-соединений.2425Эта функция возвращает объект, похожий на файл, с двумя дополнительными методами из модуля `urllib.response`2627- `geturl()` – возвращает URL полученного ресурса; часто используется для определения, было ли выполнено перенаправление28- `info()` – возвращает метаинформацию страницы, такую как заголовки, в виде экземпляра [`email.message_from_string()`](https://python-all.ru/3.1/library/email.parser.html#email.message_from_string) (см. [Краткий справочник по HTTP-заголовкам](https://python-all.ru/3.1/library/urllib.request.html))2930Возбуждает `URLError` при ошибках.3132Обратите внимание, что может быть возвращён `None`, если ни один обработчик не обрабатывает запрос (хотя установленный по умолчанию глобальный [`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector) использует [`UnknownHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.UnknownHandler), чтобы гарантировать, что этого никогда не произойдёт).3334Кроме того, установленный по умолчанию [`ProxyHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.ProxyHandler) гарантирует, что запросы обрабатываются через прокси, если они настроены.3536Устаревшая функция `urllib.urlopen` из Python 2.6 и более ранних версий была прекращена; [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen) соответствует старой `urllib2.urlopen`. Обработка прокси, которая осуществлялась передачей словарного параметра в `urllib.urlopen`, может быть получена с использованием объектов [`ProxyHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.ProxyHandler).3738#### `urllib.request.install_opener(opener)`3940Устанавливает экземпляр4142[`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector)4344в качестве глобального открывателя по умолчанию. Установка открывателя необходима только в том случае, если требуется, чтобы urlopen использовал именно этот открыватель; в противном случае просто вызывайте4546[`OpenerDirector.open()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector.open)4748вместо4950[`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen)5152. Код не проверяет, является ли объект реальным5354[`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector)5556; подойдет любой класс с подходящим интерфейсом.5758#### `urllib.request.build_opener([handler, ...])`5960Возвращает экземпляр [`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector), который объединяет обработчики в указанном порядке. *обработчики* могут быть как экземплярами [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler), так и подклассами [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler) (в этом случае конструктор должен вызываться без параметров). Экземпляры следующих классов будут размещены перед *обработчиками*, если только *обработчики* не содержат их, их экземпляры или подклассы: [`ProxyHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.ProxyHandler), [`UnknownHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.UnknownHandler), [`HTTPHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPHandler), [`HTTPDefaultErrorHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPDefaultErrorHandler), [`HTTPRedirectHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPRedirectHandler), [`FTPHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.FTPHandler), [`FileHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.FileHandler), `HTTPErrorProcessor`.6162Если установка Python имеет поддержку SSL (т.е. если можно импортировать модуль [`ssl`](https://python-all.ru/3.1/library/ssl.html#module-ssl)), будет также добавлен [`HTTPSHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPSHandler).6364Подкласс [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler) также может изменить свою переменную-член `handler_order`, чтобы изменить свою позицию в списке обработчиков.6566#### `urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)`6768Копирует сетевой объект, заданный URL, в локальный файл, если это необходимо. Если URL указывает на локальный файл или существует валидная кешированная копия объекта, объект не копируется. Возвращает кортеж `(filename, headers)`, где *filename* – это имя локального файла, в котором можно найти объект, а *headers* – то, что вернул метод `info()` объекта, возвращенного [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen) (для удаленного объекта, возможно кешированного). Исключения те же, что и для [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen).6970Второй аргумент, если он задан, указывает, в какой файл копировать данные (если отсутствует, данные будут записаны во временный файл с автоматически сгенерированным именем). Третий аргумент, если он задан, – это функция-обработчик, которая будет вызвана один раз при установке сетевого соединения и затем после каждого прочитанного блока. Функция будет получать три аргумента: количество переданных блоков, размер блока в байтах и общий размер файла. Третий аргумент может быть `-1` на старых FTP-серверах, которые не возвращают размер файла в ответ на запрос получения.7172Если *url* использует идентификатор схемы `http:`, необязательный аргумент *data* может быть передан для указания запроса `POST` (обычно тип запроса – `GET`). Аргумент *data* должен быть в стандартном формате *application/x-www-form-urlencoded*; см. функцию `urlencode()` ниже.7374[`urlretrieve()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlretrieve) вызовет исключение `ContentTooShortError`, если обнаружит, что объём доступных данных меньше ожидаемого (то есть размера, указанного в заголовке *Content-Length*). Это может произойти, например, если загрузка была прервана.7576Заголовок *Content-Length* рассматривается как нижняя граница: если есть больше данных для чтения, [`urlretrieve()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlretrieve) читает больше данных, но если доступно меньше данных, он возбуждает исключение.7778В этом случае загруженные данные всё ещё можно получить, они хранятся в атрибуте `content` экземпляра исключения.7980Если заголовок *Content-Length* не был предоставлен, [`urlretrieve()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlretrieve) не может проверить размер загруженных данных и просто возвращает их. В этом случае остаётся только предположить, что загрузка прошла успешно.8182#### `urllib.request.urlcleanup()`8384Очищает кеш, который мог накопиться при предыдущих вызовах8586[`urlretrieve()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlretrieve)8788.8990#### `urllib.request.pathname2url(path)`9192Преобразует имя пути9394*path*9596из локального синтаксиса в форму, используемую в компоненте пути URL. При этом не создаётся полный URL. Возвращаемое значение уже будет экранировано с помощью функции9798`quote()`99100.101102#### `urllib.request.url2pathname(path)`103104Преобразует компонент пути105106*path*107108из URL с процентным кодированием в локальный синтаксис пути. Эта функция не принимает полный URL. Для декодирования109110*path*111112используется113114`unquote()`115116.117118#### `urllib.request.getproxies()`119120Эта вспомогательная функция возвращает словарь соответствий схемы URL-адресу прокси-сервера. Сначала она сканирует окружение на наличие переменных с именем121122`<scheme>_proxy`123124для всех операционных систем, и если не может их найти, ищет информацию о прокси в System Configuration на Mac OS X и в реестре Windows.125126Предоставляются следующие классы:127128#### `class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False)`129130Этот класс представляет абстракцию URL-запроса.131132*url* должен быть строкой, содержащей корректный URL.133134Параметр *data* может быть строкой, указывающей дополнительные данные для отправки на сервер, или `None`, если такие данные не нужны. В настоящее время только HTTP-запросы используют *data*; HTTP-запрос будет POST вместо GET, если указан параметр *data*. *data* должен быть буфером в стандартном формате *application/x-www-form-urlencoded*. Функция [`urllib.parse.urlencode()`](https://python-all.ru/3.1/library/urllib.parse.html#urllib.parse.urlencode) принимает отображение или последовательность из двух кортежей и возвращает строку в этом формате.135136*headers* должен быть словарём, и будет обрабатываться так, как если бы для каждой пары ключ-значение была вызвана [`add_header()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request.add_header). Это часто используется для «подделки» заголовка `User-Agent`, который браузер использует для самоидентификации – некоторые HTTP-серверы разрешают запросы только от распространённых браузеров, а не от скриптов. Например, Mozilla Firefox может идентифицировать себя как `"Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"`, в то время как строка пользовательского агента по умолчанию для `urllib` – `"Python-urllib/2.6"` (на Python 2.6).137138Последние два аргумента представляют интерес только для корректной обработки сторонних HTTP-куки:139140*origin\_req\_host* должен быть хостом запроса исходной транзакции, как определено в [**RFC 2965**](https://python-all.ru/3.1/library/urllib.request.html). По умолчанию `http.cookiejar.request_host(self)`. Это имя хоста или IP-адрес исходного запроса, инициированного пользователем. Например, если запрос предназначен для изображения в HTML-документе, здесь должен быть хост запроса страницы, содержащей изображение.141142*unverifiable* должен указывать, является ли запрос непроверяемым, как определено в RFC 2965. По умолчанию False. Непроверяемый запрос – это запрос, URL которого пользователь не мог утвердить. Например, если запрос предназначен для изображения в HTML-документе, и у пользователя не было возможности разрешить автоматическую загрузку изображения, это должно быть true.143144#### `class urllib.request.URLopener(proxies=None, **x509)`145146Базовый класс для открытия и чтения URL. Если не требуется поддержка открытия объектов с использованием схем, отличных от `http:`, `ftp:` или `file:`, вероятно, стоит использовать [`FancyURLopener`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.FancyURLopener).147148По умолчанию класс [`URLopener`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.URLopener) отправляет заголовок *User-Agent* со значением `urllib/VVV`, где *VVV* – это номер версии `urllib`. Приложения могут определить свой собственный заголовок *User-Agent*, создав подкласс [`URLopener`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.URLopener) или [`FancyURLopener`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.FancyURLopener) и установив атрибут класса [`version`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.URLopener.version) в соответствующее строковое значение в определении подкласса.149150Необязательный параметр *proxies* должен быть словарём, сопоставляющим имена схем с URL прокси, причём пустой словарь полностью отключает прокси. По умолчанию значение равно `None`; в этом случае будут использованы настройки прокси из окружения, если они присутствуют, как описано в определении [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen) выше.151152Дополнительные именованные параметры, собранные в *x509*, могут использоваться для аутентификации клиента при использовании схемы `https:`. Поддерживаются ключи *key\_file* и *cert\_file* для предоставления SSL-ключа и сертификата; оба необходимы для поддержки аутентификации клиента.153154Объекты [`URLopener`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.URLopener) возбуждают исключение [`IOError`](https://python-all.ru/3.1/library/exceptions.html#IOError), если сервер возвращает код ошибки.155156> #### `open(fullurl, data=None)`157>158> Открывает159>160> *fullurl*161>162> , используя соответствующий протокол. Этот метод настраивает кеш и информацию о прокси, затем вызывает соответствующий метод open с его входными аргументами. Если схема не распознана, вызывается163>164> [`open_unknown()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.URLopener.open_unknown)165>166> . Аргумент167>168> *data*169>170> имеет тот же смысл, что и аргумент171>172> *data*173>174> функции175>176> [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen)177>178> .179>180> #### `open_unknown(fullurl, data=None)`181>182> Переопределяемый интерфейс для открытия неизвестных типов URL.183>184> #### `retrieve(url, filename=None, reporthook=None, data=None)`185>186> Извлекает содержимое *url* и помещает его в *filename*. Возвращаемое значение – это кортеж, состоящий из локального имени файла и либо объекта [`email.message.Message`](https://python-all.ru/3.1/library/email.message.html#email.message.Message), содержащего заголовки ответа (для удаленных URL), либо `None` (для локальных URL). Вызывающий код затем должен открыть и прочитать содержимое *filename*. Если *filename* не указан и URL ссылается на локальный файл, возвращается исходное имя файла. Если URL не локальный и *filename* не указан, имя файла – результат вызова [`tempfile.mktemp()`](https://python-all.ru/3.1/library/tempfile.html#tempfile.mktemp) с суффиксом, соответствующим суффиксу последнего компонента пути входного URL. Если указан *reporthook*, он должен быть функцией, принимающей три числовых параметра. Она будет вызываться после каждого чтения блока данных из сети. *reporthook* игнорируется для локальных URL.187>188> Если *url* использует идентификатор схемы `http:`, необязательный аргумент *data* может быть передан для указания запроса `POST` (обычно тип запроса – `GET`). Аргумент *data* должен быть в стандартном формате *application/x-www-form-urlencoded*; см. функцию `urlencode()` ниже.189>190> #### `version`191>192> Переменная, задающая пользовательский агент объекта opener. Чтобы заставить193>194> `urllib`195>196> сообщать серверам, что он использует определённый пользовательский агент, задайте эту переменную в подклассе как переменную класса или в конструкторе перед вызовом конструктора базового класса.197198#### `class urllib.request.FancyURLopener(...)`199200[`FancyURLopener`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.FancyURLopener) является подклассом [`URLopener`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.URLopener), предоставляющим стандартную обработку следующих кодов ответа HTTP: 301, 302, 303, 307 и 401. Для перечисленных выше кодов 30x заголовок *Location* используется для получения фактического URL. Для кода 401 (требуется аутентификация) выполняется базовая HTTP-аутентификация. Для кодов 30x рекурсия ограничена значением атрибута *maxtries*, по умолчанию равным 10.201202Для всех остальных кодов ответа вызывается метод `http_error_default()`, который можно переопределить в подклассах для соответствующей обработки ошибки.203204> **Примечание**205>206> В соответствии с буквой [**RFC 2616**](https://python-all.ru/3.1/library/urllib.request.html) ответы 301 и 302 на POST-запросы не должны автоматически перенаправляться без подтверждения пользователем. Однако на практике браузеры разрешают автоматическое перенаправление таких ответов, изменяя POST на GET, и `urllib` воспроизводит это поведение.207208Параметры конструктора такие же, как и для [`URLopener`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.URLopener).209210> **Примечание**211>212> При выполнении базовой аутентификации экземпляр [`FancyURLopener`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.FancyURLopener) вызывает свой метод [`prompt_user_passwd()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.FancyURLopener.prompt_user_passwd). Реализация по умолчанию запрашивает у пользователя необходимые сведения на управляющем терминале. При необходимости подкласс может переопределить этот метод, чтобы обеспечить более подходящее поведение.213214Класс [`FancyURLopener`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.FancyURLopener) предоставляет один дополнительный метод, который следует переопределить для обеспечения соответствующего поведения:215216#### `prompt_user_passwd(host, realm)`217218Возвращает информацию, необходимую для аутентификации пользователя на указанном хосте в заданной области безопасности. Возвращаемое значение должно быть кортежем, `(user, password)`, который можно использовать для базовой аутентификации.219220Реализация запрашивает эту информацию на терминале; приложение должно переопределить этот метод, чтобы использовать подходящую модель взаимодействия в локальной среде.221222#### `class urllib.request.OpenerDirector`223224Класс225226[`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector)227228открывает URL-адреса через цепочку обработчиков229230[`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler)231232. Он управляет объединением обработчиков в цепочку и восстановлением после ошибок.233234#### `class urllib.request.BaseHandler`235236Это базовый класс для всех зарегистрированных обработчиков – он отвечает только за простую механику регистрации.237238#### `class urllib.request.HTTPDefaultErrorHandler`239240Класс, который определяет обработчик по умолчанию для HTTP-ответов с ошибками; все ответы преобразуются в исключения241242`HTTPError`243244.245246#### `class urllib.request.HTTPRedirectHandler`247248Класс для обработки перенаправлений.249250#### `class urllib.request.HTTPCookieProcessor(cookiejar=None)`251252Класс для обработки HTTP-куки.253254#### `class urllib.request.ProxyHandler(proxies=None)`255256Направляет запросы через прокси-сервер. Если указан *proxies*, это должен быть словарь, сопоставляющий имена протоколов с URL-адресами прокси. По умолчанию список прокси читается из переменных окружения . Если ни одна из переменных окружения прокси не установлена, в среде Windows параметры прокси берутся из раздела Internet Settings реестра, а в среде Mac OS X информация о прокси получается из платформы System Configuration.257258Чтобы отключить автоматически обнаруженный прокси, передайте пустой словарь.259260#### `class urllib.request.HTTPPasswordMgr`261262Ведёт базу данных соответствий между263264`(realm, uri) -> и (user, password)`265266.267268#### `class urllib.request.HTTPPasswordMgrWithDefaultRealm`269270Ведёт базу данных соответствий между271272`(realm, uri) -> и (user, password)`273274. Область (realm) со значением275276`None`277278считается универсальной – она используется, если не подходит ни одна другая.279280#### `class urllib.request.AbstractBasicAuthHandler(password_mgr=None)`281282Это миксин-класс, который помогает с HTTP-аутентификацией как на удалённом хосте, так и на прокси.283284*password\_mgr*285286, если задан, должен быть совместим с287288[`HTTPPasswordMgr`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPPasswordMgr)289290; информацию об интерфейсе, который должен поддерживаться, см. в разделе291292[*HTTPPasswordMgr Objects*](https://python-all.ru/3.1/library/urllib.request.html#http-password-mgr)293294.295296#### `class urllib.request.HTTPBasicAuthHandler(password_mgr=None)`297298Обрабатывает аутентификацию с удалённым хостом. Если указан,299300*password\_mgr*301302должен быть совместим с303304[`HTTPPasswordMgr`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPPasswordMgr)305306; информацию о том, какой интерфейс должен поддерживаться, см. в разделе307308[*HTTPPasswordMgr Objects*](https://python-all.ru/3.1/library/urllib.request.html#http-password-mgr)309310.311312#### `class urllib.request.ProxyBasicAuthHandler(password_mgr=None)`313314Обрабатывает аутентификацию с прокси.315316*password\_mgr*317318, если задан, должен быть совместим с319320[`HTTPPasswordMgr`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPPasswordMgr)321322; информацию об интерфейсе, который должен поддерживаться, см. в разделе323324[*HTTPPasswordMgr Objects*](https://python-all.ru/3.1/library/urllib.request.html#http-password-mgr)325326.327328#### `class urllib.request.AbstractDigestAuthHandler(password_mgr=None)`329330Это миксин-класс, который помогает с HTTP-аутентификацией как на удалённом хосте, так и на прокси.331332*password\_mgr*333334, если задан, должен быть совместим с335336[`HTTPPasswordMgr`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPPasswordMgr)337338; информацию об интерфейсе, который должен поддерживаться, см. в разделе339340[*HTTPPasswordMgr Objects*](https://python-all.ru/3.1/library/urllib.request.html#http-password-mgr)341342.343344#### `class urllib.request.HTTPDigestAuthHandler(password_mgr=None)`345346Обрабатывает аутентификацию с удалённым хостом. Если указан,347348*password\_mgr*349350должен быть совместим с351352[`HTTPPasswordMgr`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPPasswordMgr)353354; информацию о том, какой интерфейс должен поддерживаться, см. в разделе355356[*HTTPPasswordMgr Objects*](https://python-all.ru/3.1/library/urllib.request.html#http-password-mgr)357358.359360#### `class urllib.request.ProxyDigestAuthHandler(password_mgr=None)`361362Обрабатывает аутентификацию с прокси.363364*password\_mgr*365366, если задан, должен быть совместим с367368[`HTTPPasswordMgr`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPPasswordMgr)369370; информацию об интерфейсе, который должен поддерживаться, см. в разделе371372[*HTTPPasswordMgr Objects*](https://python-all.ru/3.1/library/urllib.request.html#http-password-mgr)373374.375376#### `class urllib.request.HTTPHandler`377378Класс для открытия HTTP-URL.379380#### `class urllib.request.HTTPSHandler`381382Класс для открытия HTTPS-URL.383384#### `class urllib.request.FileHandler`385386Открывает локальные файлы.387388#### `class urllib.request.FTPHandler`389390Открывает FTP-URL.391392#### `class urllib.request.CacheFTPHandler`393394Открывает FTP-URL, сохраняя кеш открытых FTP-соединений для минимизации задержек.395396#### `class urllib.request.UnknownHandler`397398Универсальный класс для обработки неизвестных URL.399400## 20.5.1. Объекты Request401402Следующие методы описывают открытый интерфейс [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request), и все они могут быть переопределены в подклассах. Он также определяет несколько открытых атрибутов, которые могут использоваться клиентами для анализа разобранного запроса.403404#### `Request.full_url`405406Оригинальный URL, переданный конструктору.407408#### `Request.type`409410Схема URI.411412#### `Request.host`413414Авторитетная часть URI, обычно хост, но может также содержать порт, отделённый двоеточием.415416#### `Request.origin_req_host`417418Исходный хост запроса, без порта.419420#### `Request.selector`421422Путь URI. Если423424[`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request)425426использует прокси, то selector будет полным URL, который передаётся прокси.427428#### `Request.data`429430Тело запроса (entity body) или None, если не указано.431432#### `Request.unverifiable`433434логическое значение, указывает, является ли запрос непроверяемым, как определено в RFC 2965.435436#### `Request.add_data(data)`437438Устанавливает данные439440[`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request)441442в443444*data*445446. Это игнорируется всеми обработчиками, кроме HTTP-обработчиков – в них это должна быть строка байтов, и изменит запрос на447448`POST`449450вместо451452`GET`453454.455456#### `Request.get_method()`457458Возвращает строку, указывающую метод HTTP-запроса. Это имеет смысл только для HTTP-запросов, и в настоящее время всегда возвращает459460`'GET'`461462или463464`'POST'`465466.467468#### `Request.has_data()`469470Возвращает, есть ли у экземпляра данные, отличные от471472`None`473474.475476#### `Request.get_data()`477478Возвращает данные экземпляра.479480#### `Request.add_header(key, val)`481482Добавляет ещё один заголовок к запросу. В настоящее время заголовки игнорируются всеми обработчиками, кроме HTTP-обработчиков, где они добавляются в список заголовков, отправляемых серверу. Обратите внимание, что не может быть более одного заголовка с одним и тем же именем, и последующие вызовы перезапишут предыдущие в случае совпадения483484*ключа*485486. В настоящее время это не приводит к потере функциональности HTTP, поскольку все заголовки, имеющие смысл при многократном использовании, имеют (специфичный для заголовка) способ достижения той же функциональности с помощью только одного заголовка.487488#### `Request.add_unredirected_header(key, header)`489490Добавляет заголовок, который не будет добавлен в перенаправленный запрос.491492#### `Request.has_header(header)`493494Возвращает, имеет ли экземпляр указанный заголовок (проверяет как обычные, так и неперенаправленные).495496#### `Request.get_full_url()`497498Возвращает URL, переданный в конструктор.499500#### `Request.get_type()`501502Возвращает тип URL – также известный как схема.503504#### `Request.get_host()`505506Возвращает хост, к которому будет установлено соединение.507508#### `Request.get_selector()`509510Возвращает селектор – часть URL, которая отправляется серверу.511512#### `Request.set_proxy(host, type)`513514Подготавливает запрос, подключаясь к прокси-серверу.515516*host*517518и519520*type*521522заменят соответствующие значения экземпляра, а selector экземпляра будет содержать исходный URL, переданный в конструктор.523524#### `Request.get_origin_req_host()`525526Возвращает хост запроса исходной транзакции, как определено в527528[**RFC 2965**](https://python-all.ru/3.1/library/urllib.request.html)529530. См. документацию к конструктору531532[`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request)533534.535536#### `Request.is_unverifiable()`537538Возвращает, является ли запрос непроверяемым, как определено в RFC 2965. См. документацию к конструктору539540[`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request)541542.543544## 20.5.2. Объекты OpenerDirector545546[`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector) имеет следующие методы:547548#### `OpenerDirector.add_handler(handler)`549550*handler* должен быть экземпляром [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler). Ищутся и добавляются в возможные цепочки следующие методы (обратите внимание, что ошибки HTTP являются особым случаем).551552- `protocol_open()` – сигнал о том, что обработчик умеет открывать URL-адреса *протокол*.553- `http_error_type()` – сигнал о том, что обработчик умеет обрабатывать ошибки HTTP с кодом ошибки HTTP *type*.554- `protocol_error()` – сигнал о том, что обработчик умеет обрабатывать ошибки от протокола *протокол* (кроме `http`).555- `protocol_request()` – сигнал о том, что обработчик умеет предварительно обрабатывать запросы *протокол*.556- `protocol_response()` – сигнал о том, что обработчик умеет выполнять последующую обработку ответов *протокол*.557558#### `OpenerDirector.open(url, data=None[, timeout])`559560Открывает указанный561562*url*563564(может быть объектом запроса или строкой), необязательно передавая указанные565566*data*567568. Аргументы, возвращаемые значения и исключения такие же, как у569570[`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen)571572(которая просто вызывает метод573574[`open()`](https://python-all.ru/3.1/library/functions.html#open)575576у текущего установленного глобального577578[`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector)579580). Необязательный параметр581582*timeout*583584задает тайм-аут в секундах для блокирующих операций, таких как попытка соединения (если не указан, используется глобальный тайм-аут по умолчанию). Тайм-аут работает только для соединений HTTP, HTTPS и FTP).585586#### `OpenerDirector.error(proto, *args)`587588Обрабатывает ошибку указанного протокола. Вызывает зарегистрированные обработчики ошибок для данного протокола с указанными аргументами (которые зависят от протокола). Протокол HTTP является особым случаем, использующим код ответа HTTP для определения конкретного обработчика ошибок; обратитесь к методам `http_error_*()` классов обработчиков.589590Возвращаемые значения и исключения такие же, как у [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen).591592Объекты OpenerDirector открывают URL в три этапа:593594Порядок вызова этих методов в каждом этапе определяется сортировкой экземпляров обработчиков.5955961. У каждого обработчика, имеющего метод с именем вида `protocol_request()`, этот метод вызывается для предварительной обработки запроса.5972. Обработчики с методом, названным как `protocol_open()`, вызываются для обработки запроса. Этот этап завершается, когда обработчик либо возвращает значение, отличное от [`None`](https://python-all.ru/3.1/library/constants.html#None) (т.е. ответ), либо вызывает исключение (обычно `URLError`). Исключения могут распространяться.598599 На самом деле описанный алгоритм сначала применяется к методам с именем `default_open()`. Если все такие методы возвращают [`None`](https://python-all.ru/3.1/library/constants.html#None), алгоритм повторяется для методов с именем вида `protocol_open()`. Если все такие методы возвращают [`None`](https://python-all.ru/3.1/library/constants.html#None), алгоритм повторяется для методов с именем `unknown_open()`.600601 Обратите внимание, что реализация этих методов может включать вызовы методов [`open()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector.open) и [`error()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector.error) родительского экземпляра [`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector).6023. У каждого обработчика, имеющего метод с именем вида `protocol_response()`, этот метод вызывается для последующей обработки ответа.603604## 20.5.3. Объекты BaseHandler605606Объекты [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler) предоставляют несколько методов, которые полезны непосредственно, и другие, предназначенные для использования производными классами. Следующие предназначены для прямого использования:607608#### `BaseHandler.add_parent(director)`609610Добавляет директор в качестве родителя.611612#### `BaseHandler.close()`613614Удаляет всех родителей.615616Следующие атрибуты и методы должны использоваться только классами, производными от [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler).617618> **Примечание**619>620> Принято соглашение: подклассы, определяющие методы `protocol_request()` или `protocol_response()`, называются `*Processor`; все остальные называются `*Handler`.621622#### `BaseHandler.parent`623624Действительный объект625626[`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector)627628, который можно использовать для открытия с помощью другого протокола или для обработки ошибок.629630#### `BaseHandler.default_open(req)`631632Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны определить его, если хотят перехватывать все URL.633634Этот метод, если реализован, будет вызван родительским [`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector). Он должен вернуть объект, похожий на файл, как описано в возвращаемом значении [`open()`](https://python-all.ru/3.1/library/functions.html#open) класса [`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector), или `None`. Он должен вызывать `URLError`, если только не происходит действительно исключительная ситуация (например, [`MemoryError`](https://python-all.ru/3.1/library/exceptions.html#MemoryError) не должно преобразовываться в `URLError`).635636Этот метод будет вызван перед любым методом открытия, специфичным для протокола.637638#### `BaseHandler.protocol_open(req)`639640Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны определить его, если хотят обрабатывать URL с указанным протоколом.641642Этот метод, если он определён, вызывается родительским [`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector). Возвращаемые значения должны быть такими же, как для `default_open()`.643644#### `BaseHandler.unknown_open(req)`645646Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны определить его, если хотят перехватывать все URL, для открытия которых нет зарегистрированного конкретного обработчика.647648Этот метод, если он реализован, вызывается родительским [`родительский`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler.parent) [`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector). Возвращаемые значения должны быть такими же, как и для [`default_open()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler.default_open).649650#### `BaseHandler.http_error_default(req, fp, code, msg, hdrs)`651652Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны переопределить его, если намерены предоставить универсальный обработчик для всех прочих необработанных HTTP-ошибок. Он будет автоматически вызван [`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector) при получении ошибки и обычно не должен вызываться в других обстоятельствах.653654*req* будет объектом [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request), *fp* – файлоподобным объектом с телом HTTP-ошибки, *code* – трёхзначным кодом ошибки, *msg* – понятным пользователю пояснением кода, а *hdrs* – объектом-отображением с заголовками ошибки.655656Возвращаемые значения и возбуждаемые исключения должны быть такими же, как у [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen).657658#### `BaseHandler.http_error_nnn(req, fp, code, msg, hdrs)`659660*nnn* должен быть трёхзначным кодом HTTP-ошибки. Этот метод также не определён в [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler), но будет вызван, если он существует, на экземпляре подкласса при возникновении HTTP-ошибки с кодом *nnn*.661662Подклассы должны переопределить этот метод для обработки конкретных HTTP-ошибок.663664Аргументы, возвращаемые значения и возбуждаемые исключения должны быть такими же, как и для [`http_error_default()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler.http_error_default).665666#### `BaseHandler.protocol_request(req)`667668Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны определить его, если хотят предварительно обрабатывать запросы указанного протокола.669670Этот метод, если он определён, вызывается родительским [`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector). *req* будет объектом [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request). Возвращаемое значение должно быть объектом [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request).671672#### `BaseHandler.protocol_response(req, response)`673674Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны определить его, если хотят выполнять последующую обработку ответов указанного протокола.675676Этот метод, если он определён, вызывается родительским [`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector). *req* будет объектом [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request). *response* будет объектом, реализующим тот же интерфейс, что и возвращаемое значение [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen). Возвращаемое значение должно реализовывать тот же интерфейс, что и возвращаемое значение [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen).677678## 20.5.4. Объекты HTTPRedirectHandler679680> **Примечание**681>682> Некоторые HTTP-перенаправления требуют действий со стороны клиентского кода этого модуля. Если это так, возбуждается `HTTPError`. Подробнее о точном значении различных кодов перенаправления см. [**RFC 2616**](https://python-all.ru/3.1/library/urllib.request.html).683>684> Исключение `HTTPError` возбуждается из соображений безопасности, если HTTPRedirectHandler получает перенаправленный URL, который не является HTTP, HTTPS или FTP URL.685686#### `HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)`687688Возвращает [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request) или `None` в ответ на перенаправление. Вызывается реализациями по умолчанию методов `http_error_30*()` при получении перенаправления от сервера. Если перенаправление должно произойти, возвращается новый [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request), чтобы `http_error_30*()` выполнил перенаправление на *newurl*. В противном случае возбуждается `HTTPError`, если никакой другой обработчик не должен обрабатывать этот URL, или возвращается `None`, если нет возможности обработать, но другой обработчик может.689690> **Примечание**691>692> Реализация этого метода по умолчанию не строго следует [**RFC 2616**](https://python-all.ru/3.1/library/urllib.request.html), в котором сказано, что ответы с кодами 301 и 302 на `POST` запросы не должны автоматически перенаправляться без подтверждения пользователем. На практике браузеры разрешают автоматическое перенаправление этих ответов, заменяя POST на `GET`, и реализация по умолчанию воспроизводит такое поведение.693694#### `HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)`695696Перенаправляет на URL из заголовков697698`Location:`699700или701702`URI:`703704. Этот метод вызывается родительским705706[`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector)707708при получении HTTP-ответа «перемещён навсегда».709710#### `HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)`711712То же, что и713714[`http_error_301()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPRedirectHandler.http_error_301)715716, но вызывается для ответа «found».717718#### `HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)`719720То же, что и721722[`http_error_301()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPRedirectHandler.http_error_301)723724, но вызывается для ответа «see other».725726#### `HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)`727728То же, что и729730[`http_error_301()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPRedirectHandler.http_error_301)731732, но вызывается для ответа «temporary redirect».733734## 20.5.5. Объекты HTTPCookieProcessor735736Экземпляры [`HTTPCookieProcessor`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPCookieProcessor) имеют один атрибут:737738#### `HTTPCookieProcessor.cookiejar`739740Объект741742[`http.cookiejar.CookieJar`](https://python-all.ru/3.1/library/http.cookiejar.html#http.cookiejar.CookieJar)743744, в котором хранятся куки.745746## 20.5.6. Объекты ProxyHandler747748#### `ProxyHandler.protocol_open(request)`749750Для каждого751752*протокола*753754, для которого в словаре755756*proxies*757758, переданном в конструктор, указан прокси, объект759760[`ProxyHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.ProxyHandler)761762будет иметь метод763764`protocol_open()`765766. Этот метод изменяет запрос для направления через прокси, вызывая767768`request.set_proxy()`769770, и передаёт управление следующему обработчику в цепочке для фактического выполнения протокола.771772## 20.5.7. Объекты HTTPPasswordMgr773774Эти методы доступны для объектов [`HTTPPasswordMgr`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPPasswordMgr) и [`HTTPPasswordMgrWithDefaultRealm`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPPasswordMgrWithDefaultRealm).775776#### `HTTPPasswordMgr.add_password(realm, uri, user, passwd)`777778*uri*779780может быть как одним URI, так и последовательностью URI.781782*realm*783784,785786*user*787788и789790*passwd*791792должны быть строками. В результате793794`(user, passwd)`795796будет использоваться в качестве токенов аутентификации при запросе аутентификации для797798*realm*799800и супер-URI любого из указанных URI.801802#### `HTTPPasswordMgr.find_user_password(realm, authuri)`803804Возвращает пару пользователь/пароль для указанных realm и URI, если они есть. Если совпадений нет, этот метод вернёт `(None, None)`.805806Для объектов [`HTTPPasswordMgrWithDefaultRealm`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPPasswordMgrWithDefaultRealm), если для указанного *realm* нет подходящей пары пользователь/пароль, будет выполнен поиск по realm `None`.807808## 20.5.8. Объекты AbstractBasicAuthHandler809810#### `AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)`811812Обрабатывает запрос аутентификации, получая пару пользователь/пароль и повторяя запрос. *authreq* должно быть именем заголовка, в котором содержится информация о realm, *host* указывает URL и путь для аутентификации, *req* должен быть (неудачным) объектом [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request), а *headers* – заголовками ошибки.813814*host* – это либо полномочное имя (например, `"python.org"`), либо URL, содержащий компонент полномочного имени (например, `"http://python.org/"`). В любом случае полномочное имя не должно содержать компонента userinfo (так что `"python.org"` и `"python.org:80"` допустимы, а `"joe:password@python.org"` – нет).815816## 20.5.9. Объекты HTTPBasicAuthHandler817818#### `HTTPBasicAuthHandler.http_error_401(req, fp, code, msg, hdrs)`819820Повторяет запрос с информацией аутентификации, если она доступна.821822## 20.5.10. Объекты ProxyBasicAuthHandler823824#### `ProxyBasicAuthHandler.http_error_407(req, fp, code, msg, hdrs)`825826Повторяет запрос с информацией аутентификации, если она доступна.827828## 20.5.11. Объекты AbstractDigestAuthHandler829830#### `AbstractDigestAuthHandler.http_error_auth_reqed(authreq, host, req, headers)`831832*authreq*833834должно быть именем заголовка, в котором содержится информация о realm,835836*host*837838должен быть хостом для аутентификации,839840*req*841842должен быть (неудачным) объектом843844[`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request)845846, а847848*headers*849850– заголовками ошибки.851852## 20.5.12. Объекты HTTPDigestAuthHandler853854#### `HTTPDigestAuthHandler.http_error_401(req, fp, code, msg, hdrs)`855856Повторяет запрос с информацией аутентификации, если она доступна.857858## 20.5.13. Объекты ProxyDigestAuthHandler859860#### `ProxyDigestAuthHandler.http_error_407(req, fp, code, msg, hdrs)`861862Повторяет запрос с информацией аутентификации, если она доступна.863864## 20.5.14. Объекты HTTPHandler865866#### `HTTPHandler.http_open(req)`867868Отправляет HTTP-запрос, который может быть GET или POST, в зависимости от869870`req.has_data()`871872.873874## 20.5.15. Объекты HTTPSHandler875876#### `HTTPSHandler.https_open(req)`877878Отправляет HTTPS-запрос, который может быть GET или POST, в зависимости от879880`req.has_data()`881882.883884## 20.5.16. Объекты FileHandler885886#### `FileHandler.file_open(req)`887888Открывает файл локально, если имя хоста отсутствует или равно889890`'localhost'`891892. В противном случае меняет протокол на893894`ftp`895896и повторяет попытку открытия с помощью897898`parent`899900.901902## 20.5.17. Объекты FTPHandler903904#### `FTPHandler.ftp_open(req)`905906Открывает FTP-файл, указанный907908*req*909910. Вход всегда выполняется с пустыми именем пользователя и паролем.911912## 20.5.18. Объекты CacheFTPHandler913914Объекты [`CacheFTPHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.CacheFTPHandler) являются объектами [`FTPHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.FTPHandler) с дополнительными методами:915916#### `CacheFTPHandler.setTimeout(t)`917918Устанавливает тайм-аут соединений равным919920*t*921922секунд.923924#### `CacheFTPHandler.setMaxConns(m)`925926Устанавливает максимальное количество кэшированных соединений равным927928*m*929930.931932## 20.5.19. Объекты UnknownHandler933934#### `UnknownHandler.unknown_open()`935936Возбуждает исключение937938`URLError`939940.941942## 20.5.20. Объекты HTTPErrorProcessor943944#### `HTTPErrorProcessor.unknown_open()`945946Обрабатывает ошибочные HTTP-ответы.947948Для кода 200 объект ответа возвращается немедленно.949950Для кодов ошибок, отличных от 200, этот метод просто передает задачу методам-обработчикам `protocol_error_code()` через [`OpenerDirector.error()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector.error). В конечном итоге [`HTTPDefaultErrorHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.HTTPDefaultErrorHandler) возбудит `HTTPError`, если ни один другой обработчик не обработает ошибку.951952## 20.5.21. Примеры953954Этот пример получает главную страницу python.org и отображает первые 300 байт этой страницы.955956```python957>>> import urllib.request958>>> f = urllib.request.urlopen('http://www.python.org/')959>>> print(f.read(300))960b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"961"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html962xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\n<head>\n963<meta http-equiv="content-type" content="text/html; charset=utf-8" />\n964<title>Python Programming '965```966967Обратите внимание, что urlopen возвращает объект bytes. Это связано с тем, что urlopen не может автоматически определить кодировку байтового потока, получаемого от HTTP-сервера. В общем случае программа декодирует возвращаемый объект bytes в строку после того, как определит или угадает подходящую кодировку.968969В следующем документе W3C, [http://www.w3.org/International/O-charset](https://python-all.ru/3.1/library/urllib.request.html), перечислены различные способы, которыми (X)HTML- или XML-документ мог указать информацию о своей кодировке.970971Поскольку сайт python.org использует кодировку *utf-8*, как указано в его мета-теге, мы будем использовать её же для декодирования объекта bytes.972973```python974>>> import urllib.request975>>> f = urllib.request.urlopen('http://www.python.org/')976>>> print(f.read(100).decode('utf-8'))977<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"978"http://www.w3.org/TR/xhtml1/DTD/xhtm979```980981В следующем примере мы отправляем поток данных на стандартный ввод CGI и читаем данные, которые он возвращает. Обратите внимание: этот пример будет работать только в том случае, если установка Python поддерживает SSL.982983```python984>>> import urllib.request985>>> req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi',986... data='This data is passed to stdin of the CGI')987>>> f = urllib.request.urlopen(req)988>>> print(f.read().decode('utf-8'))989Got Data: "This data is passed to stdin of the CGI"990```991992Код образца CGI, использованного в приведённом выше примере:993994```python995#!/usr/bin/env python996import sys997data = sys.stdin.read()998print('Content-type: text-plain\n\nGot Data: "%s"' % data)999```10001001Использование базовой HTTP-аутентификации:10021003```python1004import urllib.request1005# Создать OpenerDirector с поддержкой базовой HTTP-аутентификации...1006auth_handler = urllib.request.HTTPBasicAuthHandler()1007auth_handler.add_password(realm='PDQ Application',1008 uri='https://mahler:8092/site-updates.py',1009 user='klem',1010 passwd='kadidd!ehopper')1011opener = urllib.request.build_opener(auth_handler)1012# ...и установить его глобально, чтобы его можно было использовать с urlopen.1013urllib.request.install_opener(opener)1014urllib.request.urlopen('http://www.example.com/login.html')1015```10161017[`build_opener()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.build_opener) по умолчанию предоставляет множество обработчиков, включая [`ProxyHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.ProxyHandler). По умолчанию [`ProxyHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.ProxyHandler) использует переменные окружения с именами вида `<scheme>_proxy`, где `<scheme>` – это схема URL. Например, переменная окружения **http\_proxy** считывается для получения URL HTTP-прокси.10181019В этом примере стандартный [`ProxyHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.ProxyHandler) заменяется на тот, который использует программно задаваемые URL прокси, и добавляется поддержка авторизации прокси с помощью [`ProxyBasicAuthHandler`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.ProxyBasicAuthHandler).10201021```python1022proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})1023proxy_auth_handler = urllib.request.ProxyBasicAuthHandler()1024proxy_auth_handler.add_password('realm', 'host', 'username', 'password')10251026opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler)1027# На этот раз, вместо установки OpenerDirector, используется напрямую:1028opener.open('http://www.example.com/login.html')1029```10301031Добавление HTTP-заголовков:10321033Используйте аргумент *headers* конструктора [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request) или:10341035```python1036import urllib.request1037req = urllib.request.Request('http://www.example.com/')1038req.add_header('Referer', 'http://www.python.org/')1039r = urllib.request.urlopen(req)1040```10411042[`OpenerDirector`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector) автоматически добавляет заголовок *User-Agent* к каждому [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request). Чтобы изменить это:10431044```python1045import urllib.request1046opener = urllib.request.build_opener()1047opener.addheaders = [('User-agent', 'Mozilla/5.0')]1048opener.open('http://www.example.com/')1049```10501051Также помните, что несколько стандартных заголовков (*Content-Length*, *Content-Type* и *Host*) добавляются, когда [`Request`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.Request) передаётся в [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen) (или [`OpenerDirector.open()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.OpenerDirector.open)).10521053Ниже приведён пример сеанса, в котором используется метод `GET` для получения URL, содержащего параметры:10541055```python1056>>> import urllib.request1057>>> import urllib.parse1058>>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})1059>>> f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)1060>>> print(f.read().decode('utf-8'))1061```10621063В следующем примере вместо этого используется метод `POST`:10641065```python1066>>> import urllib.request1067>>> import urllib.parse1068>>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})1069>>> f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query", params)1070>>> print(f.read().decode('utf-8'))1071```10721073В следующем примере используется явно указанный HTTP-прокси, переопределяющий настройки окружения:10741075```python1076>>> import urllib.request1077>>> proxies = {'http': 'http://proxy.example.com:8080/'}1078>>> opener = urllib.request.FancyURLopener(proxies)1079>>> f = opener.open("http://www.python.org")1080>>> f.read().decode('utf-8')1081```10821083В следующем примере прокси не используются вовсе, переопределяя настройки окружения:10841085```python1086>>> import urllib.request1087>>> opener = urllib.request.FancyURLopener({})1088>>> f = opener.open("http://www.python.org/")1089>>> f.read().decode('utf-8')1090```10911092## 20.5.22. `urllib.request` Ограничения10931094>10951096- В настоящее время поддерживаются только следующие протоколы: HTTP (версии 0.9 и 1.0), FTP и локальные файлы.1097- Возможность кэширования [`urlretrieve()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlretrieve) отключена, пока не найдётся время на реализацию корректной обработки заголовков срока действия.1098- Должна быть функция для проверки, находится ли определённый URL в кэше.1099- Для обратной совместимости, если URL указывает на локальный файл, но файл не удаётся открыть, URL интерпретируется заново с использованием протокола FTP. Это иногда может приводить к запутанным сообщениям об ошибках.1100- Функции [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen) и [`urlretrieve()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlretrieve) могут вызывать сколь угодно долгие задержки при ожидании установки сетевого соединения. Это означает, что создать интерактивный веб-клиент с помощью этих функций без использования потоков сложно.1101- Данные, возвращаемые [`urlopen()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlopen) или [`urlretrieve()`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.urlretrieve), представляют собой необработанные данные, возвращаемые сервером. Это могут быть бинарные данные (например, изображение), обычный текст или, скажем, HTML. Протокол HTTP предоставляет информацию о типе в заголовке ответа, которую можно узнать, посмотрев на заголовок *Content-Type*. Если возвращаемые данные являются HTML, можно использовать модуль [`html.parser`](https://python-all.ru/3.1/library/html.parser.html#module-html.parser) для его разбора.1102- Код, работающий с протоколом FTP, не может различить файл и каталог. Это может привести к неожиданному поведению при попытке чтения URL, указывающего на недоступный файл. Если URL заканчивается на `/`, считается, что он ссылается на каталог, и обработка будет соответствующей. Но если попытка чтения файла приводит к ошибке 550 (означающей, что URL не найден или недоступен, часто по причинам прав доступа), то путь обрабатывается как каталог, чтобы учесть случай, когда в URL указан каталог, но завершающий `/` опущен. Это может привести к вводящим в заблуждение результатам при попытке получить файл, права на чтение которого делают его недоступным; код FTP попытается его прочитать, получит ошибку 550, а затем выполнит листинг каталога для недоступного файла. Если требуется тонкий контроль, рассмотрите возможность использования модуля [`ftplib`](https://python-all.ru/3.1/library/ftplib.html#module-ftplib), создания подкласса [`FancyURLopener`](https://python-all.ru/3.1/library/urllib.request.html#urllib.request.FancyURLopener) или изменения *\_urlopener* в соответствии с вашими потребностями.11031104# 20.6. `urllib.response` – Классы ответов, используемые в urllib11051106Модуль `urllib.response` определяет функции и классы, реализующие минимальный файлоподобный интерфейс, включая `read()` и `readline()`. Типичный объект ответа – это экземпляр addinfourl, который определяет метод `info()`, возвращающий заголовки, и метод `geturl()`, возвращающий URL. Функции, определённые в этом модуле, используются внутри модуля `urllib.request`.1107