Python requests: практическое руководство по HTTP-запросам
Библиотека requests является стандартным инструментом для выполнения HTTP-запросов в Python. Она предоставляет интуитивно понятный API, автоматически обрабатывает такие детали, как кодировка, куки, редиректы и таймауты. Ниже рассматривается основное применение модуля и несколько альтернативных подходов для типовых задач.
Основы работы с библиотекой requests
Как выполнить простой GET-запрос и получить содержимое страницы?
Самый распространённый сценарий - получение данных по URL. Для этого используется метод get(). Пример:
import requests
url = 'https://httpbin.org/get'
response = requests.get(url)
print(response.status_code)
print(response.text[:200])Python 2 requests (библиотека requests в python 2)
200
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
...
},
"origin": "...",
"url": "https://httpbin.org/get"
}Python 3 requests (библиотека requests в python 3)
Метод возвращает объект Response, содержащий статус-код, заголовки, тело ответа и другую информацию. Для извлечения данных в удобном формате, например JSON, используется метод json().
Типичные ошибки: ConnectionError при недоступном сервере, Timeout при превышении времени ожидания, HTTPError при кодах 4xx/5xx. Для обработки следует использовать блок try-except или проверять response.raise_for_status().
Как передать параметры в GET-запрос?
Параметры запроса можно передать через словарь в аргумент params. Библиотека сама закодирует их и добавит к URL.
params = {'key1': 'value1', 'key2': 'value2'}
response = requests.get('https://httpbin.org/get', params=params)
print(response.url) # https://httpbin.org/get?key1=value1&key2=value2
Python requests url (выполнение запроса по url с помощью requests в python)
Цель: удобное формирование строки запроса без ручного кодирования. Подходит для API, ожидающих параметры в URL.
Как отправить POST-запрос с данными формы?
Для отправки данных в теле запроса (например, форма) используется метод post() с параметром data.
data = {'username': 'user', 'password': 'secret'}
response = requests.post('https://httpbin.org/post', data=data)
print(response.json()['form'])Python requests headers (заголовки запросов в python requests)
{'username': 'user', 'password': 'secret'}Python requests exceptions (исключения в python requests)
Если требуется отправить JSON-данные, следует использовать аргумент json вместо data.
Проблема: забыть указать Content-Type. При использовании data заголовок application/x-www-form-urlencoded устанавливается автоматически. Для JSON requests сам выставляет application/json.
Как настроить таймаут и повторные попытки?
Для предотвращения зависания программы устанавливается таймаут через аргумент timeout. Для повторных попыток при сбоях используется адаптер HTTPAdapter с Retry.
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
retries = Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503])
adapter = HTTPAdapter(max_retries=retries)
session.mount('http://', adapter)
session.mount('https://', adapter)
try:
response = session.get('https://httpbin.org/status/500', timeout=10)
except requests.exceptions.RetryError:
print('Не удалось после 3 попыток')Python requests codes (коды ответов http в python requests)
Использование: в сценариях с нестабильным сетевым соединением или при работе с серверами, которые временно возвращают ошибки.
Как работать с сессиями и сохранять куки?
Объект Session позволяет сохранять состояние между запросами (куки, заголовки). Это полезно для имитации браузерной сессии.
session = requests.Session()
session.headers.update({'User-Agent': 'MyApp'})
response1 = session.get('https://httpbin.org/cookies/set?session_id=abc')
response2 = session.get('https://httpbin.org/cookies')
print(response2.json()['cookies'])Python module requests (модуль requests в python)
{'session_id': 'abc'}Python requests response (обработка ответа requests в python)
Ошибка: при использовании нескольких объектов Session куки не разделяются. Следует создавать одну сессию для всей цепочки запросов.
Как обрабатывать ошибки HTTP (4xx, 5xx)?
Метод raise_for_status() выбрасывает исключение HTTPError для неуспешных кодов. Это позволяет централизованно обрабатывать ошибки.
response = requests.get('https://httpbin.org/status/404')
try:
response.raise_for_status()
except requests.exceptions.HTTPError as e:
print(f'Ошибка: {e}')работа с requests python (работа с библиотекой requests в python)
Ошибка: 404 Client Error: NOT FOUND for url: https://httpbin.org/status/404
Назначение: упрощение логики проверки статус-кода в коде. Рекомендуется использовать при работе с внешними API.
Потоковая загрузка больших файлов
При скачивании крупных файлов не следует сразу загружать их в память. Используется параметр stream=True и итеративное чтение содержимого.
import requests
url = 'https://httpbin.org/image/png'
response = requests.get(url, stream=True)
if response.status_code == 200:
with open('image.png', 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
print('Файл загружен')
Файл загружен
Проблема: без stream=True всё тело ответа загружается в оперативную память, что может привести к её переполнению. Решение: всегда использовать потоковую загрузку для файлов размером более нескольких мегабайт.
Работа с самоподписанными SSL-сертификатами
Для запросов к серверам с невалидными сертификатами можно отключить проверку или указать собственный CA-файл.
# Отключение проверки (опасно)
response = requests.get('https://self-signed.badssl.com/', verify=False)
print(response.status_code)
# Указание своего сертификата
response = requests.get('https://example.com', verify='/path/to/cert.pem')
print(response.status_code)
200 200
Внимание: отключение verify делает соединение уязвимым для атак типа man-in-the-middle. Следует применять только в тестовой среде или при полном доверии к серверу.
Кастомные заголовки и прокси
Для эмуляции браузера или доступа через корпоративный прокси задаются соответствующие параметры.
proxies = {
'http': 'http://proxy.example.com:8080',
'https': 'https://proxy.example.com:8080'
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
response = requests.get('https://httpbin.org/headers', headers=headers, proxies=proxies)
print(response.json()['headers']['User-Agent'])
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Если прокси требует аутентификацию, используется строка вида http://user:pass@proxy:port или отдельный аргумент auth.
Использование PreparedRequest для тонкой настройки
Класс PreparedRequest позволяет создать объект запроса, модифицировать его и затем отправить через сессию. Это даёт максимум контроля.
from requests import Request, Session
url = 'https://httpbin.org/post'
data = {'key': 'value'}
req = Request('POST', url, data=data)
prepared = req.prepare()
# Добавление заголовка после подготовки
prepared.headers['X-Custom'] = '123'
session = Session()
response = session.send(prepared)
print(response.json()['headers']['X-Custom'])
123
Зачем: когда нужно изменить запрос уже после вызова preprare(), например, добавить подпись на основе тела запроса.
Автоматическое следование редиректам
По умолчанию requests автоматически следует редиректам (коды 301, 302, 303, 307, 308). Можно отключить это поведение и получить историю переходов.
response = requests.get('https://httpbin.org/redirect/3', allow_redirects=False)
print('Статус:', response.status_code)
print('Location:', response.headers.get('Location'))
# Включим редиректы и посмотрим историю
response2 = requests.get('https://httpbin.org/redirect/3', allow_redirects=True)
for r in response2.history:
print(r.status_code, r.url)
print('Итоговый URL:', response2.url)
Статус: 302 Location: /relative-redirect/2 302 https://httpbin.org/redirect/3 302 https://httpbin.org/relative-redirect/2 302 https://httpbin.org/relative-redirect/1 Итоговый URL: https://httpbin.org/get
Параметр allow_redirects удобен, когда нужно отловить промежуточные URL.