Содержимое ответа response — .json() .text .content



Объект Response в библиотеке Requests представляет собой основной элемент для организации веб-парсинга. Он хранит большое количество информации, полученной от сервера после обработки запроса. Для эффективного и безопасного извлечения данных необходимо уметь работать с доступными методами, свойствами и другими важными особенностями.

При отправке HTTP-запроса с использованием функций requests.get(), requests.post() и т.д., эти функции возвращают объект Response.

import requests

# Отправляем GET-запрос
r = requests.get('https://api.github.com/events')
# Получаем текст ответа
print("Содержимое ответа:")
print(r.text)

Кодировка

По умолчанию, Requests использует встроенные инструменты для определения кодировки полученного ответа, для этого используется информация из заголовков. Однако предусмотрена возможность узнать, какая кодировка используется и при необходимости изменить ее.

# Узнать текущую кодировку
print("Текущая кодировка:", r.encoding)

# Изменить кодировку
r.encoding = 'ISO-8859-1'

Особенности работы с пользовательскими кодировками

Если в ответ на запрос поступает непонятный набор символов, возможно причина в несоответствии кодировки. Для исправления ситуации можно явно указать данный параметр:

# Используйте необходимую кодировку
response.encoding = 'utf-8'

JSON

Для корректной обработки данных в формате JSON в библиотеку requests встроен соответствующий декодер. Пример работы:

import requests

response = requests.get(url='https://jsonplaceholder.typicode.com/todos/')
print(response.json())
>>> [{'userId': 1, 'id': 1, 'title': 'delectus aut autem', 'completed': False},

В данном случае ответ сервера автоматически преобразуется в список или словарь, в зависимости от структуры JSON. Если процесс декодирования завершить не удается, метод r.json() генерирует исключение requests.exceptions.JSONDecodeError.

Пример с использованием .text

import requests

response = requests.get(url='https://jsonplaceholder.typicode.com/todos/')
print(response.text)

>>>[
  {
    "userId": 1,
    "id": 1,
    "title": "delectus aut autem",
    "completed": false
  },.....

Если поочередно запустить два последних примера в терминале, окажется что возвращается идентичный ответ. Однако при проверки типа ответа при помощи type() проявятся различия. В случае с .text возвращается тип <class ‘str’>, при использовании .json() – <class ‘list’>.

Стоит отметить, что успешная обработка r.json() не всегда является гарантией, что запрос прошел успешно. В некоторых случаях серверы могут возвращать объект JSON, даже при возникновении ошибки. К примеру, в таком формате может быть прислано описание ошибки 500. Для проверки, был ли запрос успешным, можно использовать метод r.raise_for_status(). Также можно явно проверить код ответа при помощи конструкции: r.status_code==200.

Пример работы:

# Проверка статуса ответа
if r.status_code == 200:
    print("Запрос успешно выполнен")
else:
    print(f"Произошла ошибка: {r.status_code}")

Использование конструкции r.raise_for_status():

try:
    r.raise_for_status()
    print("Запрос успешно выполнен")
except requests.exceptions.HTTPError as err:
    print(f"Произошла ошибка: {err}")

Такой запрос позволяет быть уверенным, что полученный ответ будет корректно обработан.

TEXT

Не всегда очевидно, в чем разница подходов, какой лучше использовать. response.json() и response.text обеспечивают получение ответа от сервера, однако они отличаются по типу возвращаемых данных и методам обработки этих данных. Далее этот момент будет рассмотрен подробнее.

response.json()

Возвращает данные в виде списка или словаря, в зависимости от структуры JSON-объекта. Полученные данные автоматически декодируются в Python-объект.

Если строка не является валидным JSON, возвращается исключение JSONDecodeError.

Удобно использовать, когда сервер в качестве ответа использует JSON.

response.text

Данные возвращаются в виде обычной строки. При этом автоматическая обработка данных не предусмотрена, программист должен самостоятельно обработать набор данных.

Используется, когда данные возвращаются в текстовом формате, это может быть JSON, HTML, XML и так далее.

CONTENT

response.content предоставляет ответ сервера в формате байтовой строки. Другими словами, передаются «сырые» байты. Пример:

import requests

response = requests.get(url='http://httpbin.org/image/jpeg')

print(response.content)

>>> b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x02\x00\x1c\x00\x1c\x00\x00\xff\xfe\x005Edited by Paul Sherman for WPClipart, Public Domain\xff\xdb\x00C\x00\x02\x01\x01\x01\x01\x01\x02\x01\x01\x01\x02\x02\x02\x02\x02\x04\x03\x02\x02\x02\x02\x05\x04\x04\x03\x04\x06\x05\x06\x06\x06\x05\x06\x06\x06\x07\t\x08\x06\x07\t\x07\x06\x06\x08\x0b\x08\t\n\n\n\n\n\x06\x08\x0b\x0c\x0b\n\x0c\t\n\n\n\xff\xdb\x00C\x01\x02\x02\x02\x02\x02\x02\x05\x03\x03\x05\n\x07\x06\x07\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\xff\xc0\x00\x11\x08\x00\xb2\x00\xef\x03\x01\x11\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x1e\x00\x00\x01\x05\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x06\x03\x04\x05\x07\x08\x02\t\x00\x01\n\xff\xc4\x00M\x10\x00\x01\x03\x03\x01\x07\x02\x03\x05\x05\x06\x02\x07\x06\x07\x00\x04\x01\x03\x05\x02\x06\x11!\x00\x07\x08\x12\x13\x141#A"$Q\t\x1534a\

….

Такой вывод не информативен, но в некоторых ситуациях данный вариант вывода предпочтительнее.

Использование менеджера контекста with

Если поставлена задача сохранить данные в файл, что хорошей практикой будет использование менеджера контекста with. В этом случае обеспечивается корректное закрытие и открытие файла, даже если возникнет ошибка:

import requests

response = requests.get(url='http://httpbin.org/image/jpeg')
with open('image.jpeg', 'wb') as file:
    file.write(response.content)

Если запустить данный код, в папке проекта появится файл image.jpeg. Флаг «wb» обозначает запись в байтовом формате (write byte).

Стоит учитывать, что в параметр url должна передаваться прямая ссылка на файл. При этом расширение указывать не обязательно.

Когда лучше использовать response.content?

Данный метод оптимально подходит для загрузки различных бинарных файлов (видео, аудио, графику и так далее).

Если необходимо дополнительно обработать «сырые» байты, например, для нестандартного преобразования или декодировки.

Дебаггинг. В некоторых ситуациях необходимо отобразить ответ сервера без предварительной обработки.

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



Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: