Содержание страницы
21.6. urllib.request – расширяемая библиотека для открытия URL¶urllib.request – Extensible library for opening URLs
Модуль urllib.request определяет функции и классы, которые помогают открывать URL (в основном HTTP) в сложном мире – базовая и дайджест-аутентификация, перенаправления, куки и многое другое.
Модуль urllib.request определяет следующие функции:
- urllib.request.urlopen(url, data=None[, timeout], *, cafile=None, capath=None, cadefault=False)¶
Открывает URL url, который может быть строкой или объектом Request.
data должен быть объектом bytes, задающим дополнительные данные для отправки на сервер, или None, если такие данные не нужны. data также может быть итерируемым объектом, и в этом случае значение Content-Length должно быть указано в заголовках. В настоящее время только HTTP-запросы используют data; HTTP-запрос будет POST вместо GET, когда указан параметр data.
data должен быть буфером в стандартном application/x-www-form-urlencoded формате. Функция urllib.parse.urlencode() принимает отображение или последовательность кортежей из двух элементов и возвращает строку в этом формате. Перед использованием в качестве параметра data её следует закодировать в байты. Параметр charset в заголовке Content-Type может использоваться для указания кодировки. Если параметр charset не передан с заголовком Content-Type, сервер, следуя рекомендации HTTP 1.1, может предположить, что данные закодированы в ISO-8859-1. Рекомендуется использовать параметр charset с кодировкой, указанной в заголовке Content-Type, совместно с Request.
Модуль urllib.request использует HTTP/1.1 и включает заголовок Connection:close в свои HTTP-запросы.
Необязательный параметр timeout задает таймаут в секундах для блокирующих операций, таких как попытка подключения (если не указан, используется глобальная настройка таймаута по умолчанию). Это на самом деле работает только для HTTP, HTTPS и FTP-соединений.
Необязательные параметры cafile и capath задают набор доверенных сертификатов ЦС для HTTPS-запросов. cafile должен указывать на один файл, содержащий набор сертификатов ЦС, а capath – на каталог с файлами сертификатов с хешированными именами. Дополнительную информацию можно найти в ssl.SSLContext.load_verify_locations().
Параметр cadefault указывает, следует ли вернуться к загрузке стандартного хранилища сертификатов, определенного библиотекой OpenSSL, если параметры cafile и capath опущены. Это будет работать только на некоторых платформах, отличных от Windows.
Предупреждение
Если не указаны ни cafile, ни capath, а cadefault равен False, HTTPS-запрос не будет выполнять никакой проверки сертификата сервера.
Для URL http и https эта функция возвращает объект http.client.HTTPResponse, который имеет следующие методы HTTPResponse Objects.
Для URL ftp, file и data, а также запросов, явно обрабатываемых устаревшими классами URLopener и FancyURLopener, эта функция возвращает объект urllib.response.addinfourl, который может работать как контекстный менеджер и имеет такие методы, как
- geturl() – возвращает URL полученного ресурса; часто используется для определения, было ли выполнено перенаправление
- info() – возвращает метаинформацию страницы, такую как заголовки, в виде экземпляра email.message_from_string() (см. Краткий справочник по HTTP-заголовкам)
- getcode() – возвращает HTTP-статус код ответа.
Вызывает URLError при ошибках.
Обратите внимание, что может быть возвращён None, если ни один обработчик не обрабатывает запрос (хотя установленный по умолчанию глобальный OpenerDirector использует UnknownHandler, чтобы гарантировать, что этого никогда не произойдёт).
Кроме того, если обнаружены настройки прокси (например, когда установлена переменная окружения *_proxy, такая как http_proxy), по умолчанию устанавливается ProxyHandler, который обеспечивает обработку запросов через прокси.
Устаревшая функция urllib.urlopen из Python 2.6 и более ранних версий была прекращена; urllib.request.urlopen() соответствует старой urllib2.urlopen. Обработка прокси, которая выполнялась путём передачи словаря в urllib.urlopen, может быть получена с помощью объектов ProxyHandler.
Изменено в версии 3.2: добавлены cafile и capath.
Изменено в версии 3.2: Виртуальные хосты HTTPS теперь поддерживаются, если это возможно (то есть если ssl.HAS_SNI истинно).
Новое в версии 3.2: Параметр data может быть итерируемым объектом.
Изменено в версии 3.3: добавлен cadefault.
- urllib.request.install_opener(opener)¶
Устанавливает экземпляр OpenerDirector в качестве глобального открывателя по умолчанию. Установка открывателя нужна только в том случае, если требуется, чтобы urlopen использовал именно этот открыватель; в противном случае просто вызывайте OpenerDirector.open() вместо urlopen(). Код не проверяет, является ли объект реальным OpenerDirector; подойдёт любой класс с подходящим интерфейсом.
- urllib.request.build_opener([handler, ...])¶
Возвращает экземпляр OpenerDirector, который объединяет обработчики в заданном порядке. handler могут быть как экземплярами BaseHandler, так и подклассами BaseHandler (в этом случае должна быть возможность вызвать конструктор без параметров). Экземпляры следующих классов будут помещены перед handler, если только handler не содержат их, их экземпляры или их подклассы: ProxyHandler (если обнаружены настройки прокси), UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler, HTTPErrorProcessor.
Если установка Python имеет поддержку SSL (т.е. если можно импортировать модуль ssl), будет также добавлен HTTPSHandler.
Подкласс BaseHandler может также изменить свой атрибут handler_order, чтобы изменить свою позицию в списке обработчиков.
- urllib.request.pathname2url(path)¶
Преобразует имя пути path из локального синтаксиса пути в форму, используемую в компоненте пути URL. Это не создаёт полный URL. Возвращаемое значение уже будет закодировано с помощью функции quote().
- urllib.request.url2pathname(path)¶
Преобразует компонент пути path из процентно-кодированного URL в локальный синтаксис пути. Эта функция не принимает полный URL. Для декодирования path используется функция unquote().
- urllib.request.getproxies()¶
Эта вспомогательная функция возвращает словарь, сопоставляющий схему с URL прокси-сервера. Сначала она ищет переменные окружения вида <scheme>_proxy (без учёта регистра) для всех операционных систем, а если не находит, то обращается к системной конфигурации Mac OS X и реестру Windows.
Примечание
Если установлена переменная окружения REQUEST_METHOD, что обычно означает, что скрипт выполняется в CGI-среде, то переменная окружения HTTP_PROXY (в верхнем регистре _PROXY) будет игнорироваться. Это связано с тем, что клиент может подставить эту переменную через HTTP-заголовок «Proxy:». Если необходимо использовать HTTP-прокси в CGI-среде, следует явно использовать ProxyHandler.
Предоставляются следующие классы:
- class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)¶
Этот класс представляет абстракцию URL-запроса.
url должен быть строкой, содержащей корректный URL.
Параметр data должен быть объектом bytes, задающим дополнительные данные для отправки на сервер, или None, если такие данные не нужны. В настоящее время только HTTP-запросы используют data; HTTP-запрос будет POST вместо GET, когда указан параметр data. Параметр data должен быть буфером в стандартном формате application/x-www-form-urlencoded.
Функция urllib.parse.urlencode() принимает отображение или последовательность кортежей из двух элементов и возвращает строку в этом формате. Её следует закодировать в байты перед использованием в качестве параметра data. Параметр charset в заголовке Content-Type может использоваться для указания кодировки. Если параметр charset не передан с заголовком Content-Type, сервер, следуя рекомендации HTTP 1.1, может предположить, что данные закодированы в ISO-8859-1. Рекомендуется использовать параметр charset с кодировкой, указанной в заголовке Content-Type, совместно с Request.
headers должен быть словарём, и он будет обрабатываться так, как если бы для каждой пары ключ-значение была вызвана 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).
Пример использования заголовка Content-Type с аргументом data – отправка словаря вида {"Content-Type":" application/x-www-form-urlencoded;charset=utf-8"}
Последние два аргумента представляют интерес только для корректной обработки сторонних HTTP-куки:
origin_req_host должен быть хостом запроса исходной транзакции, как определено в RFC 2965. По умолчанию http.cookiejar.request_host(self). Это имя хоста или IP-адрес исходного запроса, инициированного пользователем. Например, если запрос предназначен для изображения в HTML-документе, здесь должен быть хост запроса страницы, содержащей изображение.
unverifiable должен указывать, является ли запрос непроверяемым (unverifiable), как определено в RFC 2965. По умолчанию False. Непроверяемый запрос – это запрос, URL которого пользователь не имел возможности подтвердить. Например, если запрос предназначен для изображения в HTML-документе, и у пользователя не было возможности подтвердить автоматическую загрузку изображения, это должно быть true.
Параметр method должен быть строкой, указывающей метод HTTP-запроса, который будет использоваться (например, 'HEAD'). Его значение хранится в атрибуте method и используется методом get_method().
Изменено в версии 3.3: добавлен аргумент Request.method в класс Request.
- class urllib.request.OpenerDirector¶
Класс OpenerDirector открывает URL-адреса через цепочку обработчиков BaseHandler. Он управляет объединением обработчиков в цепочку и восстановлением после ошибок.
- class urllib.request.BaseHandler¶
Это базовый класс для всех зарегистрированных обработчиков – он отвечает только за простую механику регистрации.
- class urllib.request.HTTPDefaultErrorHandler¶
Класс, определяющий обработчик по умолчанию для HTTP-ответов с ошибками; все ответы преобразуются в исключения HTTPError.
- class urllib.request.HTTPRedirectHandler¶
Класс для обработки перенаправлений.
- class urllib.request.HTTPCookieProcessor(cookiejar=None)¶
Класс для обработки HTTP-куки.
- class urllib.request.ProxyHandler(proxies=None)¶
Заставляет запросы проходить через прокси. Если указан proxies, это должен быть словарь, сопоставляющий имена протоколов с URL-адресами прокси. По умолчанию список прокси читается из переменных окружения <протокол>_proxy. Если переменные окружения прокси не заданы, то в среде Windows настройки прокси берутся из раздела Internet Settings реестра, а в среде Mac OS X информация о прокси извлекается из OS X System Configuration Framework.
Чтобы отключить автоматически обнаруженный прокси, передайте пустой словарь.
Примечание
HTTP_PROXY будет игнорироваться, если установлена переменная REQUEST_METHOD; см. документацию по getproxies().
- class urllib.request.HTTPPasswordMgr¶
Ведёт базу данных соответствий между (realm, uri) -> и (user, password).
- class urllib.request.HTTPPasswordMgrWithDefaultRealm¶
Ведёт базу данных соответствий между (realm, uri) -> и (user, password). Область (realm) со значением None считается универсальной – она используется, если не подходит ни одна другая.
- class urllib.request.AbstractBasicAuthHandler(password_mgr=None)¶
Это миксин-класс, который помогает с HTTP-аутентификацией как на удалённом хосте, так и на прокси. password_mgr, если задан, должен быть совместим с HTTPPasswordMgr; информацию об интерфейсе, который должен поддерживаться, см. в разделе HTTPPasswordMgr Objects.
- class urllib.request.HTTPBasicAuthHandler(password_mgr=None)¶
Обрабатывает аутентификацию на удалённом хосте. password_mgr, если указан, должен быть совместим с HTTPPasswordMgr; информацию об интерфейсе, который необходимо поддерживать, см. в разделе HTTPPasswordMgr Objects. HTTPBasicAuthHandler вызовет исключение ValueError при неправильной схеме аутентификации.
- class urllib.request.ProxyBasicAuthHandler(password_mgr=None)¶
Обрабатывает аутентификацию с прокси. password_mgr, если задан, должен быть совместим с HTTPPasswordMgr; информацию об интерфейсе, который должен поддерживаться, см. в разделе HTTPPasswordMgr Objects.
- class urllib.request.AbstractDigestAuthHandler(password_mgr=None)¶
Это миксин-класс, который помогает с HTTP-аутентификацией как на удалённом хосте, так и на прокси. password_mgr, если задан, должен быть совместим с HTTPPasswordMgr; информацию об интерфейсе, который должен поддерживаться, см. в разделе HTTPPasswordMgr Objects.
- class urllib.request.HTTPDigestAuthHandler(password_mgr=None)¶
Обрабатывает аутентификацию с удалённым хостом. password_mgr, если задан, должен быть совместим с HTTPPasswordMgr; информацию об интерфейсе, который должен поддерживаться, см. в разделе HTTPPasswordMgr Objects. Когда добавлены и обработчик дайджест-аутентификации, и обработчик базовой аутентификации, дайджест-аутентификация всегда выполняется первой. Если дайджест-аутентификация снова возвращает ответ 40x, он передаётся обработчику базовой аутентификации. Этот метод-обработчик возбуждает исключение ValueError при получении схемы аутентификации, отличной от Digest или Basic.
Изменено в версии 3.3: Возбуждает ValueError при неподдерживаемой схеме аутентификации.
- class urllib.request.ProxyDigestAuthHandler(password_mgr=None)¶
Обрабатывает аутентификацию с прокси. password_mgr, если задан, должен быть совместим с HTTPPasswordMgr; информацию об интерфейсе, который должен поддерживаться, см. в разделе HTTPPasswordMgr Objects.
- class urllib.request.HTTPHandler¶
Класс для открытия HTTP-URL.
- class urllib.request.HTTPSHandler(debuglevel=0, context=None, check_hostname=None)¶
Класс для открытия HTTPS-URL. context и check_hostname имеют тот же смысл, что и в http.client.HTTPSConnection.
Изменено в версии 3.2: Добавлены параметры context и check_hostname.
- class urllib.request.FileHandler¶
Открывает локальные файлы.
- class urllib.request.FTPHandler¶
Открывает FTP-URL.
- class urllib.request.CacheFTPHandler¶
Открывает FTP-URL, сохраняя кеш открытых FTP-соединений для минимизации задержек.
- class urllib.request.UnknownHandler¶
Универсальный класс для обработки неизвестных URL.
- class urllib.request.HTTPErrorProcessor¶
Обрабатывает ошибочные HTTP-ответы.
21.6.1. Объекты запросов¶Request Objects
Следующие методы описывают открытый интерфейс Request, и все они могут быть переопределены в подклассах. Он также определяет несколько открытых атрибутов, которые могут использоваться клиентами для анализа разобранного запроса.
- Request.full_url¶
Оригинальный URL, переданный конструктору.
- Request.type¶
Схема URI.
- Request.host¶
Авторитетная часть URI, обычно хост, но может также содержать порт, отделённый двоеточием.
- Request.origin_req_host¶
Исходный хост запроса, без порта.
- Request.selector¶
Путь URI. Если Request использует прокси, то selector будет полным URL, который передаётся прокси.
- Request.data¶
Тело запроса (entity body) или None, если не указано.
- Request.unverifiable¶
логическое значение, указывает, является ли запрос непроверяемым, как определено в RFC 2965.
- Request.method¶
HTTP-метод запроса, который следует использовать. Это значение используется get_method() для переопределения вычисленного HTTP-метода запроса, который в противном случае был бы возвращён. Этот атрибут инициализируется значением аргумента method, переданного конструктору.
Новое в версии 3.3.
- Request.get_method()¶
Возвращает строку, указывающую метод HTTP-запроса. Если Request.method не равен None, возвращает его значение; в противном случае возвращает 'GET', если Request.data равно None, или 'POST' в противном случае. Это имеет смысл только для HTTP-запросов.
Изменено в версии 3.3: get_method теперь проверяет значение Request.method.
- Request.add_header(key, val)¶
Добавляет ещё один заголовок к запросу. В настоящее время заголовки игнорируются всеми обработчиками, кроме HTTP-обработчиков, где они добавляются в список заголовков, отправляемых серверу. Обратите внимание, что не может быть более одного заголовка с одним и тем же именем, и последующие вызовы перезапишут предыдущие в случае совпадения ключа. В настоящее время это не приводит к потере функциональности HTTP, поскольку все заголовки, имеющие смысл при многократном использовании, имеют (специфичный для заголовка) способ достижения той же функциональности с помощью только одного заголовка.
- Request.add_unredirected_header(key, header)¶
Добавляет заголовок, который не будет добавлен в перенаправленный запрос.
- Request.has_header(header)¶
Возвращает, имеет ли экземпляр указанный заголовок (проверяет как обычные, так и неперенаправленные).
- Request.get_full_url()¶
Возвращает URL, переданный в конструктор.
- Request.set_proxy(host, type)¶
Подготавливает запрос, подключаясь к прокси-серверу. host и type заменят соответствующие значения экземпляра, а selector экземпляра будет содержать исходный URL, переданный в конструктор.
- Request.add_data(data)¶
Устанавливает данные Request в data. Все обработчики, кроме HTTP, игнорируют этот атрибут; для HTTP он должен быть байтовой строкой и изменит запрос, сделав его POST, а не GET. Устарело в версии 3.3, используйте Request.data.
Устарело с версии 3.3, будет удалено в версии 3.4.
- Request.has_data()¶
Возвращает, имеет ли экземпляр данные, отличные от None. Устарело в версии 3.3, используйте Request.data.
Устарело с версии 3.3, будет удалено в версии 3.4.
- Request.get_data()¶
Возвращает данные экземпляра. Устарело в версии 3.3, используйте Request.data.
Устарело с версии 3.3, будет удалено в версии 3.4.
- Request.get_type()¶
Возвращает тип URL – также известный как схема. Устарело в версии 3.3, используйте Request.type.
Устарело с версии 3.3, будет удалено в версии 3.4.
- Request.get_host()¶
Возвращает хост, к которому будет установлено соединение. Устарело в 3.3, используйте Request.host.
Устарело с версии 3.3, будет удалено в версии 3.4.
- Request.get_selector()¶
Возвращает селектор – часть URL, которая отправляется серверу. Устарело в 3.3, используйте Request.selector.
Устарело с версии 3.3, будет удалено в версии 3.4.
- Request.get_header(header_name, default=None)¶
Возвращает значение указанного заголовка. Если заголовок отсутствует, возвращает значение по умолчанию.
- Request.header_items()¶
Возвращает список кортежей (имя_заголовка, значение_заголовка) заголовков запроса.
- Request.set_proxy(host, type)
- Request.get_origin_req_host()¶
Возвращает хост запроса исходной транзакции, как определено в RFC 2965. См. документацию конструктора Request. Устарело в 3.3, используйте Request.origin_req_host.
Устарело с версии 3.3, будет удалено в версии 3.4.
- Request.is_unverifiable()¶
Возвращает, является ли запрос непроверяемым, как определено в RFC 2965. См. документацию конструктора Request. Устарело в 3.3, используйте Request.unverifiable.
Устарело с версии 3.3, будет удалено в версии 3.4.
21.6.2. Объекты OpenerDirector¶OpenerDirector Objects
OpenerDirector имеет следующие методы:
- OpenerDirector.add_handler(handler)¶
handler должен быть экземпляром BaseHandler. Ищутся и добавляются в возможные цепочки следующие методы (обратите внимание, что ошибки HTTP являются особым случаем).
- protocol_open() – сигнал о том, что обработчик умеет открывать URL-адреса протокол.
- http_error_type() – сигнал о том, что обработчик умеет обрабатывать ошибки HTTP с кодом ошибки HTTP type.
- protocol_error() – сигнал о том, что обработчик умеет обрабатывать ошибки от протокола протокол (кроме http).
- protocol_request() – сигнал о том, что обработчик умеет предварительно обрабатывать запросы протокол.
- protocol_response() – сигнал о том, что обработчик умеет выполнять последующую обработку ответов протокол.
- OpenerDirector.open(url, data=None[, timeout])¶
Открывает указанный url (может быть объектом запроса или строкой), необязательно передавая указанные data. Аргументы, возвращаемые значения и исключения такие же, как у urlopen() (которая просто вызывает метод open() у текущего установленного глобального OpenerDirector). Необязательный параметр timeout задает тайм-аут в секундах для блокирующих операций, таких как попытка соединения (если не указан, используется глобальный тайм-аут по умолчанию). Тайм-аут работает только для соединений HTTP, HTTPS и FTP).
- OpenerDirector.error(proto, *args)¶
Обрабатывает ошибку указанного протокола. Вызывает зарегистрированные обработчики ошибок для данного протокола с указанными аргументами (которые зависят от протокола). Протокол HTTP является особым случаем, использующим код ответа HTTP для определения конкретного обработчика ошибок; обратитесь к методам http_error_*() классов обработчиков.
Возвращаемые значения и исключения такие же, как у urlopen().
Объекты OpenerDirector открывают URL в три этапа:
Порядок вызова этих методов в каждом этапе определяется сортировкой экземпляров обработчиков.
У каждого обработчика, имеющего метод с именем вида protocol_request(), этот метод вызывается для предварительной обработки запроса.
Обработчики с методом вида protocol_open() вызываются для обработки запроса. Этот этап завершается, когда обработчик возвращает значение, отличное от None (т.е. ответ), или возбуждает исключение (обычно URLError). Исключения могут распространяться.
На самом деле описанный алгоритм сначала применяется к методам с именем default_open(). Если все такие методы возвращают None, алгоритм повторяется для методов с именем вида protocol_open(). Если все такие методы возвращают None, алгоритм повторяется для методов с именем unknown_open().
Обратите внимание, что реализация этих методов может включать вызовы методов open() и error() родительского экземпляра OpenerDirector.
У каждого обработчика, имеющего метод с именем вида protocol_response(), этот метод вызывается для последующей обработки ответа.
21.6.3. Объекты BaseHandler¶BaseHandler Objects
Объекты BaseHandler предоставляют несколько методов, которые полезны непосредственно, и другие, предназначенные для использования производными классами. Следующие предназначены для прямого использования:
- BaseHandler.add_parent(director)¶
Добавляет директор в качестве родителя.
- BaseHandler.close()¶
Удаляет всех родителей.
Следующий атрибут и методы должны использоваться только классами, производными от BaseHandler.
Примечание
Принято соглашение: подклассы, определяющие методы protocol_request() или protocol_response(), называются *Processor; все остальные называются *Handler.
- BaseHandler.parent¶
Действительный объект OpenerDirector, который можно использовать для открытия с помощью другого протокола или для обработки ошибок.
- BaseHandler.default_open(req)¶
Этот метод не определён в BaseHandler, но подклассы должны определить его, если хотят перехватывать все URL.
Этот метод, если он реализован, вызывается родительским OpenerDirector. Он должен возвращать файлоподобный объект, как описано в возвращаемом значении метода open() объекта OpenerDirector, или None. Он должен возбуждать URLError, если только не происходит поистине исключительная ситуация (например, MemoryError не должен отображаться на URLError).
Этот метод будет вызван перед любым методом открытия, специфичным для протокола.
- BaseHandler.protocol_open(req)
Этот метод не определён в BaseHandler, но подклассы должны определить его, если хотят обрабатывать URL с указанным протоколом.
Этот метод, если он определён, вызывается родительским OpenerDirector. Возвращаемые значения должны быть такими же, как для default_open().
- BaseHandler.unknown_open(req)¶
Этот метод не определён в BaseHandler, но подклассы должны определить его, если хотят перехватывать все URL, для открытия которых нет зарегистрированного конкретного обработчика.
Этот метод, если он реализован, вызывается родительским родительский OpenerDirector. Возвращаемые значения должны быть такими же, как и для default_open().
- BaseHandler.http_error_default(req, fp, code, msg, hdrs)¶
Этот метод не определён в BaseHandler, но подклассы должны переопределить его, если намерены предоставить универсальный обработчик для всех прочих необработанных HTTP-ошибок. Он будет автоматически вызван OpenerDirector при получении ошибки и обычно не должен вызываться в других обстоятельствах.
req будет объектом Request, fp – файлоподобным объектом с телом HTTP-ошибки, code – трёхзначным кодом ошибки, msg – понятным пользователю пояснением кода, а hdrs – объектом-отображением с заголовками ошибки.
Возвращаемые значения и возбуждаемые исключения должны быть такими же, как у urlopen().
- BaseHandler.http_error_nnn(req, fp, code, msg, hdrs)¶
nnn должен быть трёхзначным кодом HTTP-ошибки. Этот метод также не определён в BaseHandler, но будет вызван, если он существует, на экземпляре подкласса при возникновении HTTP-ошибки с кодом nnn.
Подклассы должны переопределить этот метод для обработки конкретных HTTP-ошибок.
Аргументы, возвращаемые значения и возбуждаемые исключения должны быть такими же, как и для http_error_default().
- BaseHandler.protocol_request(req)
Этот метод не определён в BaseHandler, но подклассы должны определить его, если хотят предварительно обрабатывать запросы указанного протокола.
Этот метод, если он определён, вызывается родительским OpenerDirector. req будет объектом Request. Возвращаемое значение должно быть объектом Request.
- BaseHandler.protocol_response(req, response)
Этот метод не определён в BaseHandler, но подклассы должны определить его, если хотят выполнять последующую обработку ответов указанного протокола.
Этот метод, если он определён, вызывается родительским OpenerDirector. req будет объектом Request. response будет объектом, реализующим тот же интерфейс, что и возвращаемое значение urlopen(). Возвращаемое значение должно реализовывать тот же интерфейс, что и возвращаемое значение urlopen().
21.6.4. Объекты HTTPRedirectHandler¶HTTPRedirectHandler Objects
Примечание
Некоторые HTTP-перенаправления требуют действий от клиентского кода этого модуля. В таком случае возбуждается HTTPError. См. RFC 2616 для получения подробной информации о точном значении различных кодов перенаправления.
Исключение HTTPError возбуждается из соображений безопасности, если HTTPRedirectHandler получает перенаправленный URL, который не является HTTP, HTTPS или FTP URL.
- HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)¶
Возвращает Request или None в ответ на перенаправление. Этот метод вызывается реализациями по умолчанию методов http_error_30*(), когда от сервера получено перенаправление. Если необходимо выполнить перенаправление, верните новый Request, чтобы дать возможность http_error_30*() выполнить перенаправление на newurl. В противном случае возбудите HTTPError, если ни один другой обработчик не должен пытаться обработать этот URL, или верните None, если вы не можете этого сделать, но другой обработчик может.
Примечание
Реализация этого метода по умолчанию не строго следует RFC 2616, в котором сказано, что ответы с кодами 301 и 302 на POST запросы не должны автоматически перенаправляться без подтверждения пользователем. На практике браузеры разрешают автоматическое перенаправление этих ответов, заменяя POST на GET, и реализация по умолчанию воспроизводит такое поведение.
- HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)¶
Перенаправляет на URL из заголовков Location: или URI:. Этот метод вызывается родительским OpenerDirector при получении HTTP-ответа «перемещён навсегда».
- HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)¶
То же, что и http_error_301(), но вызывается для ответа «found».
- HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)¶
То же, что и http_error_301(), но вызывается для ответа «see other».
- HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)¶
То же, что и http_error_301(), но вызывается для ответа «temporary redirect».
21.6.5. Объекты HTTPCookieProcessor¶HTTPCookieProcessor Objects
Экземпляры HTTPCookieProcessor имеют один атрибут:
Объект http.cookiejar.CookieJar, в котором хранятся куки.
21.6.6. Объекты ProxyHandler¶ProxyHandler Objects
- ProxyHandler.protocol_open(request)
Для каждого протокола, для которого в словаре proxies, переданном в конструктор, указан прокси, объект ProxyHandler будет иметь метод protocol_open(). Этот метод изменяет запрос для направления через прокси, вызывая request.set_proxy(), и передаёт управление следующему обработчику в цепочке для фактического выполнения протокола.
21.6.7. Объекты HTTPPasswordMgr¶HTTPPasswordMgr Objects
Эти методы доступны для объектов HTTPPasswordMgr и HTTPPasswordMgrWithDefaultRealm.
- HTTPPasswordMgr.add_password(realm, uri, user, passwd)¶
uri может быть как одним URI, так и последовательностью URI. realm, user и passwd должны быть строками. В результате (user, passwd) будет использоваться в качестве токенов аутентификации при запросе аутентификации для realm и супер-URI любого из указанных URI.
- HTTPPasswordMgr.find_user_password(realm, authuri)¶
Возвращает пару пользователь/пароль для указанных realm и URI, если они есть. Если совпадений нет, этот метод вернёт (None, None).
Для объектов HTTPPasswordMgrWithDefaultRealm, если для указанного realm нет подходящей пары пользователь/пароль, будет выполнен поиск по realm None.
21.6.8. Объекты AbstractBasicAuthHandler¶AbstractBasicAuthHandler Objects
- AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)¶
Обрабатывает запрос аутентификации, получая пару пользователь/пароль и повторяя запрос. authreq должно быть именем заголовка, в котором содержится информация о realm, host указывает URL и путь для аутентификации, req должен быть (неудачным) объектом Request, а headers – заголовками ошибки.
host – это либо полномочное имя (например, "python.org"), либо URL, содержащий компонент полномочного имени (например, "http://python.org/"). В любом случае полномочное имя не должно содержать компонента userinfo (так что "python.org" и "python.org:80" допустимы, а "joe:password@python.org" – нет).
21.6.9. Объекты HTTPBasicAuthHandler¶HTTPBasicAuthHandler Objects
- HTTPBasicAuthHandler.http_error_401(req, fp, code, msg, hdrs)¶
Повторяет запрос с информацией аутентификации, если она доступна.
21.6.10. Объекты ProxyBasicAuthHandler¶ProxyBasicAuthHandler Objects
- ProxyBasicAuthHandler.http_error_407(req, fp, code, msg, hdrs)¶
Повторяет запрос с информацией аутентификации, если она доступна.
21.6.11. Объекты AbstractDigestAuthHandler¶AbstractDigestAuthHandler Objects
21.6.12. Объекты HTTPDigestAuthHandler¶HTTPDigestAuthHandler Objects
- HTTPDigestAuthHandler.http_error_401(req, fp, code, msg, hdrs)¶
Повторяет запрос с информацией аутентификации, если она доступна.
21.6.13. Объекты ProxyDigestAuthHandler¶ProxyDigestAuthHandler Objects
- ProxyDigestAuthHandler.http_error_407(req, fp, code, msg, hdrs)¶
Повторяет запрос с информацией аутентификации, если она доступна.
21.6.14. Объекты HTTPHandler¶HTTPHandler Objects
- HTTPHandler.http_open(req)¶
Отправляет HTTP-запрос, который может быть GET или POST, в зависимости от req.has_data().
21.6.15. Объекты HTTPSHandler¶HTTPSHandler Objects
- HTTPSHandler.https_open(req)¶
Отправляет HTTPS-запрос, который может быть GET или POST, в зависимости от req.has_data().
21.6.16. Объекты FileHandler¶FileHandler Objects
21.6.17. Объекты FTPHandler¶FTPHandler Objects
- FTPHandler.ftp_open(req)¶
Открывает FTP-файл, указанный req. Вход всегда выполняется с пустыми именем пользователя и паролем.
21.6.18. Объекты CacheFTPHandler¶CacheFTPHandler Objects
Объекты CacheFTPHandler являются объектами FTPHandler с дополнительными методами:
- CacheFTPHandler.setTimeout(t)¶
Устанавливает тайм-аут соединений равным t секунд.
- CacheFTPHandler.setMaxConns(m)¶
Устанавливает максимальное количество кэшированных соединений равным m.
21.6.19. Объекты UnknownHandler¶UnknownHandler Objects
21.6.20. Объекты HTTPErrorProcessor¶HTTPErrorProcessor Objects
- HTTPErrorProcessor.http_response()¶
Обрабатывает ошибочные HTTP-ответы.
Для кода 200 объект ответа возвращается немедленно.
Для кодов ошибок, отличных от 200, он просто передаёт задачу методам-обработчикам protocol_error_code() через OpenerDirector.error(). В конечном итоге HTTPDefaultErrorHandler вызовет исключение HTTPError, если ни один другой обработчик не обработает ошибку.
- HTTPErrorProcessor.https_response()¶
Обрабатывает ошибочные HTTPS-ответы.
Поведение такое же, как у http_response().
21.6.21. Примеры¶Examples
Этот пример получает главную страницу python.org и отображает первые 300 байт этой страницы.
>>> import urllib.request
>>> f = urllib.request.urlopen('http://www.python.org/')
>>> print(f.read(300))
b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html
xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\n<head>\n
<meta http-equiv="content-type" content="text/html; charset=utf-8" />\n
<title>Python Programming '
Обратите внимание, что urlopen возвращает объект bytes. Это связано с тем, что urlopen не может автоматически определить кодировку байтового потока, получаемого от HTTP-сервера. В общем случае программа декодирует возвращаемый объект bytes в строку после того, как определит или угадает подходящую кодировку.
Следующий документ W3C, http://www.w3.org/International/O-charset, перечисляет различные способы, которыми (X)HTML- или XML-документ может указывать информацию о своей кодировке.
Поскольку на сайте python.org используется кодировка utf-8, указанная в его мета-теге, мы будем использовать ту же самую для декодирования объекта bytes.
>>> with urllib.request.urlopen('http://www.python.org/') as f:
... print(f.read(100).decode('utf-8'))
...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtm
Тот же результат можно получить и без использования менеджера контекста подхода.
>>> import urllib.request
>>> f = urllib.request.urlopen('http://www.python.org/')
>>> print(f.read(100).decode('utf-8'))
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtm
В следующем примере мы отправляем поток данных на стандартный ввод CGI и читаем данные, которые он возвращает. Обратите внимание: этот пример будет работать только в том случае, если установка Python поддерживает SSL.
>>> import urllib.request
>>> req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi',
... data=b'This data is passed to stdin of the CGI')
>>> f = urllib.request.urlopen(req)
>>> print(f.read().decode('utf-8'))
Got Data: "This data is passed to stdin of the CGI"
Код образца CGI, использованного в приведённом выше примере:
#!/usr/bin/env python
import sys
data = sys.stdin.read()
print('Content-type: text-plain\n\nGot Data: "%s"' % data)
Вот пример выполнения запроса PUT с использованием Request:
import urllib.request
DATA=b'some data'
req = urllib.request.Request(url='http://localhost:8080', data=DATA,method='PUT')
f = urllib.request.urlopen(req)
print(f.status)
print(f.reason)
Использование базовой HTTP-аутентификации:
import urllib.request
# Создать OpenerDirector с поддержкой базовой HTTP-аутентификации...
auth_handler = urllib.request.HTTPBasicAuthHandler()
auth_handler.add_password(realm='PDQ Application',
uri='https://mahler:8092/site-updates.py',
user='klem',
passwd='kadidd!ehopper')
opener = urllib.request.build_opener(auth_handler)
# ...и установить его глобально, чтобы его можно было использовать с urlopen.
urllib.request.install_opener(opener)
urllib.request.urlopen('http://www.example.com/login.html')
build_opener() по умолчанию предоставляет множество обработчиков, включая ProxyHandler. По умолчанию ProxyHandler использует переменные окружения с именами вида <scheme>_proxy, где <scheme> – это соответствующая схема URL. Например, переменная окружения http_proxy считывается для получения URL HTTP-прокси.
В этом примере стандартный ProxyHandler заменяется на тот, который использует программно задаваемые URL прокси, и добавляется поддержка авторизации прокси с помощью ProxyBasicAuthHandler.
proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})
proxy_auth_handler = urllib.request.ProxyBasicAuthHandler()
proxy_auth_handler.add_password('realm', 'host', 'username', 'password')
opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler)
# На этот раз, вместо установки OpenerDirector, используется напрямую:
opener.open('http://www.example.com/login.html')
Добавление HTTP-заголовков:
Используйте аргумент headers конструктора Request или:
import urllib.request
req = urllib.request.Request('http://www.example.com/')
req.add_header('Referer', 'http://www.python.org/')
r = urllib.request.urlopen(req)
OpenerDirector автоматически добавляет заголовок User-Agent к каждому Request. Чтобы изменить это:
import urllib.request
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
opener.open('http://www.example.com/')
Также следует помнить, что несколько стандартных заголовков (Content-Length, Content-Type без параметра charset и Host) добавляются, когда Request передаётся в urlopen() (или OpenerDirector.open()).
Ниже приведён пример сеанса, в котором используется метод GET для получения URL, содержащего параметры:
>>> import urllib.request
>>> import urllib.parse
>>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
>>> print(f.read().decode('utf-8'))
В следующем примере вместо этого используется метод POST. Обратите внимание, что вывод params из urlencode кодируется в байты перед отправкой в urlopen в качестве data:
>>> import urllib.request
>>> import urllib.parse
>>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> data = data.encode('utf-8')
>>> request = urllib.request.Request("http://requestb.in/xrbl82xr")
>>> # добавление параметра charset в заголовок Content‑Type.
>>> request.add_header("Content-Type","application/x-www-form-urlencoded;charset=utf-8")
>>> f = urllib.request.urlopen(request, data)
>>> print(f.read().decode('utf-8'))
В следующем примере используется явно указанный HTTP-прокси, переопределяющий настройки окружения:
>>> import urllib.request
>>> proxies = {'http': 'http://proxy.example.com:8080/'}
>>> opener = urllib.request.FancyURLopener(proxies)
>>> f = opener.open("http://www.python.org")
>>> f.read().decode('utf-8')
В следующем примере прокси не используются вовсе, переопределяя настройки окружения:
>>> import urllib.request
>>> opener = urllib.request.FancyURLopener({})
>>> f = opener.open("http://www.python.org/")
>>> f.read().decode('utf-8')
21.6.22. Устаревший интерфейс¶Legacy interface
Следующие функции и классы перенесены из модуля Python 2 urllib (в отличие от urllib2). В будущем они могут стать устаревшими.
- urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)¶
Копирует сетевой объект, заданный URL, в локальный файл. Если URL указывает на локальный файл, объект не будет скопирован, если не указан filename. Возвращает кортеж (filename, headers), где filename – это имя локального файла, в котором находится объект, а headers – это то, что вернул метод info() объекта, возвращённого urlopen() (для удалённого объекта). Исключения те же, что и для urlopen().
Второй аргумент, если он задан, указывает, в какой файл копировать данные (если отсутствует, данные будут записаны во временный файл с автоматически сгенерированным именем). Третий аргумент, если он задан, – это функция-обработчик, которая будет вызвана один раз при установке сетевого соединения и затем после каждого прочитанного блока. Функция будет получать три аргумента: количество переданных блоков, размер блока в байтах и общий размер файла. Третий аргумент может быть -1 на старых FTP-серверах, которые не возвращают размер файла в ответ на запрос получения.
Следующий пример иллюстрирует наиболее распространённый сценарий использования:
>>> import urllib.request >>> local_filename, headers = urllib.request.urlretrieve('http://python.org/') >>> html = open(local_filename) >>> html.close()
Если в url используется идентификатор схемы http:, необязательный аргумент data может быть задан для указания запроса POST (обычно тип запроса – GET). Аргумент data должен быть объектом bytes в стандартном формате application/x-www-form-urlencoded; см. функцию urllib.parse.urlencode().
urlretrieve() вызовет исключение ContentTooShortError, если обнаружит, что объём доступных данных меньше ожидаемого (то есть размера, указанного в заголовке Content-Length). Это может произойти, например, если загрузка была прервана.
Заголовок Content-Length рассматривается как нижняя граница: если доступно больше данных для чтения, urlretrieve читает больше данных, но если данных меньше, он вызывает исключение.
В этом случае загруженные данные всё ещё можно получить, они хранятся в атрибуте content экземпляра исключения.
Если заголовок Content-Length не был передан, urlretrieve не может проверить размер загруженных данных и просто возвращает их. В этом случае остаётся только предполагать, что загрузка прошла успешно.
- urllib.request.urlcleanup()¶
Удаляет временные файлы, которые могли остаться после предыдущих вызовов urlretrieve().
- class urllib.request.URLopener(proxies=None, **x509)¶
Устарело с версии 3.3.
Базовый класс для открытия и чтения URL. Если не требуется поддержка открытия объектов с использованием схем, отличных от http:, ftp: или file:, вероятно, стоит использовать FancyURLopener.
По умолчанию класс URLopener отправляет заголовок User-Agent со значением urllib/VVV, где VVV – это номер версии urllib. Приложения могут определить собственный заголовок User-Agent, создав подкласс URLopener или FancyURLopener и установив атрибут класса version в соответствующее строковое значение в определении подкласса.
Необязательный параметр proxies должен быть словарём, сопоставляющим имена схем с URL прокси, причём пустой словарь полностью отключает прокси. По умолчанию значение равно None; в этом случае будут использованы настройки прокси из окружения, если они присутствуют, как описано в определении urlopen() выше.
Дополнительные именованные параметры, собранные в x509, могут использоваться для аутентификации клиента при использовании схемы https:. Поддерживаются ключи key_file и cert_file для предоставления SSL-ключа и сертификата; оба необходимы для поддержки аутентификации клиента.
Объекты URLopener вызывают исключение OSError, если сервер возвращает код ошибки.
- open(fullurl, data=None)¶
Открывает fullurl, используя соответствующий протокол. Этот метод настраивает кеш и информацию о прокси, затем вызывает соответствующий метод open с его входными аргументами. Если схема не распознана, вызывается open_unknown(). Аргумент data имеет тот же смысл, что и аргумент data функции urlopen().
- open_unknown(fullurl, data=None)¶
Переопределяемый интерфейс для открытия неизвестных типов URL.
- retrieve(url, filename=None, reporthook=None, data=None)¶
Извлекает содержимое url и помещает его в filename. Возвращаемое значение – кортеж, состоящий из локального имени файла и либо объекта email.message.Message, содержащего заголовки ответа (для удалённых URL), либо None (для локальных URL). Затем вызывающий код должен открыть и прочитать содержимое filename. Если filename не указан и URL ссылается на локальный файл, возвращается исходное имя файла. Если URL не локальный и filename не указан, имя файла – результат вызова tempfile.mktemp() с суффиксом, совпадающим с суффиксом последнего компонента пути входного URL. Если задан reporthook, он должен быть функцией, принимающей три числовых параметра: номер блока, максимальный размер, которым читаются блоки, и общий размер загрузки (-1, если неизвестен). Она будет вызвана один раз в начале и после каждого считанного из сети блока данных. reporthook игнорируется для локальных URL.
Если в url используется идентификатор схемы http:, необязательный аргумент data может быть задан для указания запроса POST (обычно тип запроса – GET). Аргумент data должен быть в стандартном формате application/x-www-form-urlencoded; см. функцию urllib.parse.urlencode().
- class urllib.request.FancyURLopener(...)¶
Устарело с версии 3.3.
FancyURLopener является подклассом URLopener, предоставляющим стандартную обработку следующих кодов ответа HTTP: 301, 302, 303, 307 и 401. Для перечисленных выше кодов 30x заголовок Location используется для получения фактического URL. Для кода 401 (требуется аутентификация) выполняется базовая HTTP-аутентификация. Для кодов 30x рекурсия ограничена значением атрибута maxtries, по умолчанию равным 10.
Для всех остальных кодов ответа вызывается метод http_error_default(), который можно переопределить в подклассах для соответствующей обработки ошибки.
Примечание
Согласно букве RFC 2616, ответы 301 и 302 на POST-запросы не должны автоматически перенаправляться без подтверждения пользователем. На деле браузеры допускают автоматическое перенаправление этих ответов, изменяя POST на GET, и urllib воспроизводит такое поведение.
Параметры конструктора такие же, как и для URLopener.
Примечание
При выполнении базовой аутентификации экземпляр FancyURLopener вызывает свой метод prompt_user_passwd(). Реализация по умолчанию запрашивает у пользователя необходимые сведения на управляющем терминале. При необходимости подкласс может переопределить этот метод, чтобы обеспечить более подходящее поведение.
Класс FancyURLopener предоставляет один дополнительный метод, который следует переопределить для обеспечения соответствующего поведения:
- prompt_user_passwd(host, realm)¶
Возвращает информацию, необходимую для аутентификации пользователя на указанном хосте в заданной области безопасности. Возвращаемое значение должно быть кортежем, (user, password), который можно использовать для базовой аутентификации.
Реализация запрашивает эту информацию на терминале; приложение должно переопределить этот метод, чтобы использовать подходящую модель взаимодействия в локальной среде.
21.6.23. urllib.request Ограничения¶urllib.request Restrictions
В настоящее время поддерживаются только следующие протоколы: HTTP (версии 0.9 и 1.0), FTP и локальные файлы.
Функция кэширования urlretrieve() отключена до тех пор, пока кто-нибудь не найдет время реализовать правильную обработку заголовков с временем истечения.
Должна быть функция для проверки, находится ли определённый URL в кэше.
Для обратной совместимости, если URL указывает на локальный файл, но файл не удаётся открыть, URL интерпретируется заново с использованием протокола FTP. Это иногда может приводить к запутанным сообщениям об ошибках.
Функции urlopen() и urlretrieve() могут вызывать сколь угодно долгие задержки при ожидании установки сетевого соединения. Это означает, что создать интерактивный веб-клиент с помощью этих функций без использования потоков сложно.
Данные, возвращаемые urlopen() или urlretrieve(), представляют собой необработанные данные, возвращаемые сервером. Это могут быть бинарные данные (например, изображение), обычный текст или, скажем, HTML. Протокол HTTP предоставляет информацию о типе в заголовке ответа, которую можно узнать, посмотрев на заголовок Content-Type. Если возвращаемые данные являются HTML, можно использовать модуль html.parser для его разбора.
Код, работающий с протоколом FTP, не может различить файл и каталог. Это может привести к неожиданному поведению при попытке чтения URL, указывающего на недоступный файл. Если URL заканчивается на /, считается, что он ссылается на каталог, и обработка будет соответствующей. Но если попытка чтения файла приводит к ошибке 550 (означающей, что URL не найден или недоступен, часто по причинам прав доступа), то путь обрабатывается как каталог, чтобы учесть случай, когда в URL указан каталог, но завершающий / опущен. Это может привести к вводящим в заблуждение результатам при попытке получить файл, права на чтение которого делают его недоступным; код FTP попытается его прочитать, получит ошибку 550, а затем выполнит листинг каталога для недоступного файла. Если требуется тонкий контроль, рассмотрите возможность использования модуля ftplib, создания подкласса FancyURLopener или изменения _urlopener в соответствии с вашими потребностями.
21.7. urllib.response – Классы ответов, используемые urllib¶urllib.response – Response classes used by urllib
Модуль urllib.response определяет функции и классы, которые задают минимальный файлоподобный интерфейс, включая read() и readline(). Типичный объект ответа – это экземпляр addinfourl, который определяет метод info(), возвращающий заголовки, и метод geturl(), возвращающий URL. Функции, определенные этим модулем, используются внутри модуля urllib.request.