5.1 Знакомство с HttpClient
В Python, как и во многих языках программирования, есть стандартный HttpClient. В Python он называется http.client и позволяет выполнять низкоуровневые HTTP-запросы и работать с HTTP-ответами. Он позволяет создавать подключения к HTTP-серверам и взаимодействовать с ними.
Низкоуровневый модуль, такой как http.client, предоставляет более детальный контроль над HTTP-операциями, но требует больше кода для выполнения задач. В отличие от него, высокоуровневые модули, как requests, предоставляют более простой интерфейс, скрывая многие детали реализации.
Основные возможности http.client
Модуль http.client предоставляет следующие основные возможности:
- Создание HTTP-подключений.
- Отправка HTTP-запросов.
- Чтение HTTP-ответов.
- Обработка заголовков и тела запросов и ответов.
В отличие от модуля requests, модуль http.client более низкоуровневый и там уделено большое внимание нюансам работы http-запроса.
Основные классы и методы http.client
| Класс/Метод | Описание |
|---|---|
HTTPConnection |
Создание HTTP-подключения. |
HTTPSConnection |
Создание HTTPS-подключения. |
request(method, url, ...) |
Отправка HTTP-запроса. |
getresponse() |
Получение ответа на запрос. |
response.status |
Статус-код ответа. |
response.reason |
Текстовое описание статуса ответа. |
response.read() |
Чтение данных ответа. |
response.getheaders() |
Получение всех заголовков ответа. |
response.getheader(name) |
Получение значения конкретного заголовка. |
Ниже мы рассмотрим некоторые из них подробнее.
5.2 Выполнение GET-запроса
Чтобы выполнять запросы с использованием библиотеки http.client, нужно выполнить такой порядок действий:
Установить соединение
Отправить запрос
Получить ответ
Закрыть соединение
Важно отметить, что закрытие соединения после использования необходимо для освобождения ресурсов и предотвращения утечек памяти. Это особенно важно при работе с большим количеством запросов или в долгоживущих приложениях.
Пример использования HTTPConnection для обычного HTTP-запроса:
import http.client
# Создание HTTP-подключения
conn = http.client.HTTPConnection("example.com")
# Отправка GET-запроса
conn.request("GET", "/")
# Получение ответа
response = conn.getresponse()
print(response.status, response.reason)
# Закрытие подключения
conn.close()
Пример использования HTTPSConnection:
import http.client
# Создание подключения
conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")
# Отправка GET-запроса
conn.request("GET", "/posts/1")
# Получение ответа
response = conn.getresponse()
print(response.status, response.reason)
# Чтение и декодирование данных ответа
data = response.read().decode('utf-8')
print(data)
# Получение всех заголовков ответа
headers = response.getheaders()
for header in headers:
print(f"{header[0]}: {header[1]}")
# Закрытие подключения
conn.close()
Немного длиннее, чем при использовании requests, не так ли?
5.3 Выполнение POST-запроса
POST-запрос с использованием http.client выполняется очень похоже на GET-запрос, только данные нужно упаковать в json-строку самостоятельно, а также нужно вручную указать тип передаваемых данных — добавить заголовок Content-Type.
Пример:
import http.client
import json
# Отправка POST-запроса
conn.request("POST", "/posts", body=payload, headers=headers)
В качестве body нужно передать json-объект, сериализованный в строку, а в качестве headers — словарь, содержащий информацию о типе данных.
Они могут выглядеть, например, так:
# Данные для отправки
payload = json.dumps({
"title": "foo",
"body": "bar",
"userId": 1
})
# Заголовки – тип передаваемого контента
headers = {
'Content-Type': 'application/json'
}
Тогда полный код POST-запроса будет выглядеть так:
import http.client
import json
# Данные для отправки
payload = json.dumps({
"title": "foo",
"body": "bar",
"userId": 1
})
# Заголовки
headers = {
'Content-Type': 'application/json'
}
# Создание подключения
conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")
# Отправка POST-запроса
conn.request("POST", "/posts", body=payload, headers=headers)
# Получение ответа
response = conn.getresponse()
print(response.status, response.reason)
# Чтение и декодирование данных ответа
data = response.read().decode('utf-8')
print(data)
# Закрытие подключения
conn.close()
5.4 Обработка ошибок при выполнении запросов
Также думаю, будет полезно привести пример обработки ошибок, т.к. он отличается от поведения requests. В модуле http.client исключение кидается автоматически, если были проблемы с соединением или другие HTTP-ошибки.
Пример:
import http.client
try:
# Создание подключения
conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")
# Отправка GET-запроса
conn.request("GET", "/posts/1")
# Получение ответа
response = conn.getresponse()
print(response.status, response.reason)
# Чтение и декодирование данных ответа
data = response.read().decode('utf-8')
print(data)
except http.client.HTTPException as e:
print("HTTP error occurred:", e)
except Exception as e:
print("An error occurred:", e)
finally:
# Закрытие подключения
conn.close()
Что сказать? Использование модуля requests будет, конечно, попроще. Но! Многие модули и фреймворки используют под капотом именно низкоуровневый http.client. Вам нужно знать, как с ним работать, чтобы вы могли правильно конфигурировать их работу.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ