urllib.request.md
1> **Источник:** https://python-all.ru/3.3/library/urllib.request.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 21.6. [`urllib.request`](https://python-all.ru/3.3/library/urllib.request.html#module-urllib.request) – расширяемая библиотека для открытия URL89Модуль [`urllib.request`](https://python-all.ru/3.3/library/urllib.request.html#module-urllib.request) определяет функции и классы, которые помогают открывать URL (в основном HTTP) в сложном мире – базовая и дайджест-аутентификация, перенаправления, куки и многое другое.1011Модуль [`urllib.request`](https://python-all.ru/3.3/library/urllib.request.html#module-urllib.request) определяет следующие функции:1213#### `urllib.request.urlopen(url, data=None[, timeout], *, cafile=None, capath=None, cadefault=False)`1415Открывает URL *url*, который может быть строкой или объектом [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request).1617*data* должен быть объектом bytes, задающим дополнительные данные для отправки на сервер, или `None`, если такие данные не нужны. *data* также может быть итерируемым объектом, и в этом случае значение Content-Length должно быть указано в заголовках. В настоящее время только HTTP-запросы используют *data*; HTTP-запрос будет POST вместо GET, когда указан параметр *data*.1819*data* должен быть буфером в стандартном *application/x-www-form-urlencoded* формате. Функция [`urllib.parse.urlencode()`](https://python-all.ru/3.3/library/urllib.parse.html#urllib.parse.urlencode) принимает отображение или последовательность кортежей из двух элементов и возвращает строку в этом формате. Перед использованием в качестве параметра *data* её следует закодировать в байты. Параметр charset в заголовке `Content-Type` может использоваться для указания кодировки. Если параметр charset не передан с заголовком Content-Type, сервер, следуя рекомендации HTTP 1.1, может предположить, что данные закодированы в ISO-8859-1. Рекомендуется использовать параметр charset с кодировкой, указанной в заголовке `Content-Type`, совместно с [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request).2021Модуль urllib.request использует HTTP/1.1 и включает заголовок `Connection:close` в свои HTTP-запросы.2223Необязательный параметр *timeout* задает таймаут в секундах для блокирующих операций, таких как попытка подключения (если не указан, используется глобальная настройка таймаута по умолчанию). Это на самом деле работает только для HTTP, HTTPS и FTP-соединений.2425Необязательные параметры *cafile* и *capath* задают набор доверенных сертификатов ЦС для HTTPS-запросов. *cafile* должен указывать на один файл, содержащий набор сертификатов ЦС, а *capath* – на каталог с файлами сертификатов с хешированными именами. Дополнительную информацию можно найти в [`ssl.SSLContext.load_verify_locations()`](https://python-all.ru/3.3/library/ssl.html#ssl.SSLContext.load_verify_locations).2627Параметр *cadefault* указывает, следует ли вернуться к загрузке стандартного хранилища сертификатов, определенного библиотекой OpenSSL, если параметры *cafile* и *capath* опущены. Это будет работать только на некоторых платформах, отличных от Windows.2829> **Предупреждение**30>31> Если не указаны ни *cafile*, ни *capath*, а *cadefault* равен `False`, HTTPS-запрос не будет выполнять никакой проверки сертификата сервера.3233Для URL http и https эта функция возвращает объект [`http.client.HTTPResponse`](https://python-all.ru/3.3/library/http.client.html#http.client.HTTPResponse), который имеет следующие методы [*HTTPResponse Objects*](https://python-all.ru/3.3/library/http.client.html#httpresponse-objects).3435Для URL ftp, file и data, а также запросов, явно обрабатываемых устаревшими классами [`URLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.URLopener) и [`FancyURLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.FancyURLopener), эта функция возвращает объект `urllib.response.addinfourl`, который может работать как [*контекстный менеджер*](https://python-all.ru/3.3/glossary.html#term-context-manager) и имеет такие методы, как3637- `geturl()` – возвращает URL полученного ресурса; часто используется для определения, было ли выполнено перенаправление38- `info()` – возвращает метаинформацию страницы, такую как заголовки, в виде экземпляра [`email.message_from_string()`](https://python-all.ru/3.3/library/email.parser.html#email.message_from_string) (см. [Краткий справочник по HTTP-заголовкам](https://python-all.ru/3.3/library/urllib.request.html))39- `getcode()` – возвращает HTTP-статус код ответа.4041Вызывает [`URLError`](https://python-all.ru/3.3/library/urllib.error.html#urllib.error.URLError) при ошибках.4243Обратите внимание, что может быть возвращён `None`, если ни один обработчик не обрабатывает запрос (хотя установленный по умолчанию глобальный [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector) использует [`UnknownHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.UnknownHandler), чтобы гарантировать, что этого никогда не произойдёт).4445Кроме того, если обнаружены настройки прокси (например, когда установлена переменная окружения `*_proxy`, такая как `http_proxy`), по умолчанию устанавливается [`ProxyHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.ProxyHandler), который обеспечивает обработку запросов через прокси.4647Устаревшая функция `urllib.urlopen` из Python 2.6 и более ранних версий была прекращена; [`urllib.request.urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen) соответствует старой `urllib2.urlopen`. Обработка прокси, которая выполнялась путём передачи словаря в `urllib.urlopen`, может быть получена с помощью объектов [`ProxyHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.ProxyHandler).4849Изменено в версии 3.2: добавлены *cafile* и *capath*.5051Изменено в версии 3.2: Виртуальные хосты HTTPS теперь поддерживаются, если это возможно (то есть если [`ssl.HAS_SNI`](https://python-all.ru/3.3/library/ssl.html#ssl.HAS_SNI) истинно).5253Новое в версии 3.2: Параметр *data* может быть итерируемым объектом.5455Изменено в версии 3.3: добавлен *cadefault*.5657#### `urllib.request.install_opener(opener)`5859Устанавливает экземпляр [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector) в качестве глобального открывателя по умолчанию. Установка открывателя нужна только в том случае, если требуется, чтобы urlopen использовал именно этот открыватель; в противном случае просто вызывайте [`OpenerDirector.open()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector.open) вместо [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen). Код не проверяет, является ли объект реальным [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector); подойдёт любой класс с подходящим интерфейсом.6061#### `urllib.request.build_opener([handler, ...])`6263Возвращает экземпляр [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector), который объединяет обработчики в заданном порядке. *handler* могут быть как экземплярами [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler), так и подклассами [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler) (в этом случае должна быть возможность вызвать конструктор без параметров). Экземпляры следующих классов будут помещены перед *handler*, если только *handler* не содержат их, их экземпляры или их подклассы: [`ProxyHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.ProxyHandler) (если обнаружены настройки прокси), [`UnknownHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.UnknownHandler), [`HTTPHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPHandler), [`HTTPDefaultErrorHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPDefaultErrorHandler), [`HTTPRedirectHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPRedirectHandler), [`FTPHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.FTPHandler), [`FileHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.FileHandler), [`HTTPErrorProcessor`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPErrorProcessor).6465Если установка Python имеет поддержку SSL (т.е. если можно импортировать модуль [`ssl`](https://python-all.ru/3.3/library/ssl.html#module-ssl)), будет также добавлен [`HTTPSHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPSHandler).6667Подкласс [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler) может также изменить свой атрибут `handler_order`, чтобы изменить свою позицию в списке обработчиков.6869#### `urllib.request.pathname2url(path)`7071Преобразует имя пути *path* из локального синтаксиса пути в форму, используемую в компоненте пути URL. Это не создаёт полный URL. Возвращаемое значение уже будет закодировано с помощью функции [`quote()`](https://python-all.ru/3.3/library/urllib.parse.html#urllib.parse.quote).7273#### `urllib.request.url2pathname(path)`7475Преобразует компонент пути *path* из процентно-кодированного URL в локальный синтаксис пути. Эта функция не принимает полный URL. Для декодирования *path* используется функция [`unquote()`](https://python-all.ru/3.3/library/urllib.parse.html#urllib.parse.unquote).7677#### `urllib.request.getproxies()`7879Эта вспомогательная функция возвращает словарь, сопоставляющий схему с URL прокси-сервера. Сначала она ищет переменные окружения вида `<scheme>_proxy` (без учёта регистра) для всех операционных систем, а если не находит, то обращается к системной конфигурации Mac OS X и реестру Windows.8081> **Примечание**82>83> Если установлена переменная окружения `REQUEST_METHOD`, что обычно означает, что скрипт выполняется в CGI-среде, то переменная окружения `HTTP_PROXY` (в верхнем регистре `_PROXY`) будет игнорироваться. Это связано с тем, что клиент может подставить эту переменную через HTTP-заголовок «Proxy:». Если необходимо использовать HTTP-прокси в CGI-среде, следует явно использовать `ProxyHandler`.8485Предоставляются следующие классы:8687#### `class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)`8889Этот класс представляет абстракцию URL-запроса.9091*url* должен быть строкой, содержащей корректный URL.9293Параметр *data* должен быть объектом bytes, задающим дополнительные данные для отправки на сервер, или `None`, если такие данные не нужны. В настоящее время только HTTP-запросы используют *data*; HTTP-запрос будет POST вместо GET, когда указан параметр *data*. Параметр *data* должен быть буфером в стандартном формате *application/x-www-form-urlencoded*.9495Функция [`urllib.parse.urlencode()`](https://python-all.ru/3.3/library/urllib.parse.html#urllib.parse.urlencode) принимает отображение или последовательность кортежей из двух элементов и возвращает строку в этом формате. Её следует закодировать в байты перед использованием в качестве параметра *data*. Параметр charset в заголовке `Content-Type` может использоваться для указания кодировки. Если параметр charset не передан с заголовком Content-Type, сервер, следуя рекомендации HTTP 1.1, может предположить, что данные закодированы в ISO-8859-1. Рекомендуется использовать параметр charset с кодировкой, указанной в заголовке `Content-Type`, совместно с [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request).9697*headers* должен быть словарём, и он будет обрабатываться так, как если бы для каждой пары ключ-значение была вызвана [`add_header()`](https://python-all.ru/3.3/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`](https://python-all.ru/3.3/library/urllib.html#module-urllib) – `"Python-urllib/2.6"` (в Python 2.6).9899Пример использования заголовка `Content-Type` с аргументом *data* – отправка словаря вида `{"Content-Type":" application/x-www-form-urlencoded;charset=utf-8"}`100101Последние два аргумента представляют интерес только для корректной обработки сторонних HTTP-куки:102103*origin\_req\_host* должен быть хостом запроса исходной транзакции, как определено в [**RFC 2965**](https://python-all.ru/3.3/library/urllib.request.html). По умолчанию `http.cookiejar.request_host(self)`. Это имя хоста или IP-адрес исходного запроса, инициированного пользователем. Например, если запрос предназначен для изображения в HTML-документе, здесь должен быть хост запроса страницы, содержащей изображение.104105*unverifiable* должен указывать, является ли запрос непроверяемым (unverifiable), как определено в RFC 2965. По умолчанию `False`. Непроверяемый запрос – это запрос, URL которого пользователь не имел возможности подтвердить. Например, если запрос предназначен для изображения в HTML-документе, и у пользователя не было возможности подтвердить автоматическую загрузку изображения, это должно быть true.106107Параметр *method* должен быть строкой, указывающей метод HTTP-запроса, который будет использоваться (например, `'HEAD'`). Его значение хранится в атрибуте [`method`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.method) и используется методом [`get_method()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.get_method).108109Изменено в версии 3.3: добавлен аргумент [`Request.method`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.method) в класс Request.110111#### `class urllib.request.OpenerDirector`112113Класс [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector) открывает URL-адреса через цепочку обработчиков [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler). Он управляет объединением обработчиков в цепочку и восстановлением после ошибок.114115#### `class urllib.request.BaseHandler`116117Это базовый класс для всех зарегистрированных обработчиков – он отвечает только за простую механику регистрации.118119#### `class urllib.request.HTTPDefaultErrorHandler`120121Класс, определяющий обработчик по умолчанию для HTTP-ответов с ошибками; все ответы преобразуются в исключения [`HTTPError`](https://python-all.ru/3.3/library/urllib.error.html#urllib.error.HTTPError).122123#### `class urllib.request.HTTPRedirectHandler`124125Класс для обработки перенаправлений.126127#### `class urllib.request.HTTPCookieProcessor(cookiejar=None)`128129Класс для обработки HTTP-куки.130131#### `class urllib.request.ProxyHandler(proxies=None)`132133Заставляет запросы проходить через прокси. Если указан *proxies*, это должен быть словарь, сопоставляющий имена протоколов с URL-адресами прокси. По умолчанию список прокси читается из переменных окружения `<протокол>_proxy`. Если переменные окружения прокси не заданы, то в среде Windows настройки прокси берутся из раздела Internet Settings реестра, а в среде Mac OS X информация о прокси извлекается из OS X System Configuration Framework.134135Чтобы отключить автоматически обнаруженный прокси, передайте пустой словарь.136137> **Примечание**138>139> `HTTP_PROXY` будет игнорироваться, если установлена переменная `REQUEST_METHOD`; см. документацию по [`getproxies()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.getproxies).140141#### `class urllib.request.HTTPPasswordMgr`142143Ведёт базу данных соответствий между `(realm, uri) -> и (user, password)`.144145#### `class urllib.request.HTTPPasswordMgrWithDefaultRealm`146147Ведёт базу данных соответствий между `(realm, uri) -> и (user, password)`. Область (realm) со значением `None` считается универсальной – она используется, если не подходит ни одна другая.148149#### `class urllib.request.AbstractBasicAuthHandler(password_mgr=None)`150151Это миксин-класс, который помогает с HTTP-аутентификацией как на удалённом хосте, так и на прокси. *password\_mgr*, если задан, должен быть совместим с [`HTTPPasswordMgr`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPPasswordMgr); информацию об интерфейсе, который должен поддерживаться, см. в разделе [*HTTPPasswordMgr Objects*](https://python-all.ru/3.3/library/urllib.request.html#http-password-mgr).152153#### `class urllib.request.HTTPBasicAuthHandler(password_mgr=None)`154155Обрабатывает аутентификацию на удалённом хосте. *password\_mgr*, если указан, должен быть совместим с [`HTTPPasswordMgr`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPPasswordMgr); информацию об интерфейсе, который необходимо поддерживать, см. в разделе [*HTTPPasswordMgr Objects*](https://python-all.ru/3.3/library/urllib.request.html#http-password-mgr). HTTPBasicAuthHandler вызовет исключение [`ValueError`](https://python-all.ru/3.3/library/exceptions.html#ValueError) при неправильной схеме аутентификации.156157#### `class urllib.request.ProxyBasicAuthHandler(password_mgr=None)`158159Обрабатывает аутентификацию с прокси. *password\_mgr*, если задан, должен быть совместим с [`HTTPPasswordMgr`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPPasswordMgr); информацию об интерфейсе, который должен поддерживаться, см. в разделе [*HTTPPasswordMgr Objects*](https://python-all.ru/3.3/library/urllib.request.html#http-password-mgr).160161#### `class urllib.request.AbstractDigestAuthHandler(password_mgr=None)`162163Это миксин-класс, который помогает с HTTP-аутентификацией как на удалённом хосте, так и на прокси. *password\_mgr*, если задан, должен быть совместим с [`HTTPPasswordMgr`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPPasswordMgr); информацию об интерфейсе, который должен поддерживаться, см. в разделе [*HTTPPasswordMgr Objects*](https://python-all.ru/3.3/library/urllib.request.html#http-password-mgr).164165#### `class urllib.request.HTTPDigestAuthHandler(password_mgr=None)`166167Обрабатывает аутентификацию с удалённым хостом. *password\_mgr*, если задан, должен быть совместим с [`HTTPPasswordMgr`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPPasswordMgr); информацию об интерфейсе, который должен поддерживаться, см. в разделе [*HTTPPasswordMgr Objects*](https://python-all.ru/3.3/library/urllib.request.html#http-password-mgr). Когда добавлены и обработчик дайджест-аутентификации, и обработчик базовой аутентификации, дайджест-аутентификация всегда выполняется первой. Если дайджест-аутентификация снова возвращает ответ 40x, он передаётся обработчику базовой аутентификации. Этот метод-обработчик возбуждает исключение [`ValueError`](https://python-all.ru/3.3/library/exceptions.html#ValueError) при получении схемы аутентификации, отличной от Digest или Basic.168169Изменено в версии 3.3: Возбуждает [`ValueError`](https://python-all.ru/3.3/library/exceptions.html#ValueError) при неподдерживаемой схеме аутентификации.170171#### `class urllib.request.ProxyDigestAuthHandler(password_mgr=None)`172173Обрабатывает аутентификацию с прокси. *password\_mgr*, если задан, должен быть совместим с [`HTTPPasswordMgr`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPPasswordMgr); информацию об интерфейсе, который должен поддерживаться, см. в разделе [*HTTPPasswordMgr Objects*](https://python-all.ru/3.3/library/urllib.request.html#http-password-mgr).174175#### `class urllib.request.HTTPHandler`176177Класс для открытия HTTP-URL.178179#### `class urllib.request.HTTPSHandler(debuglevel=0, context=None, check_hostname=None)`180181Класс для открытия HTTPS-URL. *context* и *check\_hostname* имеют тот же смысл, что и в [`http.client.HTTPSConnection`](https://python-all.ru/3.3/library/http.client.html#http.client.HTTPSConnection).182183Изменено в версии 3.2: Добавлены параметры *context* и *check\_hostname*.184185#### `class urllib.request.FileHandler`186187Открывает локальные файлы.188189#### `class urllib.request.FTPHandler`190191Открывает FTP-URL.192193#### `class urllib.request.CacheFTPHandler`194195Открывает FTP-URL, сохраняя кеш открытых FTP-соединений для минимизации задержек.196197#### `class urllib.request.UnknownHandler`198199Универсальный класс для обработки неизвестных URL.200201#### `class urllib.request.HTTPErrorProcessor`202203Обрабатывает ошибочные HTTP-ответы.204205## 21.6.1. Объекты запросов206207Следующие методы описывают открытый интерфейс [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request), и все они могут быть переопределены в подклассах. Он также определяет несколько открытых атрибутов, которые могут использоваться клиентами для анализа разобранного запроса.208209#### `Request.full_url`210211Оригинальный URL, переданный конструктору.212213#### `Request.type`214215Схема URI.216217#### `Request.host`218219Авторитетная часть URI, обычно хост, но может также содержать порт, отделённый двоеточием.220221#### `Request.origin_req_host`222223Исходный хост запроса, без порта.224225#### `Request.selector`226227Путь URI. Если [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request) использует прокси, то selector будет полным URL, который передаётся прокси.228229#### `Request.data`230231Тело запроса (entity body) или None, если не указано.232233#### `Request.unverifiable`234235логическое значение, указывает, является ли запрос непроверяемым, как определено в RFC 2965.236237#### `Request.method`238239HTTP-метод запроса, который следует использовать. Это значение используется [`get_method()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.get_method) для переопределения вычисленного HTTP-метода запроса, который в противном случае был бы возвращён. Этот атрибут инициализируется значением аргумента *method*, переданного конструктору.240241Новое в версии 3.3.242243#### `Request.get_method()`244245Возвращает строку, указывающую метод HTTP-запроса. Если [`Request.method`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.method) не равен `None`, возвращает его значение; в противном случае возвращает `'GET'`, если [`Request.data`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.data) равно `None`, или `'POST'` в противном случае. Это имеет смысл только для HTTP-запросов.246247Изменено в версии 3.3: get\_method теперь проверяет значение [`Request.method`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.method).248249#### `Request.add_header(key, val)`250251Добавляет ещё один заголовок к запросу. В настоящее время заголовки игнорируются всеми обработчиками, кроме HTTP-обработчиков, где они добавляются в список заголовков, отправляемых серверу. Обратите внимание, что не может быть более одного заголовка с одним и тем же именем, и последующие вызовы перезапишут предыдущие в случае совпадения *ключа*. В настоящее время это не приводит к потере функциональности HTTP, поскольку все заголовки, имеющие смысл при многократном использовании, имеют (специфичный для заголовка) способ достижения той же функциональности с помощью только одного заголовка.252253#### `Request.add_unredirected_header(key, header)`254255Добавляет заголовок, который не будет добавлен в перенаправленный запрос.256257#### `Request.has_header(header)`258259Возвращает, имеет ли экземпляр указанный заголовок (проверяет как обычные, так и неперенаправленные).260261#### `Request.get_full_url()`262263Возвращает URL, переданный в конструктор.264265#### `Request.set_proxy(host, type)`266267Подготавливает запрос, подключаясь к прокси-серверу. *host* и *type* заменят соответствующие значения экземпляра, а selector экземпляра будет содержать исходный URL, переданный в конструктор.268269#### `Request.add_data(data)`270271Устанавливает данные [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request) в *data*. Все обработчики, кроме HTTP, игнорируют этот атрибут; для HTTP он должен быть байтовой строкой и изменит запрос, сделав его `POST`, а не `GET`. Устарело в версии 3.3, используйте [`Request.data`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.data).272273Устарело с версии 3.3, будет удалено в версии 3.4.274275#### `Request.has_data()`276277Возвращает, имеет ли экземпляр данные, отличные от `None`. Устарело в версии 3.3, используйте [`Request.data`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.data).278279Устарело с версии 3.3, будет удалено в версии 3.4.280281#### `Request.get_data()`282283Возвращает данные экземпляра. Устарело в версии 3.3, используйте [`Request.data`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.data).284285Устарело с версии 3.3, будет удалено в версии 3.4.286287#### `Request.get_type()`288289Возвращает тип URL – также известный как схема. Устарело в версии 3.3, используйте [`Request.type`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.type).290291Устарело с версии 3.3, будет удалено в версии 3.4.292293#### `Request.get_host()`294295Возвращает хост, к которому будет установлено соединение. Устарело в 3.3, используйте [`Request.host`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.host).296297Устарело с версии 3.3, будет удалено в версии 3.4.298299#### `Request.get_selector()`300301Возвращает селектор – часть URL, которая отправляется серверу. Устарело в 3.3, используйте [`Request.selector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.selector).302303Устарело с версии 3.3, будет удалено в версии 3.4.304305#### `Request.get_header(header_name, default=None)`306307Возвращает значение указанного заголовка. Если заголовок отсутствует, возвращает значение по умолчанию.308309#### `Request.header_items()`310311Возвращает список кортежей (имя\_заголовка, значение\_заголовка) заголовков запроса.312313#### `Request.set_proxy(host, type)`314315#### `Request.get_origin_req_host()`316317Возвращает хост запроса исходной транзакции, как определено в [**RFC 2965**](https://python-all.ru/3.3/library/urllib.request.html). См. документацию конструктора [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request). Устарело в 3.3, используйте [`Request.origin_req_host`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.origin_req_host).318319Устарело с версии 3.3, будет удалено в версии 3.4.320321#### `Request.is_unverifiable()`322323Возвращает, является ли запрос непроверяемым, как определено в RFC 2965. См. документацию конструктора [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request). Устарело в 3.3, используйте [`Request.unverifiable`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request.unverifiable).324325Устарело с версии 3.3, будет удалено в версии 3.4.326327## 21.6.2. Объекты OpenerDirector328329[`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector) имеет следующие методы:330331#### `OpenerDirector.add_handler(handler)`332333*handler* должен быть экземпляром [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler). Ищутся и добавляются в возможные цепочки следующие методы (обратите внимание, что ошибки HTTP являются особым случаем).334335- `protocol_open()` – сигнал о том, что обработчик умеет открывать URL-адреса *протокол*.336- `http_error_type()` – сигнал о том, что обработчик умеет обрабатывать ошибки HTTP с кодом ошибки HTTP *type*.337- `protocol_error()` – сигнал о том, что обработчик умеет обрабатывать ошибки от протокола *протокол* (кроме `http`).338- `protocol_request()` – сигнал о том, что обработчик умеет предварительно обрабатывать запросы *протокол*.339- `protocol_response()` – сигнал о том, что обработчик умеет выполнять последующую обработку ответов *протокол*.340341#### `OpenerDirector.open(url, data=None[, timeout])`342343Открывает указанный *url* (может быть объектом запроса или строкой), необязательно передавая указанные *data*. Аргументы, возвращаемые значения и исключения такие же, как у [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen) (которая просто вызывает метод [`open()`](https://python-all.ru/3.3/library/functions.html#open) у текущего установленного глобального [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector)). Необязательный параметр *timeout* задает тайм-аут в секундах для блокирующих операций, таких как попытка соединения (если не указан, используется глобальный тайм-аут по умолчанию). Тайм-аут работает только для соединений HTTP, HTTPS и FTP).344345#### `OpenerDirector.error(proto, *args)`346347Обрабатывает ошибку указанного протокола. Вызывает зарегистрированные обработчики ошибок для данного протокола с указанными аргументами (которые зависят от протокола). Протокол HTTP является особым случаем, использующим код ответа HTTP для определения конкретного обработчика ошибок; обратитесь к методам `http_error_*()` классов обработчиков.348349Возвращаемые значения и исключения такие же, как у [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen).350351Объекты OpenerDirector открывают URL в три этапа:352353Порядок вызова этих методов в каждом этапе определяется сортировкой экземпляров обработчиков.3543551. У каждого обработчика, имеющего метод с именем вида `protocol_request()`, этот метод вызывается для предварительной обработки запроса.3562. Обработчики с методом вида `protocol_open()` вызываются для обработки запроса. Этот этап завершается, когда обработчик возвращает значение, отличное от [`None`](https://python-all.ru/3.3/library/constants.html#None) (т.е. ответ), или возбуждает исключение (обычно [`URLError`](https://python-all.ru/3.3/library/urllib.error.html#urllib.error.URLError)). Исключения могут распространяться.357358 На самом деле описанный алгоритм сначала применяется к методам с именем `default_open()`. Если все такие методы возвращают [`None`](https://python-all.ru/3.3/library/constants.html#None), алгоритм повторяется для методов с именем вида `protocol_open()`. Если все такие методы возвращают [`None`](https://python-all.ru/3.3/library/constants.html#None), алгоритм повторяется для методов с именем `unknown_open()`.359360 Обратите внимание, что реализация этих методов может включать вызовы методов [`open()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector.open) и [`error()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector.error) родительского экземпляра [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector).3613. У каждого обработчика, имеющего метод с именем вида `protocol_response()`, этот метод вызывается для последующей обработки ответа.362363## 21.6.3. Объекты BaseHandler364365Объекты [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler) предоставляют несколько методов, которые полезны непосредственно, и другие, предназначенные для использования производными классами. Следующие предназначены для прямого использования:366367#### `BaseHandler.add_parent(director)`368369Добавляет директор в качестве родителя.370371#### `BaseHandler.close()`372373Удаляет всех родителей.374375Следующий атрибут и методы должны использоваться только классами, производными от [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler).376377> **Примечание**378>379> Принято соглашение: подклассы, определяющие методы `protocol_request()` или `protocol_response()`, называются `*Processor`; все остальные называются `*Handler`.380381#### `BaseHandler.parent`382383Действительный объект [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector), который можно использовать для открытия с помощью другого протокола или для обработки ошибок.384385#### `BaseHandler.default_open(req)`386387Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны определить его, если хотят перехватывать все URL.388389Этот метод, если он реализован, вызывается родительским [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector). Он должен возвращать файлоподобный объект, как описано в возвращаемом значении метода [`open()`](https://python-all.ru/3.3/library/functions.html#open) объекта [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector), или `None`. Он должен возбуждать [`URLError`](https://python-all.ru/3.3/library/urllib.error.html#urllib.error.URLError), если только не происходит поистине исключительная ситуация (например, [`MemoryError`](https://python-all.ru/3.3/library/exceptions.html#MemoryError) не должен отображаться на `URLError`).390391Этот метод будет вызван перед любым методом открытия, специфичным для протокола.392393#### `BaseHandler.protocol_open(req)`394395Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны определить его, если хотят обрабатывать URL с указанным протоколом.396397Этот метод, если он определён, вызывается родительским [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector). Возвращаемые значения должны быть такими же, как для `default_open()`.398399#### `BaseHandler.unknown_open(req)`400401Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны определить его, если хотят перехватывать все URL, для открытия которых нет зарегистрированного конкретного обработчика.402403Этот метод, если он реализован, вызывается родительским [`родительский`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler.parent) [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector). Возвращаемые значения должны быть такими же, как и для [`default_open()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler.default_open).404405#### `BaseHandler.http_error_default(req, fp, code, msg, hdrs)`406407Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны переопределить его, если намерены предоставить универсальный обработчик для всех прочих необработанных HTTP-ошибок. Он будет автоматически вызван [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector) при получении ошибки и обычно не должен вызываться в других обстоятельствах.408409*req* будет объектом [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request), *fp* – файлоподобным объектом с телом HTTP-ошибки, *code* – трёхзначным кодом ошибки, *msg* – понятным пользователю пояснением кода, а *hdrs* – объектом-отображением с заголовками ошибки.410411Возвращаемые значения и возбуждаемые исключения должны быть такими же, как у [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen).412413#### `BaseHandler.http_error_nnn(req, fp, code, msg, hdrs)`414415*nnn* должен быть трёхзначным кодом HTTP-ошибки. Этот метод также не определён в [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler), но будет вызван, если он существует, на экземпляре подкласса при возникновении HTTP-ошибки с кодом *nnn*.416417Подклассы должны переопределить этот метод для обработки конкретных HTTP-ошибок.418419Аргументы, возвращаемые значения и возбуждаемые исключения должны быть такими же, как и для [`http_error_default()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler.http_error_default).420421#### `BaseHandler.protocol_request(req)`422423Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны определить его, если хотят предварительно обрабатывать запросы указанного протокола.424425Этот метод, если он определён, вызывается родительским [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector). *req* будет объектом [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request). Возвращаемое значение должно быть объектом [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request).426427#### `BaseHandler.protocol_response(req, response)`428429Этот метод *не* определён в [`BaseHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.BaseHandler), но подклассы должны определить его, если хотят выполнять последующую обработку ответов указанного протокола.430431Этот метод, если он определён, вызывается родительским [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector). *req* будет объектом [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request). *response* будет объектом, реализующим тот же интерфейс, что и возвращаемое значение [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen). Возвращаемое значение должно реализовывать тот же интерфейс, что и возвращаемое значение [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen).432433## 21.6.4. Объекты HTTPRedirectHandler434435> **Примечание**436>437> Некоторые HTTP-перенаправления требуют действий от клиентского кода этого модуля. В таком случае возбуждается [`HTTPError`](https://python-all.ru/3.3/library/urllib.error.html#urllib.error.HTTPError). См. [**RFC 2616**](https://python-all.ru/3.3/library/urllib.request.html) для получения подробной информации о точном значении различных кодов перенаправления.438>439> Исключение `HTTPError` возбуждается из соображений безопасности, если HTTPRedirectHandler получает перенаправленный URL, который не является HTTP, HTTPS или FTP URL.440441#### `HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)`442443Возвращает [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request) или `None` в ответ на перенаправление. Этот метод вызывается реализациями по умолчанию методов `http_error_30*()`, когда от сервера получено перенаправление. Если необходимо выполнить перенаправление, верните новый [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request), чтобы дать возможность `http_error_30*()` выполнить перенаправление на *newurl*. В противном случае возбудите [`HTTPError`](https://python-all.ru/3.3/library/urllib.error.html#urllib.error.HTTPError), если ни один другой обработчик не должен пытаться обработать этот URL, или верните `None`, если вы не можете этого сделать, но другой обработчик может.444445> **Примечание**446>447> Реализация этого метода по умолчанию не строго следует [**RFC 2616**](https://python-all.ru/3.3/library/urllib.request.html), в котором сказано, что ответы с кодами 301 и 302 на `POST` запросы не должны автоматически перенаправляться без подтверждения пользователем. На практике браузеры разрешают автоматическое перенаправление этих ответов, заменяя POST на `GET`, и реализация по умолчанию воспроизводит такое поведение.448449#### `HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)`450451Перенаправляет на URL из заголовков `Location:` или `URI:`. Этот метод вызывается родительским [`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector) при получении HTTP-ответа «перемещён навсегда».452453#### `HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)`454455То же, что и [`http_error_301()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPRedirectHandler.http_error_301), но вызывается для ответа «found».456457#### `HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)`458459То же, что и [`http_error_301()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPRedirectHandler.http_error_301), но вызывается для ответа «see other».460461#### `HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)`462463То же, что и [`http_error_301()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPRedirectHandler.http_error_301), но вызывается для ответа «temporary redirect».464465## 21.6.5. Объекты HTTPCookieProcessor466467Экземпляры [`HTTPCookieProcessor`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPCookieProcessor) имеют один атрибут:468469#### `HTTPCookieProcessor.cookiejar`470471Объект [`http.cookiejar.CookieJar`](https://python-all.ru/3.3/library/http.cookiejar.html#http.cookiejar.CookieJar), в котором хранятся куки.472473## 21.6.6. Объекты ProxyHandler474475#### `ProxyHandler.protocol_open(request)`476477Для каждого *протокола*, для которого в словаре *proxies*, переданном в конструктор, указан прокси, объект [`ProxyHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.ProxyHandler) будет иметь метод `protocol_open()`. Этот метод изменяет запрос для направления через прокси, вызывая `request.set_proxy()`, и передаёт управление следующему обработчику в цепочке для фактического выполнения протокола.478479## 21.6.7. Объекты HTTPPasswordMgr480481Эти методы доступны для объектов [`HTTPPasswordMgr`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPPasswordMgr) и [`HTTPPasswordMgrWithDefaultRealm`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPPasswordMgrWithDefaultRealm).482483#### `HTTPPasswordMgr.add_password(realm, uri, user, passwd)`484485*uri* может быть как одним URI, так и последовательностью URI. *realm*, *user* и *passwd* должны быть строками. В результате `(user, passwd)` будет использоваться в качестве токенов аутентификации при запросе аутентификации для *realm* и супер-URI любого из указанных URI.486487#### `HTTPPasswordMgr.find_user_password(realm, authuri)`488489Возвращает пару пользователь/пароль для указанных realm и URI, если они есть. Если совпадений нет, этот метод вернёт `(None, None)`.490491Для объектов [`HTTPPasswordMgrWithDefaultRealm`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPPasswordMgrWithDefaultRealm), если для указанного *realm* нет подходящей пары пользователь/пароль, будет выполнен поиск по realm `None`.492493## 21.6.8. Объекты AbstractBasicAuthHandler494495#### `AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)`496497Обрабатывает запрос аутентификации, получая пару пользователь/пароль и повторяя запрос. *authreq* должно быть именем заголовка, в котором содержится информация о realm, *host* указывает URL и путь для аутентификации, *req* должен быть (неудачным) объектом [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request), а *headers* – заголовками ошибки.498499*host* – это либо полномочное имя (например, `"python.org"`), либо URL, содержащий компонент полномочного имени (например, `"http://python.org/"`). В любом случае полномочное имя не должно содержать компонента userinfo (так что `"python.org"` и `"python.org:80"` допустимы, а `"joe:password@python.org"` – нет).500501## 21.6.9. Объекты HTTPBasicAuthHandler502503#### `HTTPBasicAuthHandler.http_error_401(req, fp, code, msg, hdrs)`504505Повторяет запрос с информацией аутентификации, если она доступна.506507## 21.6.10. Объекты ProxyBasicAuthHandler508509#### `ProxyBasicAuthHandler.http_error_407(req, fp, code, msg, hdrs)`510511Повторяет запрос с информацией аутентификации, если она доступна.512513## 21.6.11. Объекты AbstractDigestAuthHandler514515#### `AbstractDigestAuthHandler.http_error_auth_reqed(authreq, host, req, headers)`516517*authreq* должно быть именем заголовка, в котором содержится информация о realm, *host* должен быть хостом для аутентификации, *req* должен быть (неудачным) объектом [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request), а *headers* – заголовками ошибки.518519## 21.6.12. Объекты HTTPDigestAuthHandler520521#### `HTTPDigestAuthHandler.http_error_401(req, fp, code, msg, hdrs)`522523Повторяет запрос с информацией аутентификации, если она доступна.524525## 21.6.13. Объекты ProxyDigestAuthHandler526527#### `ProxyDigestAuthHandler.http_error_407(req, fp, code, msg, hdrs)`528529Повторяет запрос с информацией аутентификации, если она доступна.530531## 21.6.14. Объекты HTTPHandler532533#### `HTTPHandler.http_open(req)`534535Отправляет HTTP-запрос, который может быть GET или POST, в зависимости от `req.has_data()`.536537## 21.6.15. Объекты HTTPSHandler538539#### `HTTPSHandler.https_open(req)`540541Отправляет HTTPS-запрос, который может быть GET или POST, в зависимости от `req.has_data()`.542543## 21.6.16. Объекты FileHandler544545#### `FileHandler.file_open(req)`546547Открывает файл локально, если имя хоста отсутствует или равно `'localhost'`.548549Изменено в версии 3.2: Этот метод применим только к локальным именам хостов. При указании удалённого имени хоста возникает исключение [`URLError`](https://python-all.ru/3.3/library/urllib.error.html#urllib.error.URLError).550551## 21.6.17. Объекты FTPHandler552553#### `FTPHandler.ftp_open(req)`554555Открывает FTP-файл, указанный *req*. Вход всегда выполняется с пустыми именем пользователя и паролем.556557## 21.6.18. Объекты CacheFTPHandler558559Объекты [`CacheFTPHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.CacheFTPHandler) являются объектами [`FTPHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.FTPHandler) с дополнительными методами:560561#### `CacheFTPHandler.setTimeout(t)`562563Устанавливает тайм-аут соединений равным *t* секунд.564565#### `CacheFTPHandler.setMaxConns(m)`566567Устанавливает максимальное количество кэшированных соединений равным *m*.568569## 21.6.19. Объекты UnknownHandler570571#### `UnknownHandler.unknown_open()`572573Вызывает исключение [`URLError`](https://python-all.ru/3.3/library/urllib.error.html#urllib.error.URLError).574575## 21.6.20. Объекты HTTPErrorProcessor576577#### `HTTPErrorProcessor.http_response()`578579Обрабатывает ошибочные HTTP-ответы.580581Для кода 200 объект ответа возвращается немедленно.582583Для кодов ошибок, отличных от 200, он просто передаёт задачу методам-обработчикам `protocol_error_code()` через [`OpenerDirector.error()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector.error). В конечном итоге [`HTTPDefaultErrorHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPDefaultErrorHandler) вызовет исключение [`HTTPError`](https://python-all.ru/3.3/library/urllib.error.html#urllib.error.HTTPError), если ни один другой обработчик не обработает ошибку.584585#### `HTTPErrorProcessor.https_response()`586587Обрабатывает ошибочные HTTPS-ответы.588589Поведение такое же, как у [`http_response()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.HTTPErrorProcessor.http_response).590591## 21.6.21. Примеры592593Этот пример получает главную страницу python.org и отображает первые 300 байт этой страницы.594595```python596>>> import urllib.request597>>> f = urllib.request.urlopen('http://www.python.org/')598>>> print(f.read(300))599b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"600"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html601xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\n<head>\n602<meta http-equiv="content-type" content="text/html; charset=utf-8" />\n603<title>Python Programming '604```605606Обратите внимание, что urlopen возвращает объект bytes. Это связано с тем, что urlopen не может автоматически определить кодировку байтового потока, получаемого от HTTP-сервера. В общем случае программа декодирует возвращаемый объект bytes в строку после того, как определит или угадает подходящую кодировку.607608Следующий документ W3C, [http://www.w3.org/International/O-charset](https://python-all.ru/3.3/library/urllib.request.html), перечисляет различные способы, которыми (X)HTML- или XML-документ может указывать информацию о своей кодировке.609610Поскольку на сайте python.org используется кодировка *utf-8*, указанная в его мета-теге, мы будем использовать ту же самую для декодирования объекта bytes.611612```python613>>> with urllib.request.urlopen('http://www.python.org/') as f:614... print(f.read(100).decode('utf-8'))615...616<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"617"http://www.w3.org/TR/xhtml1/DTD/xhtm618```619620Тот же результат можно получить и без использования [*менеджера контекста*](https://python-all.ru/3.3/glossary.html#term-context-manager) подхода.621622```python623>>> import urllib.request624>>> f = urllib.request.urlopen('http://www.python.org/')625>>> print(f.read(100).decode('utf-8'))626<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"627"http://www.w3.org/TR/xhtml1/DTD/xhtm628```629630В следующем примере мы отправляем поток данных на стандартный ввод CGI и читаем данные, которые он возвращает. Обратите внимание: этот пример будет работать только в том случае, если установка Python поддерживает SSL.631632```python633>>> import urllib.request634>>> req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi',635... data=b'This data is passed to stdin of the CGI')636>>> f = urllib.request.urlopen(req)637>>> print(f.read().decode('utf-8'))638Got Data: "This data is passed to stdin of the CGI"639```640641Код образца CGI, использованного в приведённом выше примере:642643```python644#!/usr/bin/env python645import sys646data = sys.stdin.read()647print('Content-type: text-plain\n\nGot Data: "%s"' % data)648```649650Вот пример выполнения запроса `PUT` с использованием [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request):651652```python653import urllib.request654DATA=b'some data'655req = urllib.request.Request(url='http://localhost:8080', data=DATA,method='PUT')656f = urllib.request.urlopen(req)657print(f.status)658print(f.reason)659```660661Использование базовой HTTP-аутентификации:662663```python664import urllib.request665# Создать OpenerDirector с поддержкой базовой HTTP-аутентификации...666auth_handler = urllib.request.HTTPBasicAuthHandler()667auth_handler.add_password(realm='PDQ Application',668 uri='https://mahler:8092/site-updates.py',669 user='klem',670 passwd='kadidd!ehopper')671opener = urllib.request.build_opener(auth_handler)672# ...и установить его глобально, чтобы его можно было использовать с urlopen.673urllib.request.install_opener(opener)674urllib.request.urlopen('http://www.example.com/login.html')675```676677[`build_opener()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.build_opener) по умолчанию предоставляет множество обработчиков, включая [`ProxyHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.ProxyHandler). По умолчанию [`ProxyHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.ProxyHandler) использует переменные окружения с именами вида `<scheme>_proxy`, где `<scheme>` – это соответствующая схема URL. Например, переменная окружения `http_proxy` считывается для получения URL HTTP-прокси.678679В этом примере стандартный [`ProxyHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.ProxyHandler) заменяется на тот, который использует программно задаваемые URL прокси, и добавляется поддержка авторизации прокси с помощью [`ProxyBasicAuthHandler`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.ProxyBasicAuthHandler).680681```python682proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})683proxy_auth_handler = urllib.request.ProxyBasicAuthHandler()684proxy_auth_handler.add_password('realm', 'host', 'username', 'password')685686opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler)687# На этот раз, вместо установки OpenerDirector, используется напрямую:688opener.open('http://www.example.com/login.html')689```690691Добавление HTTP-заголовков:692693Используйте аргумент *headers* конструктора [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request) или:694695```python696import urllib.request697req = urllib.request.Request('http://www.example.com/')698req.add_header('Referer', 'http://www.python.org/')699r = urllib.request.urlopen(req)700```701702[`OpenerDirector`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector) автоматически добавляет заголовок *User-Agent* к каждому [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request). Чтобы изменить это:703704```python705import urllib.request706opener = urllib.request.build_opener()707opener.addheaders = [('User-agent', 'Mozilla/5.0')]708opener.open('http://www.example.com/')709```710711Также следует помнить, что несколько стандартных заголовков (*Content-Length*, *Content-Type* без параметра charset и *Host*) добавляются, когда [`Request`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.Request) передаётся в [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen) (или [`OpenerDirector.open()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.OpenerDirector.open)).712713Ниже приведён пример сеанса, в котором используется метод `GET` для получения URL, содержащего параметры:714715```python716>>> import urllib.request717>>> import urllib.parse718>>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})719>>> f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)720>>> print(f.read().decode('utf-8'))721```722723В следующем примере вместо этого используется метод `POST`. Обратите внимание, что вывод params из urlencode кодируется в байты перед отправкой в urlopen в качестве data:724725```python726>>> import urllib.request727>>> import urllib.parse728>>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})729>>> data = data.encode('utf-8')730>>> request = urllib.request.Request("http://requestb.in/xrbl82xr")731>>> # добавление параметра charset в заголовок Content‑Type.732>>> request.add_header("Content-Type","application/x-www-form-urlencoded;charset=utf-8")733>>> f = urllib.request.urlopen(request, data)734>>> print(f.read().decode('utf-8'))735```736737В следующем примере используется явно указанный HTTP-прокси, переопределяющий настройки окружения:738739```python740>>> import urllib.request741>>> proxies = {'http': 'http://proxy.example.com:8080/'}742>>> opener = urllib.request.FancyURLopener(proxies)743>>> f = opener.open("http://www.python.org")744>>> f.read().decode('utf-8')745```746747В следующем примере прокси не используются вовсе, переопределяя настройки окружения:748749```python750>>> import urllib.request751>>> opener = urllib.request.FancyURLopener({})752>>> f = opener.open("http://www.python.org/")753>>> f.read().decode('utf-8')754```755756## 21.6.22. Устаревший интерфейс757758Следующие функции и классы перенесены из модуля Python 2 `urllib` (в отличие от `urllib2`). В будущем они могут стать устаревшими.759760#### `urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)`761762Копирует сетевой объект, заданный URL, в локальный файл. Если URL указывает на локальный файл, объект не будет скопирован, если не указан filename. Возвращает кортеж `(filename, headers)`, где *filename* – это имя локального файла, в котором находится объект, а *headers* – это то, что вернул метод `info()` объекта, возвращённого [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen) (для удалённого объекта). Исключения те же, что и для [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen).763764Второй аргумент, если он задан, указывает, в какой файл копировать данные (если отсутствует, данные будут записаны во временный файл с автоматически сгенерированным именем). Третий аргумент, если он задан, – это функция-обработчик, которая будет вызвана один раз при установке сетевого соединения и затем после каждого прочитанного блока. Функция будет получать три аргумента: количество переданных блоков, размер блока в байтах и общий размер файла. Третий аргумент может быть `-1` на старых FTP-серверах, которые не возвращают размер файла в ответ на запрос получения.765766Следующий пример иллюстрирует наиболее распространённый сценарий использования:767768```python769>>> import urllib.request770>>> local_filename, headers = urllib.request.urlretrieve('http://python.org/')771>>> html = open(local_filename)772>>> html.close()773```774775Если в *url* используется идентификатор схемы `http:`, необязательный аргумент *data* может быть задан для указания запроса `POST` (обычно тип запроса – `GET`). Аргумент *data* должен быть объектом bytes в стандартном формате *application/x-www-form-urlencoded*; см. функцию [`urllib.parse.urlencode()`](https://python-all.ru/3.3/library/urllib.parse.html#urllib.parse.urlencode).776777[`urlretrieve()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlretrieve) вызовет исключение `ContentTooShortError`, если обнаружит, что объём доступных данных меньше ожидаемого (то есть размера, указанного в заголовке *Content-Length*). Это может произойти, например, если загрузка была прервана.778779Заголовок *Content-Length* рассматривается как нижняя граница: если доступно больше данных для чтения, urlretrieve читает больше данных, но если данных меньше, он вызывает исключение.780781В этом случае загруженные данные всё ещё можно получить, они хранятся в атрибуте `content` экземпляра исключения.782783Если заголовок *Content-Length* не был передан, urlretrieve не может проверить размер загруженных данных и просто возвращает их. В этом случае остаётся только предполагать, что загрузка прошла успешно.784785#### `urllib.request.urlcleanup()`786787Удаляет временные файлы, которые могли остаться после предыдущих вызовов [`urlretrieve()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlretrieve).788789#### `class urllib.request.URLopener(proxies=None, **x509)`790791Устарело с версии 3.3.792793Базовый класс для открытия и чтения URL. Если не требуется поддержка открытия объектов с использованием схем, отличных от `http:`, `ftp:` или `file:`, вероятно, стоит использовать [`FancyURLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.FancyURLopener).794795По умолчанию класс [`URLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.URLopener) отправляет заголовок *User-Agent* со значением `urllib/VVV`, где *VVV* – это номер версии [`urllib`](https://python-all.ru/3.3/library/urllib.html#module-urllib). Приложения могут определить собственный заголовок *User-Agent*, создав подкласс [`URLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.URLopener) или [`FancyURLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.FancyURLopener) и установив атрибут класса [`version`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.URLopener.version) в соответствующее строковое значение в определении подкласса.796797Необязательный параметр *proxies* должен быть словарём, сопоставляющим имена схем с URL прокси, причём пустой словарь полностью отключает прокси. По умолчанию значение равно `None`; в этом случае будут использованы настройки прокси из окружения, если они присутствуют, как описано в определении [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen) выше.798799Дополнительные именованные параметры, собранные в *x509*, могут использоваться для аутентификации клиента при использовании схемы `https:`. Поддерживаются ключи *key\_file* и *cert\_file* для предоставления SSL-ключа и сертификата; оба необходимы для поддержки аутентификации клиента.800801Объекты [`URLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.URLopener) вызывают исключение [`OSError`](https://python-all.ru/3.3/library/exceptions.html#OSError), если сервер возвращает код ошибки.802803> #### `open(fullurl, data=None)`804>805> Открывает *fullurl*, используя соответствующий протокол. Этот метод настраивает кеш и информацию о прокси, затем вызывает соответствующий метод open с его входными аргументами. Если схема не распознана, вызывается [`open_unknown()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.URLopener.open_unknown). Аргумент *data* имеет тот же смысл, что и аргумент *data* функции [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen).806>807> #### `open_unknown(fullurl, data=None)`808>809> Переопределяемый интерфейс для открытия неизвестных типов URL.810>811> #### `retrieve(url, filename=None, reporthook=None, data=None)`812>813> Извлекает содержимое *url* и помещает его в *filename*. Возвращаемое значение – кортеж, состоящий из локального имени файла и либо объекта [`email.message.Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message), содержащего заголовки ответа (для удалённых URL), либо `None` (для локальных URL). Затем вызывающий код должен открыть и прочитать содержимое *filename*. Если *filename* не указан и URL ссылается на локальный файл, возвращается исходное имя файла. Если URL не локальный и *filename* не указан, имя файла – результат вызова [`tempfile.mktemp()`](https://python-all.ru/3.3/library/tempfile.html#tempfile.mktemp) с суффиксом, совпадающим с суффиксом последнего компонента пути входного URL. Если задан *reporthook*, он должен быть функцией, принимающей три числовых параметра: номер блока, максимальный размер, которым читаются блоки, и общий размер загрузки (-1, если неизвестен). Она будет вызвана один раз в начале и после каждого считанного из сети блока данных. *reporthook* игнорируется для локальных URL.814>815> Если в *url* используется идентификатор схемы `http:`, необязательный аргумент *data* может быть задан для указания запроса `POST` (обычно тип запроса – `GET`). Аргумент *data* должен быть в стандартном формате *application/x-www-form-urlencoded*; см. функцию [`urllib.parse.urlencode()`](https://python-all.ru/3.3/library/urllib.parse.html#urllib.parse.urlencode).816>817> #### `version`818>819> Переменная, задающая пользовательский агент объекта opener. Чтобы заставить [`urllib`](https://python-all.ru/3.3/library/urllib.html#module-urllib) сообщать серверам, что это определённый пользовательский агент, установите её в подклассе как переменную класса или в конструкторе перед вызовом конструктора базового класса.820821#### `class urllib.request.FancyURLopener(...)`822823Устарело с версии 3.3.824825[`FancyURLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.FancyURLopener) является подклассом [`URLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.URLopener), предоставляющим стандартную обработку следующих кодов ответа HTTP: 301, 302, 303, 307 и 401. Для перечисленных выше кодов 30x заголовок *Location* используется для получения фактического URL. Для кода 401 (требуется аутентификация) выполняется базовая HTTP-аутентификация. Для кодов 30x рекурсия ограничена значением атрибута *maxtries*, по умолчанию равным 10.826827Для всех остальных кодов ответа вызывается метод `http_error_default()`, который можно переопределить в подклассах для соответствующей обработки ошибки.828829> **Примечание**830>831> Согласно букве [**RFC 2616**](https://python-all.ru/3.3/library/urllib.request.html), ответы 301 и 302 на POST-запросы не должны автоматически перенаправляться без подтверждения пользователем. На деле браузеры допускают автоматическое перенаправление этих ответов, изменяя POST на GET, и [`urllib`](https://python-all.ru/3.3/library/urllib.html#module-urllib) воспроизводит такое поведение.832833Параметры конструктора такие же, как и для [`URLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.URLopener).834835> **Примечание**836>837> При выполнении базовой аутентификации экземпляр [`FancyURLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.FancyURLopener) вызывает свой метод [`prompt_user_passwd()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.FancyURLopener.prompt_user_passwd). Реализация по умолчанию запрашивает у пользователя необходимые сведения на управляющем терминале. При необходимости подкласс может переопределить этот метод, чтобы обеспечить более подходящее поведение.838839Класс [`FancyURLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.FancyURLopener) предоставляет один дополнительный метод, который следует переопределить для обеспечения соответствующего поведения:840841#### `prompt_user_passwd(host, realm)`842843Возвращает информацию, необходимую для аутентификации пользователя на указанном хосте в заданной области безопасности. Возвращаемое значение должно быть кортежем, `(user, password)`, который можно использовать для базовой аутентификации.844845Реализация запрашивает эту информацию на терминале; приложение должно переопределить этот метод, чтобы использовать подходящую модель взаимодействия в локальной среде.846847## 21.6.23. [`urllib.request`](https://python-all.ru/3.3/library/urllib.request.html#module-urllib.request) Ограничения848849>850851- В настоящее время поддерживаются только следующие протоколы: HTTP (версии 0.9 и 1.0), FTP и локальные файлы.852- Функция кэширования [`urlretrieve()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlretrieve) отключена до тех пор, пока кто-нибудь не найдет время реализовать правильную обработку заголовков с временем истечения.853- Должна быть функция для проверки, находится ли определённый URL в кэше.854- Для обратной совместимости, если URL указывает на локальный файл, но файл не удаётся открыть, URL интерпретируется заново с использованием протокола FTP. Это иногда может приводить к запутанным сообщениям об ошибках.855- Функции [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen) и [`urlretrieve()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlretrieve) могут вызывать сколь угодно долгие задержки при ожидании установки сетевого соединения. Это означает, что создать интерактивный веб-клиент с помощью этих функций без использования потоков сложно.856- Данные, возвращаемые [`urlopen()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlopen) или [`urlretrieve()`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.urlretrieve), представляют собой необработанные данные, возвращаемые сервером. Это могут быть бинарные данные (например, изображение), обычный текст или, скажем, HTML. Протокол HTTP предоставляет информацию о типе в заголовке ответа, которую можно узнать, посмотрев на заголовок *Content-Type*. Если возвращаемые данные являются HTML, можно использовать модуль [`html.parser`](https://python-all.ru/3.3/library/html.parser.html#module-html.parser) для его разбора.857- Код, работающий с протоколом FTP, не может различить файл и каталог. Это может привести к неожиданному поведению при попытке чтения URL, указывающего на недоступный файл. Если URL заканчивается на `/`, считается, что он ссылается на каталог, и обработка будет соответствующей. Но если попытка чтения файла приводит к ошибке 550 (означающей, что URL не найден или недоступен, часто по причинам прав доступа), то путь обрабатывается как каталог, чтобы учесть случай, когда в URL указан каталог, но завершающий `/` опущен. Это может привести к вводящим в заблуждение результатам при попытке получить файл, права на чтение которого делают его недоступным; код FTP попытается его прочитать, получит ошибку 550, а затем выполнит листинг каталога для недоступного файла. Если требуется тонкий контроль, рассмотрите возможность использования модуля [`ftplib`](https://python-all.ru/3.3/library/ftplib.html#module-ftplib), создания подкласса [`FancyURLopener`](https://python-all.ru/3.3/library/urllib.request.html#urllib.request.FancyURLopener) или изменения *\_urlopener* в соответствии с вашими потребностями.858859# 21.7. [`urllib.response`](https://python-all.ru/3.3/library/urllib.request.html#module-urllib.response) – Классы ответов, используемые urllib860861Модуль [`urllib.response`](https://python-all.ru/3.3/library/urllib.request.html#module-urllib.response) определяет функции и классы, которые задают минимальный файлоподобный интерфейс, включая `read()` и `readline()`. Типичный объект ответа – это экземпляр addinfourl, который определяет метод `info()`, возвращающий заголовки, и метод `geturl()`, возвращающий URL. Функции, определенные этим модулем, используются внутри модуля [`urllib.request`](https://python-all.ru/3.3/library/urllib.request.html#module-urllib.request).862