import urllib.request req = urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
url
- действительный URL-адрес,data=None
- дополнительные данные для отправки на сервер POST-запросом,headers={}
- значения заголовков, передаваемые с запросом,origin_req_host=None
- хост запроса для cookies,unverifiable=False
- является ли запрос проверяемым,method=None
- метод HTTP-запроса (например, HEAD
, PUT
и т.д.)Класс Request()
модуля urllib.request
представляет собой абстракцию URL-запроса.
Аргумент url
должен быть строкой, содержащей действительный URL.
Аргумент data
должен быть объектом, определяющим дополнительные данные для отправки на сервер, или None
, если такие данные не нужны. Поддерживаемые типы объектов включают байты, файловые объекты и итерации байтовых объектов. Если поле заголовка Content-Length
или Transfer-Encoding
не предоставлено, то HTTPHandler
установит эти заголовки в соответствии с типом данных. Content-Length
будет использоваться для отправки байтовых объектов, в то время как Transfer-Encoding: chunked
, как указано в RFC 7230, будет использоваться для отправки файлов и других итераций.
Для метода HTTP POST запроса, данные должны быть буфером в стандартном формате application/x-www-form-urlencoded
. Функция urllib.parse.urlencode()
принимает отображение/словарь или последовательность двойных кортежей и возвращает строку ASCII в этом формате. Перед использованием в качестве аргумента data
он должен быть закодирован в байты.
Аргумент headers
должен быть словарем и будет обрабатываться так, как если бы метод Request.add_header()
был вызван с каждым ключом и значением в качестве аргументов. Данная функциональность часто используется для подделки значения заголовка User-Agent
, которое используется для идентификации браузера пользователя - некоторые HTTP-серверы разрешают только запросы, поступающие из обычных браузеров, а не скрипты. Строка пользовательского агента модуля urllib.request
по умолчанию идентифицирует себя как Python-urllib/3.9
, если используется Python 3.9.
Соответствующий заголовок Content-Type
должен быть включен, если присутствует аргумент data
. Если этот заголовок не был предоставлен и данные отличны от None, то по умолчанию будет добавлен заголовок Content-Type: application/x-www-form-urlencoded
.
Следующие два аргумента представляют интерес только для правильной обработки сторонних файлов cookie HTTP:
Аргумент origin_req_host
должен быть хостом запроса исходной транзакции, как определено RFC 2965. По умолчанию используется http.cookiejar.request_host(self)
. Это имя хоста или IP-адрес исходного запроса, инициированного пользователем. Например, если запрос относится к изображению в документе HTML, то это должен быть узел запроса для страницы, содержащей изображение.
Аргумент unverifiable
должен указывать, является ли запрос непроверяемым, как определено в RFC 2965. По умолчанию используется значение False
. Непроверяемый запрос - это запрос, URL-адрес которого пользователь не мог одобрить. Например, если запрос относится к скачиванию изображению в документе HTML, и у пользователя не было возможности одобрить автоматическое получение этого изображения, то аргумент unverifiable
должно быть True
.
Аргумент method
должен быть строкой, указывающей метод HTTP-запроса, который будет использоваться (например, HEAD
, PUT
и т.д.). Если аргумент указывается, то его значение сохраняется в атрибуте метода и используется Request.get_method()
. По умолчанию используется GET, если data=None
, или POST в противном случае. Подклассы могут указывать другой метод по умолчанию, устанавливая атрибут метода в самом классе.
Примечание. Запрос не будет работать должным образом, если объект данных data
не может доставить свое содержимое более одного раза (например, файл или итеративный объект, который может создавать содержимое только один раз) и запрос повторяется для перенаправления HTTP или аутентификации. Данные отправляются на HTTP-сервер сразу после заголовков.
Изменено в Python 3.6: не выдает ошибку, если Content-Length
не был указан, а данные не являются ни None
, ни байтовым объектом. Вместо ошибки, будет использовано кодирование во время передачи по частям.
Пример запроса, в котором для получения URL-адреса используется метод GET, содержащий параметры URL-адреса:
>>> import urllib.request >>> import urllib.parse >>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) >>> url = f"http://www.musi-cal.com/cgi-bin/query?{params}" >>> with urllib.request.urlopen(url) as resp: ... print(resp.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('ascii') >>> req = urllib.request.Request(url='http://requestb.in/xrbl82xr', data=data) >>> with urllib.request.urlopen("http://requestb.in/xrbl82xr", data) as resp: ... print(resp.read().decode('utf-8')) ...
Вот пример выполнения запроса PUT с использованием класса Request
:
>>> import urllib.request >>> DATA = b'some data' >>> req = urllib.request.Request(url='http://localhost:8080', data=DATA, method='PUT') >>> with urllib.request.urlopen(req) as resp: ... pass >>> print(resp.status) >>> print(resp.reason)
Отправка заголовков HEADERS:
import urllib.parse import urllib.request url = 'http://www.someserver.com/cgi-bin/register.cgi' user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)' values = {'name': 'Michael Foord', 'location': 'Northampton', 'language': 'Python' } headers = {'User-Agent': user_agent} data = urllib.parse.urlencode(values) data = data.encode('ascii') # создание объекта Request с указанием, в качестве # аргументов, параметров запроса и заголовков req = urllib.request.Request(url, data, headers) # отправка POST запроса with urllib.request.urlopen(req) as response: the_page = response.read()
Request
.Следующие методы описывают открытый интерфейс объекта Request
, поэтому все они могут быть переопределены в подклассах. Он также определяет несколько общедоступных атрибутов, которые могут использоваться клиентами для проверки проанализированного запроса.
Request.full_url
возвращает исходный URL-адрес,Request.type
возвращает схему URI,Request.host
возвращает хост,Request.origin_req_host
возвращает хост, без порта,Request.selector
возвращает путь URI,Request.data
тело объекта запроса,Request.unverifiable
является ли запрос проверяемым,Request.method
используемый метод HTTP-запроса,Request.get_method()
строка с метод HTTP-запроса,Request.add_header()
добавляет в запрос заголовок,Request.add_unredirected_header()
добавляет заголовок, который не будет передан по редиректу,Request.has_header()
имеет ли экземпляр именованный заголовок,Request.remove_header()
удаляет именованный заголовок,Request.get_full_url()
возвращает URL-адрес,Request.set_proxy()
подключается к прокси-серверу,Request.get_header()
возвращает значение заголовка,Request.header_items()
список кортежей (header_name, header_value)
.Request.full_url
:Свойство Request.full_url
возвращает исходный URL-адрес, переданный конструктору.
Это свойство с сеттером, геттером и делетером. Операция получения (геттер) возвращает исходный URL-адрес запроса с фрагментом данных, если он присутствовал.
>>> import urllib.request, urllib.parse >>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) >>> data = data.encode('utf-8') >>> req = urllib.request.Request(url='http://requestb.in:8080/xrbl82xr', data=data) >>> req.full_url # 'http://requestb.in:8080/xrbl82xr'
Request.type
:Атрибут Request.type
возвращает схему URI.
>>> import urllib.request, urllib.parse >>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) >>> data = data.encode('utf-8') >>> req = urllib.request.Request(url='http://requestb.in:8080/xrbl82xr', data=data) >>> req.type # 'http'
Request.host
:Атрибут Request.host
- обычно это хост, но может также содержать порт, разделенный двоеточием.
>>> req.host # 'requestb.in:8080'
Request.origin_req_host
:Атрибут Request.origin_req_host
представляет собой исходный хост для запроса, без порта.
>>> req.origin_req_host # 'requestb.in'
Request.selector
:Атрибут Request.selector
возвращает путь URI. Если запрос использует прокси, то селектором будет полный URL, который передается прокси.
>>> req.selector # ''/xrbl82xr''
Request.data
:Атрибут Request.data
возвращает параметры тела объекта запроса или None
, если не указано.
>>> req.selector # b'spam=1&eggs=2&bacon=0'
Request.unverifiable
:Атрибут Request.unverifiable
возвращает boolean
, указывает, является ли запрос проверяемым, как определено RFC 2965.
>>> req.unverifiable # False
Request.method
:Атрибут Request.method
возвращает используемый метод HTTP-запроса. По умолчанию его значение равно None
, что означает, что Request.get_method()
выполнит обычное вычисление метода, который будет использоваться.
Его значение можно установить (таким образом, переопределив вычисление по умолчанию в .get_method()
), либо предоставив значение по умолчанию, установив его на уровне класса в подклассе Request
, либо передав значение в конструктор Request
через аргумент метода.
Request.get_method()
:Метод Request.get_method()
возвращает строку, указывающую метод HTTP-запроса.
Если Request.method
не равен None
, то возвращает его значение, в противном случае возвращает GET, если Request.data
имеет значение None
, или POST, если это не так.
Такое поведение имеет значение только для HTTP-запросов.
>>> import urllib.request >>> req = urllib.request.Request('http://www.example.com/') >>> req.get_method() 'GET'
Request.add_header(key, val)
:Метод Request.add_header()
добавляет в запрос еще один заголовок. Заголовки в настоящее время игнорируются всеми обработчиками, кроме обработчиков HTTP, где они добавляются в список заголовков, отправляемых на сервер.
Обратите внимание, что не может быть более одного заголовка с тем же именем, и более поздние вызовы будут перезаписывать предыдущие вызовы в случае конфликта ключей. В настоящее время это не потеря функциональности HTTP, поскольку все заголовки, которые имеют значение при многократном использовании, имеют (зависящий от заголовка) способ получения той же функциональности с использованием только одного заголовка.
import urllib.request req = urllib.request.Request('http://www.example.com/') # Значение заголовка Referer. req.add_header('Referer', 'http://www.python.org/') # Значение заголовка User-Agent. req.add_header('User-Agent', 'urllib-example/0.1 (Contact: . . .)') r = urllib.request.urlopen(req)
Request.add_unredirected_header(key, header)
:Метод Request.add_unredirected_header()
добавляет заголовок, который не будет передан если сервер перенаправит запрос, другими словами, если будет редирект.
Request.has_header(header)
:Метод Request.has_header()
проверяет, имеет ли экземпляр именованный заголовок (проверяет как обычный, так и перенаправленный).
>>> import urllib.request >>> req = urllib.request.Request('http://www.example.com/') >>> req.add_header('Referer', 'http://www.python.org/') >>> req.has_header('Referer') # True
Request.remove_header(header)
:Метод Request.remove_header()
удаляет именованный заголовок из экземпляра запроса (как из обычных, так и из перенаправленных заголовков).
>>> import urllib.request >>> req = urllib.request.Request('http://www.example.com/') >>> req.add_header('Referer', 'http://www.python.org/') >>> req.add_header('User-Agent', 'urllib-example/0.1 (Contact: . . .)') >>> req.remove_header('Referer') >>> req.header_items() # [('User-agent', 'urllib-example/0.1 (Contact: . . .)')]
Request.get_full_url()
:Метод Request.get_full_url()
возвращает URL-адрес, указанный в конструкторе.
То же самое, что и Request.full_url
.
Request.set_proxy(host, type)
:Метод Request.set_proxy()
подготавливает запрос, подключившись к прокси-серверу. Аргументы хост host
и тип type
заменят те из экземпляра, а селектор экземпляра будет исходным URL-адресом, указанным в конструкторе.
import urllib.request # хост и порт прокси-сервера proxy_host = 'localhost:1234' # url-адрес для открытия url = 'http://www.httpbin.org/ip' req = urllib.request.Request(url) # подключаемся к прокси req.set_proxy(proxy_host, 'http') # открываем url-адрес response = urlrequest.urlopen(req) print(response.read().decode('utf8'))
Request.get_header(header_name, default=None)
:Метод Request.get_header()
возвращает значение данного заголовка. Если заголовок отсутствует, то возвращается значение по умолчанию.
>>> import urllib.request >>> req = urllib.request.Request('http://www.example.com/') >>> req.add_header('Referer', 'http://www.python.org/') >>> req.add_header('User-Agent', 'urllib-example/0.1 (Contact: . . .)') >>> req.get_header('Referer') # 'http://www.python.org/'
Request.header_items()
:Метод Request.header_items()
Возвращает список кортежей (header_name, header_value)
заголовков запроса.
>>> import urllib.request >>> req = urllib.request.Request('http://www.example.com/') >>> req.add_header('Referer', 'http://www.python.org/') >>> req.add_header('User-Agent', 'urllib-example/0.1 (Contact: . . .)') >>> req.header_items() # [('Referer', 'http://www.python.org/'), ('User-agent', 'urllib-example/0.1 (Contact: . . .)')]