Сообщить об ошибке.

Класс Request модуля urllib.request в Python

Создание POST, GET, PUT и т.д. запросов, отправка различных заголовков

Синтаксис:

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:

Свойство 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: . . .)')]