Объект Response в Requests: полное описание

Раздел: Python -> Requests

Основной подход к обработке ответа requests

После выполнения запроса библиотека requests возвращает объект Response. Наиболее эффективный способ работы включает следующие шаги:

  1. Проверка успешности запроса с помощью метода raise_for_status() или проверка атрибута ok.
  2. Определение типа содержимого по заголовку Content-Type.
  3. Извлечение данных в нужном формате: .json(), .text, .content.
  4. Обработка возможных исключений (сетевые ошибки, таймауты, невалидный JSON).
import requests

try:
    response = requests.get('https://api.example.com/data')
    response.raise_for_status()  # вызовет исключение при коде 4xx/5xx
    content_type = response.headers.get('Content-Type', '')
    if 'application/json' in content_type:
        data = response.json()
    else:
        data = response.text
    print(data)
except requests.exceptions.RequestException as e:
    print(f'Ошибка запроса: {e}')

Python 2 requests (библиотека requests в python 2)

Возможные проблемы:

  • Игнорирование проверки статуса может привести к обработке ошибочного ответа.
  • Вызов .json() на пустом или не JSON ответе вызывает ValueError.
  • Отсутствие таймаута может привести к зависанию скрипта.

Этот универсальный подход подходит для большинства REST API и веб-страниц.

Как получить данные в формате JSON из ответа requests?

Метод response.json() автоматически парсит тело ответа как JSON. Если сервер возвращает некорректный JSON или ответ пуст, будет выброшено исключение ValueError. Рекомендуется оборачивать вызов в try-except.

import requests

resp = requests.get('https://api.github.com/users/octocat')
try:
    user = resp.json()
    print(user['login'])
except ValueError:
    print('Ответ не содержит валидный JSON')

Python 3 requests (библиотека requests в python 3)

Типичные ошибки:

  • Ошибка парсинга при получении HTML вместо JSON.
  • Изменение кодировки: если сервер не указал кодировку, requests использует свою эвристику, что может привести к некорректному парсингу. Рекомендуется устанавливать response.encoding вручную.

Используется при работе с RESTful API, веб-хуками и любыми сервисами, возвращающими JSON.

Как извлечь текст из ответа requests с корректной кодировкой?

Свойства response.text и response.content дают строку и байты соответственно. text автоматически декодирует, используя предположительную кодировку, но можно явно задать response.encoding = 'utf-8'. Если необходимо получить сырой контент (например, для бинарных данных), используют content.

import requests

r = requests.get('https://www.python.org')
r.encoding = 'utf-8'  # принудительно
print(r.text[:200])

Python requests url (выполнение запроса по url с помощью requests в python)

Проблемы:

  • Неверная авто-детекция кодировки приводит к кракозябрам (особенно для кириллицы).
  • Большие ответы: text загружает всё в память, для больших файлов лучше использовать iter_content.

Применяется для веб-скрапинга, скачивания HTML-страниц, работы с текстовыми API.

Как проверить успешность запроса без исключений?

Атрибут response.ok возвращает True, если код статуса меньше 400. Метод response.raise_for_status() генерирует исключение HTTPError для кодов 400-599. Выбор зависит от стиля: ok для простой проверки, raise_for_status для явной обработки ошибок.

import requests

resp = requests.get('https://httpbin.org/status/404')
if not resp.ok:
    print(f'Ошибка: {resp.status_code}')
else:
    print(resp.text)

Python requests headers (заголовки запросов в python requests)

Ошибка:

  • Забывают, что ok проверяет только коды ниже 400, а для 3xx (редиректы) тоже True, если allow_redirects=True.
  • Использование raise_for_status без блока try может прервать выполнение.

Необходимо для валидации ответов перед дальнейшей обработкой.

Как получить HTTP заголовки и куки из ответа requests?

Headerы доступны через response.headers (объект CaseInsensitiveDict). Куки сохраняются в response.cookies (RequestsCookieJar). Можно также получить значение конкретного заголовка: response.headers.get('Content-Type').

import requests

resp = requests.get('https://httpbin.org/cookies/set?name=value')
print(resp.headers['Set-Cookie'])
print(resp.cookies.get('name'))

Python requests exceptions (исключения в python requests)

Проблемы:

  • Заголовки могут быть неполными (например, отсутствует Content-Length).
  • Куки могут быть заблокированы настройками безопасности.

Полезно для отладки, авторизации через куки, отслеживания редиректов.

Как скачать и сохранить бинарный файл (изображение, PDF) из ответа requests?

Для больших файлов использовать response.iter_content(chunk_size=8192) для потоковой загрузки. Для небольших файлов можно использовать response.content и сразу записать в файл. Важно открыть файл в бинарном режиме 'wb'.

import requests

url = 'https://www.python.org/static/img/python-logo.png'
r = requests.get(url, stream=True)
with open('logo.png', 'wb') as f:
    for chunk in r.iter_content(chunk_size=1024):
        f.write(chunk)

Python requests codes (коды ответов http в python requests)

Ошибки:

  • Если не указать stream=True, iter_content может загрузить всё в память.
  • При обрыве соединения файл может быть неполным; рекомендуется проверять размер.

Используется для загрузки контента с сайтов, изображений, документов.

Как получить историю редиректов и отключить их автоматическое следование?

По умолчанию requests следует редиректам (allow_redirects=True). История доступна в response.history (список объектов Response). Чтобы отключить, передать allow_redirects=False.

import requests

r = requests.get('http://httpbin.org/redirect/3')
print(f'Конечный URL: {r.url}')
print(f'Количество редиректов: {len(r.history)}')
for resp in r.history:
    print(resp.status_code, resp.url)

Python module requests (модуль requests в python)

Проблема:

Неожиданные редиректы могут привести к нежелательному конечному URL или изменению метода (POST -> GET).

Применяется для анализа цепочки перенаправлений или при работе с API, где редиректы недопустимы.

Как корректно обрабатывать исключения при запросах: ConnectionError, Timeout, HTTPError?

Все исключения библиотеки requests наследуются от requests.exceptions.RequestException. Рекомендуется ловить общее исключение или конкретные (Timeout, ConnectionError). Таймаут задаётся параметром timeout.

import requests
from requests.exceptions import Timeout, ConnectionError

try:
    r = requests.get('https://httpbin.org/delay/5', timeout=2)
    r.raise_for_status()
except Timeout:
    print('Превышен таймаут')
except ConnectionError:
    print('Не удалось подключиться')
except requests.exceptions.RequestException as e:
    print(f'Ошибка: {e}')

Типичные ошибки:

  • Отсутствие таймаута может привести к зависанию скрипта на неопределённое время.
  • Игнорирование ConnectionError при нестабильной сети.

Необходимо для стабильной работы программ, особенно при периодических опросах серверов.

- Requests python скачать (скачивание файлов с помощью requests в python)
- Python types requests (типы запросов в requests python)
- Python requests post (отправка post-запроса с помощью requests python)

Ниже приведены расширенные примеры, демонстрирующие различные аспекты обработки ответа requests в реальных сценариях.

Пример 1. Получение JSON с GitHub API с обработкой пагинации

Запрос списка репозиториев пользователя, обработка заголовка Link для перехода по страницам.

Пример
import requests
import json

def get_all_repos(username):
    repos = []
    url = f'https://api.github.com/users/{username}/repos?per_page=100'
    while url:
        resp = requests.get(url)
        resp.raise_for_status()
        repos.extend(resp.json())
        link = resp.links.get('next', {}).get('url')
        url = link
    return repos

repos = get_all_repos('octocat')
print(f'Найдено {len(repos)} репозиториев')
for repo in repos[:3]:
    print(repo['name'])
Найдено 8 репозиториев
Hello-World
Spoon-Knife
octocat.github.com

Пример 2. Потоковая загрузка большого файла с индикацией прогресса

Пример
import requests

url = 'https://speed.hetzner.de/1GB.bin'
resp = requests.get(url, stream=True)
total = int(resp.headers.get('content-length', 0))
downloaded = 0
with open('test.bin', 'wb') as f:
    for chunk in resp.iter_content(chunk_size=8192):
        if chunk:
            f.write(chunk)
            downloaded += len(chunk)
            percent = 100 * downloaded / total if total else 0
            print(f'Downloaded {downloaded} of {total} bytes ({percent:.1f}%)')
print('Download complete')
Downloaded 1048576 of 1073741824 bytes (0.1%)
...
Downloaded 1073741824 of 1073741824 bytes (100.0%)
Download complete

Пример 3. Работа с сессией и куками: авторизация и сохранение состояния

Пример
import requests

session = requests.Session()
login_data = {'username': 'user', 'password': 'pass'}
session.post('https://httpbin.org/post', data=login_data)
resp = session.get('https://httpbin.org/cookies')
print(resp.json())
{'cookies': {'session': 'abc123'}}

Обработка ответа requests в Python - comments

En
Python requests response (python)