Библиотека Requests в Python

Модуль requests в Python представляет собой мощный инструмент для работы с HTTP-запросами, который упрощает процесс взаимодействия с веб-сервисами и API. С его помощью разработчики могут легко отправлять запросы, получать и обрабатывать ответы, не углубляясь в сложные детали низкоуровневого сетевого взаимодействия. Основное преимущество requests заключается в интуитивно понятном и лаконичном интерфейсе, позволяющем избежать затруднений, с которыми часто сталкиваются при работе с библиотеками на более низком уровне.

С помощью библиотеки requests пользователи могут легко выполнять типичные задачи, такие как отправка GET- и POST-запросов, обработка заголовков, управление состоянием сессий и работа с параметрами запроса. Более того, модуль поддерживает обработку куки, аутентификацию и работу с JSON, что делает его незаменимым инструментом в арсенале современных разработчиков. Неважно, нужно ли вам просто получить данные с веб-страницы или интегрировать сложный сервис — библиотека requests предлагает все необходимые функции, чтобы быстро и эффективно решить любую задачу, связанную с HTTP.

Фактически это один из самых простых способов сделать запрос (и получить ответ) к другому сервису по сети используя Python. С помощью данной библиотеки можно, например, мониторить состояние работоспособности своего сайта, либо скачивать какой-то контент.

Установка библиотеки Requests в виртуальную среду

Чтобы начать работать с библиотекой её необходимо ее установить, для этого введем в терминале:

pip install requests

Мы получим следующий результат, говорящий об успешной установке модуля:

Далее создадим новый проект и импортируем:

import requests

Поддерживаются основные типы запросов: GET, POST, PUT, DELETE, HEAD, PATCH и OPTIONS.

 

GET - запросы используя Requests

GET запрос служит для того чтобы запросить какой-то документ по сети. Работа состоит из 2 частей:

  1. отправка запроса

  2. обработка ответа

Рассмотрим на примере получения простого документа - интернет-страницы 

import requests

url = 'https://ya.ru'
r = requests.get(url)
print(r)

Мы получим следующий ответ - <Response [200]>

Однако на практике у него есть несколько полезных для нас методов.

Параметры запроса

Иногда возникает потребность сделать запрос не просто к странице вида https://ya.ru, а к https://ya.ru/?key=value

Примером такой ситуации будет локальный поиск по сайту, который часто работает в виде site.com/?q=query, где query - собственно поисковый запрос.

Вы можете сами сформировать целиком url, используя информацию о структуре URL, но это часто не удобно, т.к. нужно склеивать несколько параметров через &. Поэтому можно просто передать все необходимые параметры в виде словаря в атрибут params:

r = requests.get(url, params = {'key1':'value1', 'key2':'value2'})

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

requests.get(url, timeout=5, retries=3)

Атрибуты и методы ответа (Response)

GET-запросы играют ключевую роль в взаимодействии клиента с веб-серверами. При использовании библиотеки Requests в Python, выполнение GET-запросов становится предельно простым и интуитивно понятным. Эта библиотека обеспечивает удобный интерфейс для отправки запросов и обработки ответов, что делает её идеальным инструментом для разработчиков. Предположим мы сделали какой-то запрос и ответ на него находится в переменной r.

url

Возвращает адрес к которому был сделан запрос. Вдруг вы забыли.

r.url
#'https://ya.ru/'

 

status_code

Код ответа.

  • 200 - ОК, всё хорошо

  • 404 - документ не найден

  • 503 - сервер недоступен (таймаут)

  • и т.д. 

Код ответа позволяет понять всё ли в порядке, получили ли вы штатный ответ от сервера, либо что-то произошло (возможно вы запросили какие-то данные, а сервер сломался, значит надо немного подождать).

r.status_code
#200

 

encoding

Кодировка документа

r.encoding
#'UTF-8'

 

headers

HTTP заголовки - мета информация о документе, содержащая служебные данные. Представляет из себя словарь, к отдельным элементам которого можно сразу обращаться по ключу (при условии, что сервер передал такой заголовок вам в ответ)

r.headers
#{'Content-Security-Policy': "style-src https://yastatic.net 'unsafe-inline';report-uri https://csp.yandex.net/csp?project=morda&from=morda.yaru.ru&showid=1568202765.34268.160468.145944&h=vla2-4730-08f-vla-portal-morda-deb-16891&csp=new&date=20190911&yandexuid=9360929801568202765;script-src https://mc.yandex.ru 'unsafe-inline' https://yastatic.net https://yandex.ru;frame-src 'self' https://mc.yandex.ru;img-src https://yastatic.net https://avatars.mds.yandex.net https://favicon.yandex.net 'self' https://mc.yandex.ru https://yandex.ru https://mc.admetrica.ru data:;default-src 'none';connect-src https://mc.admetrica.ru https://yandex.ru https://mc.yandex.ru", 'Date': 'Wed, 11 Sep 2019 11:52:45 GMT', 'X-Content-Type-Options': 'nosniff', 'Set-Cookie': 'yp=1570794765.ygu.1; Expires=Sat, 08-Sep-2029 11:52:45 GMT; Domain=.ya.ru; Path=/, mda=0; Expires=Thu, 09-Jan-2020 11:52:45 GMT; Domain=.ya.ru; Path=/, yandex_gid=213; Expires=Fri, 11-Oct-2019 11:52:45 GMT; Domain=.ya.ru; Path=/, yandexuid=9360929801568202765; Expires=Sat, 08-Sep-2029 11:52:45 GMT; Domain=.ya.ru; Path=/, i=KNh91OknZL3BuEaK2ZO7+B4BDgh1oL63LoZpd5a0K/3+JGGfKyuAJdIXYsJchVPlYyvblGcuyyoYyrNN+nHCB8Q+lT0=; Expires=Sat, 08-Sep-2029 11:52:45 GMT; Domain=.ya.ru; Path=/; Secure; HttpOnly', 'X-Frame-Options': 'DENY', 'P3P': 'policyref="/w3c/p3p.xml", CP="NON DSP ADM DEV PSD IVDo OUR IND STP PHY PRE NAV UNI"', 'Expires': 'Wed, 11 Sep 2019 11:52:45 GMT', 'Last-Modified': 'Wed, 11 Sep 2019 11:52:45 GMT', 'Transfer-Encoding': 'chunked', 'Cache-Control': 'no-cache,no-store,max-age=0,must-revalidate', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html; charset=UTF-8'}

r.headers['Content-Type']
#'text/html; charset=UTF-8'

 

text

Тело ответа, в данном случае html код страницы.

r.text

 

r.json()

При условии, что тело ответа представляет из себя JSON, парсит его в Python объект.

Фактически, это обёртка для json.loads поверх тела ответа.

r.json()

# Аналогично записи

import json
json.loads(r.text)

Если тело ответа не является JSON (а, например, html код страницы), будет получена ошибка.

 

content

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

r.content

 

Базовая аутентификация

Если вы встречали при путешествиях по интернету всплывающее окно авторизации на сайте. Её необходимо пройти прежде, чем вы получите хоть какой-то контент от сервера (или сможете отправить на него какие-то данные).

Для этого используется атрибут auth, в который передаётся кортеж с именем пользователя и паролем:

r = requests.get(url, auth=('user', 'password'))

 

Заголовки и аутентификация

Запросы Python позволяют устанавливать пользовательские заголовки и легко управлять различными методами аутентификации.

headers = {'User-Agent': 'MyApp/1.0'}
response = requests.get(url, headers=headers) # Basic Authentication
response = requests.get(url, auth=('username', 'password'))

 

Сессионные объекты

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

Для этого есть объект requests.Session().

Пример использования (для базовой аутентификации):

import requests

s = requests.Session()
s.auth = ('user', 'password') #Устанавливаем параметры базовой аутентификации 

r = s.get('https://site.com/')
print(r.status_code)

r = s.get('https://site.com/page1/')
print(r.status_code)

r = s.get('https://site.com/page2/')
print(r.status_code)

Примечание. Если бы в примере выше мы не использовали объект сессии, то авторизоваться пришлось бы на каждом запросе.

 

Обработка ошибок

Правильное обращение с ошибками имеет решающее значение при обработке веб-запросов. Запросы в Python обеспечивают бесперебойную работу с исключениями.

try:
    response = requests.get('https://api.example.com/resource')
    response.raise_for_status() # Raise an exception for HTTP errors
except requests.exceptions.HTTPError as err:
    print(f"HTTP error: {err}")

 

POST запросы используя Requests

Когда вам нужно отправить какие-то данные на сервер (например, файл), то обычно вы используете POST запрос.

Основные принципы работы с POST идентичны тому, как вы работаете с GET (так же необходимо задать url, можно добавить параметры авторизации, параметры в url, а потом обработать ответ)

import requests

p = requests.post(url)
print(p)  # <Response [200]>

Важно помнить, что по конкретному адресу сервер вполне может быть готов предоставить вам документ в ответ на GET запрос, но не готов что-то делать в ответ на передачу данных в POST (и наоборот).

Данные в POST запросе

Для передачи данных в POST запросе служит атрибут data, в который передаётся словарь:

import requests

url = 'https://httpbin.org/post'
payload = {'key1': 'value1', 'key2': 'value2'}
p = requests.post(url, data=payload)

print(p.text)

В результате получим следующий ответ, и как мы видим из тела ответа, наши данные были успешно отправлены.

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "key1": "value1", 
    "key2": "value2"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "23", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.32.3", 
    "X-Amzn-Trace-Id": "Root=1-671355d8-453f4ce6763cae4a2b6d2052"
  }, 
  "json": null, 
  "origin": "92.255.226.44", 
  "url": "https://httpbin.org/post"
}

Так же можно передавать данные в виде кортежа парами (ключ, значение) или словарём в котором для каждого ключа можно присваивать сразу несколько значений, если они совпадают:

url = 'https://httpbin.org/post'
payload = [('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3')]
p = requests.post(url, data=payload)

print(p.text)

Или:

import requests

url = 'https://httpbin.org/post'
payload = {'key1': ['value1', 'value2'], 'key2': ['value3', 'value4']}
p = requests.post(url, data=payload)

print(p.text)

Передача файлов используя Requests

С помощью POST запроса можно передавать файлы. Для этого служит атрибут files, куда необходимо положить словарь из пар ключ-файл (ключи из этого словаря будут соответствовать именам параметром POST запроса, где будет лежать файл).

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

Для передачи по сети файл нужно не просто прочитать, а прочитать в виде набора байтов, т.е. с флагом "rb".

Чтение файла как набора байтов:

open('1.png', 'rb')

Передача файла в POST запросе:

import requests

url = 'https://httpbin.org/post'
files = {'file': open('img.jpg', 'rb')}
p = requests.post(url, files=files)

print(p.text)

В результате получим следующий ответ:

"/Volumes/Mac SSD/Project/PyHub/pillow/.venv/bin/python" /Volumes/Mac SSD/Project/PyHub/pillow/request.py 
{
  "args": {}, 
  "data": "", 
  "files": {
    "file": "data:application/octet-stream;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4QAqRXhpZgAASUkqAAgAp6ChlFHO08sD1DoJjhMJlQ3YnGTkn2AwBrtY29tmmcPNSUgPkf4SD3HOtayz+AnjjXIBnbtxpoCHpmx7Ec6RmgCRETR8/dcac7Fv+4VN6/Zlwoaapb8InjzG35kcjUnTUVLU0yvJApDLnGO2lyyte1ilGD6IHa2oru8fVA4OFKcHWAkukD9S1PnL7eamWH5N3GpZq9u0ZhZkZoyOBgcaD6mljiJT8WM8katTtWhUo/KCWwb7vfz0luvz1hpqhUUqk37tTwFJQ+2MHjv31fXwp3XuKpqKKyXFxVWqKgUQl1VZIeghAM/xejOPqOPbVBRRU818oYQpjDKinB+wPGrmeG+55v7w09g+ShFNBb/MilHEnBDer2bknnGh9VmfImo2WRlcwXaohqiQHULEeOlicdDAn2I/z/XT1DKam0R0EtAbfUhGp5st5hkHRlXB7DqB4x/h0HtfGkuEKSUNO7SU8sEjMmer09ak/XGSuDnIx2xpwo7u7R1ZWBYJIXigR4WKEIScAflrnavUOEGDBWbLzBRm02a7JSs9YKWnbzI4+tRMW6MDHfIBY/TOdGsNLSR0qR11vWqqlGHZ53Xp9wAF4xjGotBS4VogmjzClSF8ksfLfpJUFgCCTz9Rp2vd3qpL0JBPPF1QoeiKbpUcewA1wNN5LbCmim1F8n//2Q=="
  }, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "134214", 
    "Content-Type": "multipart/form-data; boundary=c858410fcb8968cd4a14063109ae4387", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.32.3", 
    "X-Amzn-Trace-Id": "Root=1-671356d7-643aa7fb6511ca4e5a14e6cf"
  }, 
  "json": null, 
  "origin": "92.255.226.44", 
  "url": "https://httpbin.org/post"
}


Process finished with exit code 0

Как можно заметить по примерам, довольно частая ситуация, когда сервер отвечает на POST запрос JSON'ом.

Это позволяет получаемые и отправляемые данные представлять в виде Python словарей, автоматизируя обмен информацией между вашим приложением и сервером.

 

Итоги работы

Одно из основных применений модуля requests заключается в получении данных из различных веб-ресурсов. Например, с помощью простого вызова requests.get(url) можно моментально загрузить HTML-код страницы, который затем можно анализировать с помощью библиотек, таких как Beautiful Soup. Это открывает широкие возможности для веб-скрапинга и автоматизации получения информации.

Также стоит отметить, что requests позволяет программно взаимодействовать с RESTful API, что стало стандартом для большинства современных веб-сервисов. С помощью requests.post(url, data) разработчики легко отправляют данные на сервер и получают структурированные ответы в формате JSON, что значительно упрощает интеграцию различных систем и сервисов.

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

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

Одним из важных аспектов работы с модулем requests является его способность обрабатывать куки и сессии. Это позволяет разработчикам поддерживать состояние между запросами, что особенно полезно при взаимодействии с веб-приложениями, требующими аутентификации. Используя requests.Session(), можно создать сессию, где все запросы будут автоматически включать необходимые куки, сохраняя авторизацию или другие параметры пользователя.

Еще одной интересной функцией является возможность управления таймаутами, что критично для стабильных и отзывчивых приложений. При помощи параметра timeout можно задать максимальное время ожидания ответа от сервера, что предотвращает зависание приложения при медленных или недоступных ресурсах. Это особенно актуально, когда приложение должно обрабатывать множество запросов.

Также стоит отметить возможность работы с прокси-серверами, что расширяет горизонты для получения данных из ограниченных регионов. Используя параметр proxies, можно легко интегрировать запросы через специальные прокси, обеспечивая анонимность и безопасность работы с конфиденциальной информацией.

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

Комментарии