Библиотека запросов Python (руководство)
Оглавление
- Начните работу с библиотекой Запросов Python
- Сделайте запрос на получение
- Проверьте реакцию
- Добавление параметров строки запроса
- Настройка заголовков запросов
- Используйте другие HTTP-методы
- Отправить данные запроса
- Проверьте подготовленный запрос
- Использовать аутентификацию
- Безопасное взаимодействие с Серверами
- Повышение производительности
- Заключение
- Часто задаваемые вопросы
Смотрите сейчас, к этому уроку прилагается соответствующий видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным руководством, чтобы углубить свое понимание: Создание HTTP-запросов с помощью Python
Библиотека Запросов - это готовый пакет для выполнения HTTP-запросов на Python. Он позволяет абстрагироваться от сложностей выполнения запросов с помощью интуитивно понятного API. Хотя он и не является частью стандартной библиотеки Python, стоит рассмотреть запросы для выполнения HTTP-действий, таких как GET, POST и других.
К концу этого урока вы поймете, что:
- Requests не является встроенным модулем Python - это сторонняя библиотека, которую необходимо установить отдельно.
- Вы отправляете запрос GET на Python, используя
requests.get()с нужным URL-адресом. - Чтобы добавить заголовки к запросам, передайте словарь заголовков параметру
headersв вашем запросе. - Чтобы отправить данные POST, используйте параметр
dataдля данных, закодированных в форме, или параметрjsonдля данных JSON. response.textвыдает строку, представляющую содержимое ответа, в то время какresponse.contentпредоставляет необработанные байты.
В этом руководстве вы узнаете, как настраивать запросы с заголовками и данными, обрабатывать ответы, проверять подлинность и оптимизировать производительность с помощью сеансов и повторных попыток.
Если вы хотите изучить примеры кода, которые вы увидите в этом руководстве, вы можете скачать их здесь:
Получите свой код: Нажмите здесь, чтобы загрузить бесплатный пример кода, который показывает, как использовать библиотеку запросов Python.
<отметить класс="marker-highlight"> Пройдите тест:отметить> Проверьте свои знания с помощью нашего интерактивного теста ”Библиотека запросов Python". По завершении вы получите оценку, которая поможет вам отслеживать прогресс в обучении:
<время работы/>
Интерактивная викторина
Библиотека запросов PythonПроверьте свое понимание библиотеки запросов Python для выполнения HTTP-запросов и взаимодействия с веб-службами.
Начало работы с Библиотекой Запросов Python
Несмотря на то, что библиотека запросов является общим компонентом для многих разработчиков Python, она не включена в стандартную библиотеку Python . Таким образом, библиотека сможет продолжать развиваться более свободно как самостоятельный проект.
Примечание: Если вы хотите выполнять HTTP-запросы только с помощью стандартной библиотеки Python, то Python urllib.request - это хороший выбор для вас.
Поскольку Requests - это сторонняя библиотека, вам необходимо установить ее, прежде чем использовать в своем коде. Рекомендуется устанавливать внешние пакеты в виртуальную среду, но вы можете установить requests в свою глобальную среду, если планируете использовать ее в нескольких проектах.
Независимо от того, работаете вы в виртуальной среде или нет, вам необходимо установить requests:
$ python -m pip install requestsпредварительно> кодовый блок>Как только
pipзавершит установкуrequests, вы сможете использовать его в своем приложении. Импортrequestsвыглядит следующим образом:import requestsпредварительно> кодовый блок>Теперь, когда все готово, самое время начать работу с запросами. Вашей первой целью будет сделать
GETзапрос.Сделать запрос на получение
HTTP-методы, такие как
GETиPOST, указывают действие, которое вы хотите выполнить при отправке HTTP-запроса. В дополнение кGETиPOSTсуществует несколько других распространенных методов, которые вы будете использовать позже в этом руководстве.Одним из наиболее часто используемых HTTP-методов является
GET, который извлекает данные из указанного ресурса. Чтобы отправить запросGETс помощью запросов, вы можете вызватьrequests.get().Чтобы попробовать это, вы можете сделать
GETзапрос к REST API GitHub, вызвавget()со следующим URL-адресом:>>> import requests >>> requests.get("https://api.github.com") <Response [200]>предварительно> кодовый блок>Поздравляем! Вы отправили свой первый запрос. Теперь давайте немного углубимся в ответ на этот запрос.
Проверьте ответ
A
Response- это объект, содержащий результаты вашего запроса. Попробуйте выполнить тот же запрос еще раз, но на этот раз сохраните возвращаемое значение в переменной, чтобы вы могли более подробно ознакомиться с ее атрибутами и поведением:>>> import requests >>> response = requests.get("https://api.github.com")предварительно> кодовый блок>В этом примере вы получили возвращаемое значение
requests.get(). Это экземплярResponse, и вы сохранили его в переменной с именемresponse. Теперь вы можете использоватьresponse, чтобы просмотреть больше информации о результатах вашего запросаGET.Работа с Кодами состояния
Первая часть информации, которую вы можете почерпнуть из
Response, - это код состояния. Код состояния информирует вас о статусе запроса.Например, статус
200 OKозначает, что ваш запрос был выполнен успешно, в то время как статус404 NOT FOUNDозначает, что ресурс, который вы искали, не был найден. Существует множество других возможных кодов статуса, которые также дают вам конкретную информацию о том, что произошло с вашим запросом.Перейдя к
.status_code, вы можете увидеть код состояния, который вернул сервер:>>> response.status_code 200предварительно> кодовый блок>
.status_codeвозвращено200, что означает, что ваш запрос был выполнен успешно и сервер ответил запрошенными вами данными.Иногда вам может понадобиться использовать эту информацию для принятия решений в вашем коде:
if response.status_code == 200: print("Success!") elif response.status_code == 404: print("Not Found.")предварительно> кодовый блок>При такой логике, если сервер возвращает код состояния
200, то ваша программа выведетSuccess!. Если результат равен404, то ваша программа выведетNot Found.Запросы - это еще один шаг в упрощении этого процесса для вас. Если вы используете
Responseэкземпляр в логическом контексте, таком как условный оператор, то он будет равенTrueкогда код состояния меньше400, иFalseв противном случае.Это означает, что вы можете изменить последний пример, переписав оператор
if:if response: print("Success!") else: raise Exception(f"Non-success status code: {response.status_code}")предварительно> кодовый блок>В приведенном выше фрагменте кода вы неявно проверяете, находится ли
.status_codeизresponseмежду200и399. Если это не так, то вы создаете исключение с сообщением об ошибке, которое содержит код состояния "сбой", заключенный в f-струна.Примечание: Этот тест на истинность возможен потому, что
.__bool__()является перегруженным методом наResponse. Это означает, что адаптированное поведение по умолчанию дляResponseучитывает код состояния при определении истинного значения объекта.Имейте в виду, что этот метод выполняет , а не проверку того, равен ли код состояния
200. Это связано с тем, что другие коды состояния в диапазоне от200до399, такие как204 NO CONTENTи304 NOT MODIFIED, также считаются успешными, поскольку они обеспечивают некоторый работоспособный ответ.Например, код состояния
204сообщает вам, что ответ был получен успешно, но в теле сообщения нет содержимого, которое можно было бы вернуть.Поэтому используйте это удобное сокращение только в том случае, если хотите узнать, был ли запрос в целом выполнен успешно. Затем, при необходимости, вам нужно будет соответствующим образом обработать ответ на основе кода состояния.
Предположим, вы не хотите проверять код состояния ответа в инструкции
if. Вместо этого вы хотите использовать встроенные возможности Request для создания исключения, если запрос не был выполнен. Вы можете сделать это с помощью.raise_for_status():raise_error.pyкодовый блок>import requests from requests.exceptions import HTTPError URLS = ["https://api.github.com", "https://api.github.com/invalid"] for url in URLS: try: response = requests.get(url) response.raise_for_status() except HTTPError as http_err: print(f"HTTP error occurred: {http_err}") except Exception as err: print(f"Other error occurred: {err}") else: print("Success!")Если вы вызываете
.raise_for_status(),, то запросы будут вызыватьHTTPErrorдля кодов состояния от400до600. Если код состояния указывает на успешный запрос, то программа продолжит работу, не вызывая этого исключения.Теперь вы многое знаете о том, как обращаться с кодом состояния ответа, который вы получаете от сервера. Однако, когда вы отправляете запрос
GET, вас редко интересует только код состояния ответа. Обычно вы хотите увидеть больше. Далее вы узнаете, как просмотреть фактические данные, которые сервер отправил обратно в теле ответа.Доступ к содержимому ответа
Ответ на запрос
GETчасто содержит некоторую ценную информацию, известную как полезная нагрузка, в теле сообщения. Используя атрибуты и методыResponse, вы можете просматривать полезную нагрузку в различных форматах.Чтобы просмотреть содержимое ответа в
bytes, вы используете.content:>>> import requests >>> response = requests.get("https://api.github.com") >>> response.content b'{"current_user_url":"https://api.github.com/user", ...}' >>> type(response.content) <class 'bytes'>предварительно> кодовый блок>Хотя
.contentпредоставляет вам доступ к необработанным байтам полезной нагрузки ответа, вам часто захочется преобразовать их в строку, используя кодировка символов, например UTF-8.responseсделает это за вас, когда вы получите доступ к.text:>>> response.text '{"current_user_url":"https://api.github.com/user", ...}' >>> type(response.text) <class 'str'>предварительно> кодовый блок>Поскольку для декодирования
bytesвstrтребуется схема кодирования, Запросы будут пытаться угадать кодировку на основе заголовков ответа , если вы ее не укажете. Вы можете указать явную кодировку, установив.encodingперед доступом.text:>>> response.encoding = "utf-8" # Optional: Requests infers this. >>> response.text '{"current_user_url":"https://api.github.com/user", ...}'предварительно> кодовый блок>Если вы взглянете на ответ, то увидите, что на самом деле это сериализованный JSON контент. Чтобы получить словарь, вы могли бы взять
str, который вы извлекли из.text, и десериализовать его с помощьюjson.loads(). Однако прямым способом выполнения этой задачи является использование.json():>>> response.json() {'current_user_url': 'https://api.github.com/user', ...} >>> type(response.json()) <class 'dict'>предварительно> кодовый блок>Тип возвращаемого значения
.json()- это словарь, поэтому вы можете получить доступ к значениям в объекте по ключу:>>> response_dict = response.json() >>> response_dict["emojis_url"] 'https://api.github.com/emojis'предварительно> кодовый блок>Вы можете многое сделать с кодами состояния и текстами сообщений. Но если вам нужна дополнительная информация, например, метаданные о самом ответе, вам нужно просмотреть заголовки ответа.
Просмотр заголовков ответов
Заголовки ответа могут предоставить вам полезную информацию, такую как тип содержимого полезной нагрузки ответа и продолжительность кэширования ответа. Чтобы просмотреть эти заголовки, перейдите к
.headers:>>> import requests >>> response = requests.get("https://api.github.com") >>> response.headers {'Server': 'github.com', ... 'X-GitHub-Request-Id': 'AE83:3F40:2151C46:438A840:65C38178'}предварительно> кодовый блок>Атрибут
.headersвозвращает объект, подобный словарю, позволяющий вам получать доступ к значениям заголовка по ключу. Например, чтобы просмотреть тип содержимого полезной нагрузки ответа, вы можете получить доступ к"Content-Type":>>> response.headers["Content-Type"] 'application/json; charset=utf-8'предварительно> кодовый блок>В этом словарном объекте headers есть что-то особенное. Спецификация HTTP определяет заголовки как нечувствительные к регистру, что означает, что вы можете обращаться к ним, не беспокоясь об их заглавных буквах:
>>> response.headers["content-type"] 'application/json; charset=utf-8'предварительно> кодовый блок>Независимо от того, используете ли вы ключ
"content-type"или"Content-Type", вы получите одно и то же значение.Теперь, когда вы увидели наиболее полезные атрибуты и методы из
Responseв действии, у вас уже есть хороший обзор базового использования запросов. Вы можете получать контент из Интернета и работать с полученным ответом.Но в Интернете есть нечто большее, чем простые URL-адреса. В следующем разделе вы вернетесь на шаг назад и увидите, как меняются ваши ответы, когда вы настраиваете свои запросы
GETс учетом параметров строки запроса.Добавить параметры строки запроса
Одним из распространенных способов настройки запроса
GETявляется передача значений через строку запроса параметров в URL-адресе. Чтобы сделать это с помощьюget(), вы передаете данные вparams. Например, вы можете воспользоваться поиском по репозиторию на GitHub API для поиска популярных репозиториев Python:search_popular_repos.pyкодовый блок>import requests response = requests.get( "https://api.github.com/search/repositories", params={"q": "language:python", "sort": "stars", "order": "desc"}, ) json_response = response.json() popular_repositories = json_response["items"] for repo in popular_repositories[:3]: print(f"Name: {repo['name']}") print(f"Description: {repo['description']}") print(f"Stars: {repo['stargazers_count']}\n")Передавая словарь в
paramsпараметрget(), вы можете изменять результаты, получаемые из API поиска.Вы можете передать
paramsвget()либо в виде словаря, как вы только что сделали, либо в виде списка кортежей:>>> import requests >>> requests.get( ... "https://api.github.com/search/repositories", ... [("q", "language:python"), ("sort", "stars"), ("order", "desc")], ... ) <Response [200]>предварительно> кодовый блок>Вы даже можете передать значения в виде
bytes:>>> requests.get( ... "https://api.github.com/search/repositories", ... params=b"q=language:python&sort=stars&order=desc", ... ) <Response [200]>предварительно> кодовый блок>Строки запроса полезны для параметризации
GETзапросов. Еще один способ настроить запросы - добавить или изменить заголовки, которые вы отправляете.Настройка заголовков запросов
Чтобы настроить заголовки, вы передаете словарь HTTP-заголовков в
get(), используя параметрheaders. Например, вы можете изменить свой предыдущий поисковый запрос, чтобы выделить в результатах поиска соответствующие условия, указавtext-matchтип носителя в заголовкеAccept:text_matches.pyкодовый блок>import requests response = requests.get( "https://api.github.com/search/repositories", params={"q": '"real python"'}, headers={"Accept": "application/vnd.github.text-match+json"}, ) json_response = response.json() first_repository = json_response["items"][0] print(first_repository["text_matches"][0]["matches"])Заголовок
Acceptсообщает серверу, какие типы контента может обрабатывать ваше приложение. В этом случае, поскольку вы ожидаете, что будут выделены соответствующие поисковые запросы, вы используете значение заголовкаapplication/vnd.github.text-match+json. Это проприетарный заголовок GitHubAccept, содержимое которого представлено в специальном формате JSON.Когда вы запустите этот скрипт на Python, вы получите результат, аналогичный показанному ниже:
$ python text_matches.py [{'text': 'Real Python', 'indices': [23, 34]}]предварительно> кодовый блок>Прежде чем вы узнаете больше о способах настройки запросов, вы расширите свой кругозор, изучив другие методы HTTP.
Используйте другие HTTP-методы
Помимо
GET, другие популярные HTTP-методы включаютPOST,PUT,DELETE,HEAD,PATCHиOPTIONS. Для каждого из этих HTTP-методов Requests предоставляет функцию с сигнатурой, аналогичнойget().Примечание: Чтобы опробовать эти HTTP-методы, вам необходимо отправить запросы по адресу httpbin.org. Сервис httpbin - отличный ресурс, созданный первоначальным автором запросов, Кеннетом Рейтцем. Сервис принимает тестовые запросы и отвечает данными о запросах.
Вы заметите, что Requests предоставляет интуитивно понятный интерфейс для всех распространенных HTTP-методов:
>>> import requests >>> requests.get("https://httpbin.org/get") <Response [200]> >>> requests.post("https://httpbin.org/post", data={"key": "value"}) <Response [200]> >>> requests.put("https://httpbin.org/put", data={"key": "value"}) <Response [200]> >>> requests.delete("https://httpbin.org/delete") <Response [200]> >>> requests.head("https://httpbin.org/get") <Response [200]> >>> requests.patch("https://httpbin.org/patch", data={"key": "value"}) <Response [200]> >>> requests.options("https://httpbin.org/get") <Response [200]>предварительно> кодовый блок>В приведенном выше примере вы вызывали каждую функцию, чтобы сделать запрос к службе httpbin, используя соответствующий HTTP-метод.
Все эти функции являются высокоуровневыми сокращениями для
requests.request(),, которые принимают имя метода в качестве первого аргумента:>>> requests.request("GET", "https://httpbin.org/get") <Response [200]>предварительно> кодовый блок>Вы могли бы использовать эквивалентный вызов функции более низкого уровня, но мощь библиотеки запросов Python заключается в ее удобном для пользователя высокоуровневом интерфейсе. Вы можете просматривать ответы точно так же, как делали это раньше:
>>> response = requests.head("https://httpbin.org/get") >>> response.headers["Content-Type"] 'application/json' >>> response = requests.delete("https://httpbin.org/delete") >>> json_response = response.json() >>> json_response["args"] {}предварительно> кодовый блок>Независимо от того, какой метод вы используете, вы получаете
Responseобъект, который предоставляет доступ к заголовкам, текстам ответов, кодам состояния и многому другому.Далее вы более подробно ознакомитесь с методами
POST,PUT, иPATCHи узнаете, чем они отличаются от других типов запросов.Отправить данные запроса
В соответствии со спецификацией HTTP,
POST,PUT, и менее распространенными запросамиPATCHданные передаются через текст сообщения, а не через параметры в строке запроса. С помощью запросов вы передаете эту полезную нагрузку в параметр соответствующей функцииdata.Параметр
dataпринимает словарь, список кортежей, байты или объект, подобный файлу. Возможно, вам захочется адаптировать данные, которые вы отправляете в теле своего запроса, к конкретным потребностям сервиса, с которым вы взаимодействуете.Например, если тип содержимого вашего запроса
application/x-www-form-urlencoded, то вы можете отправить данные формы в виде словаря:>>> import requests >>> requests.post("https://httpbin.org/post", data={"key": "value"}) <Response [200]>предварительно> кодовый блок>Вы также можете отправить эти же данные в виде списка кортежей:
>>> requests.post("https://httpbin.org/post", data=[("key", "value")]) <Response [200]>предварительно> кодовый блок>Если вам нужно отправить данные в формате JSON, то вы можете использовать параметр
json. Когда вы передаете данные в формате JSON черезjson, запросы сериализуют ваши данные и добавляют правильный заголовокContent-Typeдля вас.Как вы узнали ранее, служба httpbin принимает тестовые запросы и отвечает данными о запросах. Например, вы можете использовать ее для проверки базового запроса
POST:>>> response = requests.post("https://httpbin.org/post", json={"key": "value"}) >>> json_response = response.json() >>> json_response["data"] '{"key": "value"}' >>> json_response["headers"]["Content-Type"] 'application/json'предварительно> кодовый блок>Из ответа видно, что сервер получил данные вашего запроса и заголовки в том виде, в каком вы их отправили. В Requests также представлена эта информация в виде
PreparedRequest, которую вы более подробно рассмотрите в следующем разделе.Проверьте подготовленный запрос
Когда вы отправляете запрос, библиотека запросов подготавливает запрос перед фактической отправкой на целевой сервер. Подготовка запроса включает в себя такие вещи, как проверка заголовков и сериализация содержимого JSON.
Вы можете просмотреть объект
PreparedRequest, перейдя к.requestобъектуResponse:>>> import requests >>> response = requests.post("https://httpbin.org/post", json={"key":"value"}) >>> response.request <PreparedRequest [POST]> >>> response.request.headers["Content-Type"] 'application/json' >>> response.request.url 'https://httpbin.org/post' >>> response.request.body b'{"key": "value"}'предварительно> кодовый блок>Проверка
PreparedRequestпредоставляет вам доступ ко всем видам информации о выполняемом запросе, таким как полезная нагрузка, URL-адрес, заголовки, аутентификация и многое другое.До сих пор вы делали множество различных запросов, но у всех них была одна общая черта: это были неаутентифицированные запросы к общедоступным API. Многие службы, с которыми вы столкнетесь, захотят, чтобы вы каким-либо образом прошли аутентификацию.
Использовать аутентификацию
Проверка подлинности помогает службе понять, кто вы такой. Как правило, вы предоставляете свои учетные данные серверу, передавая данные через заголовок
Authorizationили пользовательский заголовок, определенный службой. Все функции в запросах, которые вы видели до этого момента, предоставляют параметр с именемauth, который позволяет вам напрямую передавать свои учетные данные:>>> import requests >>> response = requests.get( ... "https://httpbin.org/basic-auth/user/passwd", ... auth=("user", "passwd") ... ) >>> response.status_code 200 >>> response.request.headers["Authorization"] 'Basic dXNlcjpwYXNzd2Q='предварительно> кодовый блок>Запрос выполняется успешно, если учетные данные, которые вы передаете в кортеже
auth, действительны.Когда вы передаете свои учетные данные в виде кортежа в параметр
auth, Requests применяет учетные данные, используя схему базовой аутентификации доступа HTTP .
Вы можете задаться вопросом, откуда берется строка
Basic dXNlcjpwYXNzd2Q=, которая запрашивает значение в качестве значения для вашего заголовкаAuthorization. Короче говоря, это строка имени пользователя и пароля в кодировке Base64 с префиксом"Basic ":
Во-первых, запросы объединяют имя пользователя и пароль, которые вы предоставляете, вставляя между ними двоеточие. Итак, для имени пользователя
"user"и пароля"passwd"это становится"user:passwd".Затем Requests кодирует эту строку в Base64, используя
base64.b64encode(). Кодировка преобразует строку"user:passwd"в"dXNlcjpwYXNzd2Q=".Наконец, Requests добавляет
"Basic "перед этой строкой Base64.Таким образом, конечное значение для заголовка
AuthorizationстановитсяBasic dXNlcjpwYXNzd2Q=в примере, показанном выше.Обратите внимание, что базовая аутентификация HTTP (BA) сама по себе не очень безопасна, поскольку любой может расшифровать строку Base64, чтобы раскрыть ваши учетные данные. Вот почему важно всегда отправлять эти запросы по протоколу HTTPS, который шифрует весь запрос и обеспечивает дополнительный уровень защиты.
Вы могли бы сделать тот же запрос, передав явные базовые учетные данные для проверки подлинности с помощью
HTTPBasicAuth:>>> from requests.auth import HTTPBasicAuth >>> requests.get( ... "https://httpbin.org/basic-auth/user/passwd", ... auth=HTTPBasicAuth("user", "passwd") ... ) <Response [200]>предварительно> кодовый блок>Хотя для обычной проверки подлинности вам не нужно указывать явные данные, вы можете захотеть пройти проверку подлинности с помощью другого метода. Запросы предоставляют другие методы аутентификации "из коробки", такие как
HTTPDigestAuthиHTTPProxyAuth.Реальным примером API, требующего аутентификации, является аутентифицированный пользовательский API GitHub. Эта конечная точка предоставляет информацию о профиле прошедшего проверку пользователя.
Если вы попытаетесь отправить запрос без учетных данных, то увидите, что код состояния равен
401 Unauthorized:>>> requests.get("https://api.github.com/user") <Response [401]>предварительно> кодовый блок>Если вы не укажете учетные данные для проверки подлинности при доступе к службе, которая их требует, в качестве ответа вы получите код ошибки HTTP.
Чтобы отправить запрос к аутентифицированному пользовательскому API GitHub, вам сначала необходимо сгенерировать персональный токен доступа с параметром
read:userscope. Затем вы можете передать этот токен в качестве второго элемента в кортеже вget():>>> import requests >>> token = "<YOUR_GITHUB_PA_TOKEN>" >>> response = requests.get( ... "https://api.github.com/user", ... auth=("", token) ... ) >>> response.status_code 200предварительно> кодовый блок>Как вы узнали ранее, этот подход передает учетные данные в
HTTPBasicAuth, который ожидает ввода имени пользователя и пароля, и отправляет учетные данные в виде строки в кодировке Base64 с префиксом"Basic ":>>> response.request.headers["Authorization"] 'Basic OmdocF92dkd...WpremM0SGRuUGY='предварительно> кодовый блок>Этот метод работает, но это неправильный способ аутентификации с помощью
Bearerтокена — и использовать пустую строку для ввода лишнего имени пользователя неудобно.Для запросов вы можете предоставить свой собственный механизм аутентификации, чтобы исправить это. Чтобы опробовать это, создайте подкласс из
AuthBaseи реализуйте.__call__():custom_token_auth.pyкодовый блок>from requests.auth import AuthBase class TokenAuth(AuthBase): """Implements a token authentication scheme.""" def __init__(self, token): self.token = token def __call__(self, request): """Attach an API token to the Authorization header.""" request.headers["Authorization"] = f"Bearer {self.token}" return requestЗдесь ваш пользовательский механизм
TokenAuthполучает токен, затем включает этот токен вAuthorizationзаголовок вашего запроса, также устанавливая рекомендуемый префикс"Bearer "для строки.Теперь вы можете использовать эту пользовательскую аутентификацию с помощью токена для обращения к аутентифицированному пользовательскому API GitHub:
>>> import requests >>> from custom_token_auth import TokenAuth >>> token = "<YOUR_GITHUB_PA_TOKEN>" >>> response = requests.get( ... "https://api.github.com/user", ... auth=TokenAuth(token) ... ) >>> response.status_code 200 >>> response.request.headers["Authorization"] 'Bearer ghp_b...Tx'предварительно> кодовый блок>Ваш пользовательский
TokenAuthсоздал хорошо отформатированную строку для заголовкаAuthorization. Это дает вам более интуитивно понятный и многократно используемый способ работы со схемами аутентификации на основе токенов, подобными тем, которые требуются в некоторых частях API GitHub.Примечание: Хотя вы могли бы создать строку аутентификации вне пользовательского класса аутентификации и передать ее напрямую с помощью
headers, такой подход не рекомендуется потому что это может привести к неожиданному поведению.Когда вы пытаетесь установить свои учетные данные для аутентификации напрямую, используя
headers, запросы могут внутренне перезаписать ваши данные. Это может произойти, например, если у вас есть.netrcфайл, который предоставляет учетные данные для аутентификации. Запросы будут пытаться получить учетные данные из файла.netrc, если вы не укажете метод аутентификации с помощьюauth.Некачественные механизмы аутентификации могут привести к уязвимостям в системе безопасности. Если по какой-либо причине службе не требуется специальный механизм аутентификации, лучше всего использовать проверенный метод, такой как встроенная базовая аутентификация или OAuth- например, через Запросы-OAuthlib.
Пока вы думаете о безопасности, рассмотрите возможность использования сертификатов TLS/SSL с запросами.
Безопасное взаимодействие с Серверами
Всякий раз, когда данные, которые вы пытаетесь отправить или получить, являются конфиденциальными, безопасность становится жизненно важной. Для взаимодействия с защищенными сайтами по протоколу HTTP необходимо установить зашифрованное соединение с использованием протокола безопасности транспортного уровня (TLS). Протокол TLS является преемником протокола Secure Sockets Layer (SSL) и обеспечивает повышенную безопасность и эффективность защищенных коммуникаций. Тем не менее, программисты по-прежнему часто используют термин SSL вместо TLS.
Запросы по умолчанию проверяют цифровые сертификаты серверов для вас, и вам редко приходится вносить изменения в это поведение. Однако в некоторых случаях вам может потребоваться настроить процесс проверки.
Например, когда вы работаете в корпоративной среде с пользовательскими центрами сертификации, вам может потребоваться предоставить свой собственный пакет сертификатов:
>>> import requests >>> requests.get( ... "https://internal-api.company.com", ... verify="/path/to/company-ca.pem" ... ) <Response [200]>предварительно> кодовый блок>Вы также можете указать каталог, содержащий файлы сертификатов, если вам необходимо доверять нескольким пользовательским органам.
Если вы устраняете проблемы с сертификатами в процессе разработки, у вас может возникнуть соблазн полностью отключить проверку. Хотя это и работает, это представляет значительную угрозу безопасности, и вам никогда не следует использовать этот подход в рабочей среде:
>>> requests.get("https://api.github.com", verify=False) InsecureRequestWarning: Unverified HTTPS request is being made to host ⮑ 'api.github.com'. Adding certificate verification is strongly advised. ⮑ See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings ⮑ warnings.warn( <Response [200]>предварительно> кодовый блок>Requests предупреждает вас об этой опасной практике, поскольку отключение проверки делает вас уязвимым для атак типа "человек посередине".
Примечание.: В Requests используется пакет с именем
certifiдля предоставления центров сертификации. Это позволяет запросам узнать, каким органам они могут доверять. Чтобы обеспечить максимальную безопасность ваших подключений, вам следует регулярно обновлятьcertifi.Теперь, когда вы знаете, как безопасно проводить проверку сертификата, вам может быть интересно, как обеспечить максимально быструю работу вашей программы.
Повышение производительности
При использовании запросов, особенно в среде производственных приложений, важно учитывать влияние на производительность. Такие функции, как контроль времени ожидания, сеансы и ограничения на повторные попытки, могут помочь вам обеспечить бесперебойную работу приложения.
Примечание: Requests не поддерживает асинхронные HTTP-запросы напрямую. Если вам нужна поддержка асинхронности в вашей программе, то вам следует попробовать AIOHTTP или HTTPX. Последняя библиотека в целом совместима с синтаксисом запросов.
Даже в синхронном коде есть несколько важных методов, которые вы можете использовать для оптимизации ваших HTTP-запросов и предотвращения снижения производительности.
Установить тайм-ауты запросов
Когда вы отправляете встроенный запрос к внешней службе, ваша система должна дождаться ответа, прежде чем двигаться дальше. Если ваше приложение слишком долго ожидает этого ответа, запросы к вашей службе могут быть скопированы, может пострадать ваш пользовательский опыт или фоновые задания могут зависать.
По умолчанию запросы будут ждать ответа неопределенное время, поэтому вам почти всегда следует указывать время ожидания, чтобы избежать возникновения подобных проблем. Чтобы задать время ожидания запроса, используйте параметр
timeout.timeoutможет быть целым числом илиfloatпредставлять количество секунд, в течение которых необходимо ожидать ответа до истечения времени ожидания:>>> requests.get("https://api.github.com", timeout=1) <Response [200]> >>> requests.get("https://api.github.com", timeout=0.01) Traceback (most recent call last): ... requests.exceptions.ConnectTimeout: ⮑ HTTPSConnectionPool(host='api.github.com', port=443): ⮑ Max retries exceeded with url: / (Caused by ConnectTimeoutError(...))предварительно> кодовый блок>Первый запрос выполнен успешно, поскольку сервер ответил в течение периода ожидания в одну секунду. В отличие от этого, второй запрос не был выполнен, поскольку тайм-аут был установлен на чрезвычайно короткий срок в десять миллисекунд, который истек до того, как удалось установить соединение.
Вы также можете передать кортеж в
timeoutсо следующими двумя элементами:
- Время ожидания подключения: время, в течение которого клиент может установить соединение с сервером
- Тайм-аут чтения: Время ожидания ответа после того, как клиент установит соединение
Оба этих элемента должны быть числами и могут иметь тип
intилиfloat:>>> requests.get("https://api.github.com", timeout=(3.05, 5)) <Response [200]>предварительно> кодовый блок>Если запрос устанавливает соединение в течение
3.05секунды и получает данные в течение5секунд после установления соединения, то ответ будет возвращен в том же виде, в каком он был получен ранее. Если время выполнения запроса истекло, функция вызовет либоConnectTimeout, либоReadTimeout, которые являются подклассами более общего исключенияTimeout:timeout_catcher.pyкодовый блок>import requests from requests.exceptions import Timeout try: response = requests.get("https://api.github.com", timeout=(3.05, 5)) except Timeout: print("The request timed out") else: print("The request did not time out")Ваша программа может перехватить исключение
Timeoutи отреагировать соответствующим образом.Повторное использование Соединений с Объектами Сеанса
До сих пор вы имели дело с высокоуровневыми
requestsAPI, такими какget()иpost(). Эти функции являются абстракциями от того, что происходит, когда вы отправляете свои запросы. Они скрывают детали реализации, такие как управление подключениями, поэтому вам не нужно беспокоиться о них.Под этими абстракциями находится класс под названием
Session. Если вам нужно точно настроить управление выполнением запросов или повысить производительность ваших запросов, вам может потребоваться напрямую использовать экземплярSession.Сеансы используются для сохранения параметров в разных запросах. Например, если вы хотите использовать одну и ту же аутентификацию для нескольких запросов, вы можете использовать сеанс:
persist_info_with_session.pyкодовый блок>1import requests 2from custom_token_auth import TokenAuth 3 4TOKEN = "<YOUR_GITHUB_PA_TOKEN>" 5 6with requests.Session() as session: 7 session.auth = TokenAuth(TOKEN) 8 9 first_response = session.get("https://api.github.com/user") 10 second_response = session.get("https://api.github.com/user") 11 12print(first_response.headers) 13print(second_response.json())В этом примере вы используете контекстный менеджер, чтобы гарантировать, что сеанс освободит ресурсы, когда они ему больше не понадобятся.
В строке 7 вы прикрепляете учетные данные пользователя GitHub к объекту session, используя свой пользовательский
TokenAuth. Вам нужно сделать это только один раз за сеанс, а затем вы можете выполнить несколько аутентифицированных запросов. Запросы будут сохранять учетные данные до тех пор, пока длится сеанс.В строках 9 и 10 вы затем делаете два запроса к аутентифицированному пользовательскому API, используя
session.get()вместоrequests.get().Основная оптимизация производительности сеансов осуществляется в форме постоянных подключений. Когда ваше приложение устанавливает соединение с сервером с помощью
Session, оно сохраняет это соединение в пуле подключений. Когда ваше приложение захочет снова подключиться к тому же серверу, оно повторно использует соединение из пула, а не устанавливает новое.Повторите неудачные запросы
При сбое запроса вы можете захотеть, чтобы ваше приложение повторило тот же запрос. Однако по умолчанию запросы не будут выполнять это за вас. Чтобы применить эту функциональность, вам необходимо реализовать пользовательский транспортный адаптер .
Транспортные адаптеры позволяют определить набор конфигураций для каждой службы, с которой вы взаимодействуете. Например, предположим, что вы хотите, чтобы все запросы на
https://api.github.comповторялись дважды, прежде чем, наконец, будет получено значениеRetryError. В этом случае вам следует создать транспортный адаптер, установить его параметрmax_retriesи подключить его к существующемуSession:retry_twice.pyкодовый блок>import requests from requests.adapters import HTTPAdapter from requests.exceptions import RetryError from urllib3.util.retry import Retry retry_strategy = Retry( total=2, status_forcelist=[429, 500, 502, 503, 504] ) github_adapter = HTTPAdapter(max_retries=retry_strategy) with requests.Session() as session: session.mount("https://api.github.com", github_adapter) try: response = session.get("https://api.github.com/") except RetryError as err: print(f"Error: {err}")В этом примере вы настроили свой сеанс таким образом, чтобы он повторялся максимум два раза, если ваш запрос к API GitHub не сработает должным образом. Объект
Retryпредоставляет вам детальный контроль над тем, какие коды состояния должны инициировать повторные попытки.Аргумент
max_retriesпринимает либо целое число, либо объектRetry. Использование объектаRetryпозволяет детально контролировать, какие ошибки повторяются. В то время как вы все еще можете передать простое целое число для базовых случаев, использование объектаRetryявляется современным подходом.Когда вы подключаете
HTTPAdapterкsession, тоsessionбудет придерживаться своей конфигурации для каждого запроса кhttps://api.github.com.Примечание: Хотя реализация, показанная выше, работает, вы не увидите никаких последствий от повторной попытки, если только что-то не в порядке с вашим сетевым подключением или серверами GitHub.
Если вы хотите поэкспериментировать с кодом, построенным на основе этого примера, и посмотреть, когда будут повторяться попытки, то вам повезло. Вы можете скачать материалы для этого руководства и ознакомиться с
retry_thrice.py:Получите свой код: Нажмите здесь, чтобы загрузить бесплатный пример кода, который показывает, как использовать библиотеку запросов Python.
Код в этом файле улучшен по сравнению с примером, показанным выше, путем добавления протоколирования для отображения выходных данных отладки. Это дает вам возможность отслеживать, когда Python пытается повторить попытку.
Requests поставляется в комплекте с интуитивно понятными реализациями тайм-аутов, транспортных адаптеров и сеансов, которые помогут вам сохранить эффективность вашего кода и устойчивость вашего приложения.
Заключение
Отличная работа! Вы дочитали учебник до конца и значительно расширили свои знания о мощной библиотеке запросов Python.
В этом руководстве вы узнали, как:
- Делайте запросы, используя различные HTTP-методы, такие как
GET,POST, иPUT- Настраивайте свои запросы, изменяя заголовки, аутентификацию, строки запроса и тексты сообщений
- Проверьте данные, которые вы отправляете на сервер, и данные, которые сервер отправляет вам обратно
.- Работа с Проверкой сертификатов TLS/SSL
- Эффективно использовать запросы с помощью
max_retries,timeout, сеансов и транспортных адаптеровПоскольку вы научились использовать запросы, вы готовы исследовать широкий мир веб—сервисов и создавать потрясающие приложения, используя захватывающие данные, которые они предоставляют.
Получите свой код: Нажмите здесь, чтобы загрузить бесплатный пример кода, который показывает, как использовать библиотеку запросов Python.
Часто задаваемые вопросы
Теперь, когда у вас есть некоторый опыт работы с библиотекой запросов Python, вы можете использовать вопросы и ответы, приведенные ниже, чтобы проверить свое понимание и резюмировать то, что вы узнали.
Эти часто задаваемые вопросы относятся к наиболее важным понятиям, которые вы рассмотрели в этом руководстве. Нажмите на переключатель Показывать/скрывать рядом с каждым вопросом, чтобы открыть ответ.
Нет, библиотека запросов не является частью стандартной библиотеки Python. Вам необходимо установить ее отдельно с помощью
pip.
Вы создаете
GETзапрос на Python, используя функциюrequests.get(), передавая желаемый URL в качестве аргумента.
Вы отправляете
POSTданные с запросами, передавая данные в параметрdataв функцииrequests.post(). Для данных в формате JSON используйте вместо этого параметрjson.
Вы добавляете заголовки к запросам в Python, передавая словарь заголовков параметру
headersв функцияхrequests.get()илиrequests.post().
response.textвозвращает содержимое ответа в виде строки, в то время какresponse.contentвозвращает его в виде необработанных байт. Используйтеresponse.text, если вы хотите работать с данными в виде строки.<отметить класс="marker-highlight"> Пройдите тест:отметить> Проверьте свои знания с помощью нашего интерактивного теста ”Библиотека запросов Python". По завершении вы получите оценку, которая поможет вам отслеживать прогресс в обучении:
<время работы/>![]()
Интерактивная викторина
Библиотека запросов PythonПроверьте свое понимание библиотеки запросов Python для выполнения HTTP-запросов и взаимодействия с веб-службами.
<статус завершения article-slug="python-requests" class="btn-group mb-0" data-api-article-bookmark-url="/api/v1/articles/python-requests/bookmark/" статус завершения data-api-article-url="/api/v1/articles/python-запросы/завершение_статуса/"> статус завершения> <кнопка поделиться bluesky-text="Интересная статья на #Python от @realpython.com :" email-body="Ознакомьтесь с этой статьей о Python: Библиотека запросов %0A%0APython (руководство)" email-subject="Статья о Python для вас" twitter-text="Интересная статья о #Python от @realpython:" url="https://realpython.com/python-requests /" url-title="Библиотека запросов Python (руководство)"> кнопка поделиться>Смотрите сейчас, к этому уроку прилагается соответствующий видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным руководством, чтобы углубить свое понимание: Создание HTTP-запросов с помощью Python
Back to Top