HTTP клиент на Python с помощью Requests
Раздел: Python -> Веб-библиотеки
Введение в библиотеку Requests
Библиотека Requests для Python предоставляет удобные методы для отправки HTTP запросов. Она абстрагирует работу с низкоуровневыми сетевыми протоколами и позволяет разработчику сосредоточиться на логике приложения.
Установка выполняется командой: pip install requests.
Базовый GET запрос и обработка ответа
Как отправить простой запрос и получить содержимое страницы?
import requests
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
print(response.status_code) # 200
print(response.text[:100]) # Первые 100 символовбиблиотека requests python (библиотека requests для python)
После вызова get возвращается объект Response. Его атрибуты status_code (код статуса), text (тело ответа в виде строки), content (байты), json() (JSON).
Типичные ошибки: Если URL недоступен, возникает
ConnectionError. При отсутствии интернета ConnectTimeout. Если сервер возвращает ошибку, status_code показывает 4xx или 5xx, но исключение не выбрасывается автоматически. Нужно вызывать raise_for_status().Различные варианты настройки запросов
Как передать query-параметры в URL?
import requests
params = {'userId': 1, '_limit': 3}
response = requests.get('https://jsonplaceholder.typicode.com/posts', params=params)
print(response.request.url) # https://jsonplaceholder.typicode.com/posts?userId=1&_limit=3Если передать
None или словарь с None значениями, параметр не добавится. Для вложенных структур используйте params с дублирующимися ключами через список.Как отправить POST данные в виде формы?
data = {'title': 'foo', 'body': 'bar', 'userId': 1}
response = requests.post('https://jsonplaceholder.typicode.com/posts', data=data)
print(response.status_code, response.json())Если забыть указать
data или передать строку, сервер может не распознать форму. Для JSON используйте json=, а не data.Как отправить JSON через POST?
import json
payload = {'title': 'foo', 'body': 'bar', 'userId': 1}
response = requests.post('https://jsonplaceholder.typicode.com/posts', json=payload)
print(response.json())Если передать
data=json.dumps(payload) без заголовка Content-Type: application/json, сервер может не обработать JSON. Параметр json сам устанавливает нужные заголовки.Как добавить пользовательские заголовки?
headers = {'Authorization': 'Bearer some_token', 'Accept': 'application/json'}
response = requests.get('https://api.example.com/user', headers=headers)
print(response.status_code)Ключи заголовков нечувствительны к регистру (Requests приводит к каноническому виду). Если передать неверный токен, сервер вернет 401. Ошибка не будет автоматически обработана.
Как обрабатывать ошибки HTTP?
response = requests.get('https://jsonplaceholder.typicode.com/nonexistent')
try:
response.raise_for_status()
except requests.exceptions.HTTPError as err:
print(f'HTTP error: {err}')Если не вызвать
raise_for_status, код продолжит выполняться, и ответ с 404 может быть обработан как успешный. При вызове в блоке try нужно корректно обрабатывать исключения.Как сохранить сессию с куками и параметрами?
session = requests.Session()
session.headers.update({'Accept': 'application/json'})
session.get('https://httpbin.org/cookies/set?name=value')
response = session.get('https://httpbin.org/cookies')
print(response.json()) # {'cookies': {'name': 'value'}}Сессия может вести себя неожиданно при использовании в многопоточной среде без синхронизации. Не забывайте закрывать сессию через
session.close().Как установить таймаут на запрос?
try:
response = requests.get('https://httpbin.org/delay/5', timeout=3)
except requests.exceptions.Timeout:
print('Превышен таймаут')Таймаут по умолчанию отсутствует, программа зависает. Можно задать кортеж
(подключение, чтение). Если превышено время подключения или чтения, выбрасывается Timeout.Как отправить файл через multipart/form-data?
files = {'file': open('example.txt', 'rb')}
response = requests.post('https://httpbin.org/post', files=files)
print(response.json()['files'])
files['file'].close()Файл нужно открыть в бинарном режиме. Requests автоматически определяет имя файла. Если не закрыть файл, он останется открытым. Удобно использовать контекстный менеджер
with open(...) as f: ....Как настроить прокси для запросов?
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
response = requests.get('https://httpbin.org/ip', proxies=proxies)
print(response.json())Если прокси требует аутентификации, укажите
http://user:pass@host:port. При неверных настройках ProxyError или ConnectError.Как отключить проверку SSL сертификата?
response = requests.get('https://self-signed.badssl.com', verify=False)
print(response.status_code)Отключать проверку не рекомендуется, так как это делает соединение уязвимым. При
verify=False выводится предупреждение InsecureRequestWarning. Для подавления используйте urllib3.disable_warnings().Расширенные примеры использования Requests
Использование PreparedRequest для тонкой настройки
Пример
from requests import Request, Session
url = 'https://httpbin.org/post'
headers = {'X-Custom': 'test'}
data = {'key': 'value'}
req = Request('POST', url, headers=headers, data=data)
prepared = req.prepare()
# Изменение подготовленного запроса
prepared.headers['X-Additional'] = 'extra'
session = Session()
response = session.send(prepared)
print(response.json()['headers']){
"X-Custom": "test",
"X-Additional": "extra",
...
}PreparedRequest позволяет модифицировать запрос перед отправкой, но требует ручного управления сессией. Неправильное изменение может нарушить целостность запроса.
Потоковая загрузка больших файлов
Пример
import requests
url = 'https://cdn.example.com/bigfile.zip'
response = requests.get(url, stream=True)
response.raise_for_status()
with open('bigfile.zip', 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)При
stream=True тело ответа не загружается в память целиком. Если забыть вызвать iter_content, соединение не закроется. При использовании iter_lines для текстовых данных может быть потеряна последняя строка без перевода.Отправка запроса с кастомным методом (PATCH, DELETE и др.)
Пример
import requests
response = requests.request('PATCH', 'https://httpbin.org/patch', json={'status': 'active'})
print(response.json()['json'])Метод
request() позволяет указать любой HTTP метод. Если метод не поддерживается сервером, вернется ошибка 405. Не забудьте установить соответствующие заголовки.Работа с куками через объект CookieJar
Пример
import requests
jar = requests.cookies.RequestsCookieJar()
jar.set('session_id', 'abc123', domain='httpbin.org', path='/')
response = requests.get('https://httpbin.org/cookies', cookies=jar)
print(response.json())CookieJar позволяет управлять куками на низком уровне. При неправильном domain или path кука не отправится. Сессии обычно проще.
Асинхронная отправка запросов с concurrent.futures (requests не асинхронен)
Пример
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
def fetch_url(url):
return requests.get(url).status_code
urls = ['https://httpbin.org/delay/1'] * 5
with ThreadPoolExecutor(max_workers=3) as executor:
futures = {executor.submit(fetch_url, url): url for url in urls}
for future in as_completed(futures):
print(future.result())Requests блокирует поток. Использование многопоточности увеличивает производительность, но требует осторожности с сессиями (не разделять сессию между потоками без блокировки). Для истинной асинхронности используйте
aiohttp.Библиотека Requests для Python - comments
En
библиотека requests python (python)