<jupyter_start><jupyter_text>Requests в PythonБиблиотека requests является стандартом де-факто для реализации отправки HTTP-запросов в Python. В целом процесс: клиент (например браузер или скрипт Python, использующий библиотеку requests) отправляет данные на URL, а сервер с этим URL считывает данные, решает, что с ними делать, и отправляет клиенту ответ. После этого клиент может решить, что делать с полученными в ответе данными.В составе запроса клиент отправляет данные по методу запроса. Наиболее распространенными методами запроса являются GET, POST и PUT. Запросы GET обычно предназначены только для чтения данных без их изменения, а запросы POST и PUT обычно предназначаются для изменения данных на сервере.  Метод GETМетод GET предписывает, что вы пытаетесь получить или извлечь некоторые данные из указанного ресурса. Чтобы отправить GET запрос, необходимо вызвать метод requests.get(url).<jupyter_code>import requests

response = requests.get('http://httpbin.org')<jupyter_output><empty_output><jupyter_text>Такой же запрос делает и браузер для просмотра этой страницы. Отличие в том, что библиотека requests не может выполнить рендеринг кода HTML, поэтому мы получим просто код HTML и другую информацию, содержащуюся в ответе.  Коды состоянияКоты о кодах: * 1XX — информационный сообщения, например: 102 Processing — запрос принят, но на его обработку понадобится длительное время. * 2XX — информируют о случаях успешного принятия и обработки запроса клиента* 3XX — сообщают клиенту, что для успешного выполнения операции необходимо сделать другой запрос, как правило, по другому URI* 4XX — ошибка на стороне клиента* 5XX — ошибка на стороне сервераОбычно при выполнении запросов мы хотим получить коды состояния в диапазоне 200.Библиотека requests понимает, что коды состояния 4XX и 5XX сигнализируют об ошибках, и поэтому при возврате этих кодов состояния объекту ответа на запрос присваивается значение False. Также вместо условия if можно генерировать исключение специального типа HTTPError, если запрос был неудачен. Сделать это можно используя метод **.raise_for_status()**<jupyter_code>if response:
    print ('OK')
else:
    print('Wrong')<jupyter_output>OK<jupyter_text>Посмотреть статус код:<jupyter_code>print(response.status_code)  # >>> 200<jupyter_output>200<jupyter_text>headersЗаголовки ответа сервера могут дать много полезной информации, например, тип содержимого ответа, ограничение по времени, в течение которого ответ будет кэшироваться и т.д. Чтобы просмотреть содержимое заголовков, необходимо обратиться к свойству объекта Response.headersЗаголовки отправляются вместе с запросом и возвращаются с ответом. Заголовки используются для того, чтобы клиент и сервер понимали, как интерпретировать данные, отправляемые и получаемые в запросе и ответе.Заголовок **content type** показывает формат данных, например HTML, JSON, PDF, обычный текст и т.д.При обращении к свойству Response.headers будет возвращен схожий со словарем объект, позволяющий получить доступ к значениям заголовков полученного ответа по ключу. Например, чтобы определить тип полезного содержимого ответа, получаем доступ к значению заголовка Content-Type:*Спецификация HTTP определяет названия заголовков без учета регистра! Можно обращаться к заголовкам без учета регистра.*Посмотреть заголовки (словарь):<jupyter_code>print(response.headers)
print(response.headers['Content-Type'])<jupyter_output>{'Date': 'Fri, 25 Mar 2022 10:22:27 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Content-Length': '9593', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}
text/html; charset=utf-8<jupyter_text>.text & .content & .json() Ответ на успешный запрос GET часто содержит в сообщении полезное содержимое (payload). Используя атрибуты и методы объекта Response, мы можем просматривать его в различных форматах.* Атрибут .text возвращает cодержание/контент ответа сервера в юникоде, например для html-страницы, можно увидеть код html.* Атрибут .content возвращает содержание ответа сервера, представленное в байтах (бинарный вид).<jupyter_code>print(response.text)
print(response.content)<jupyter_output><empty_output><jupyter_text>Содержимое ответа также может представлять собой сериализованную строку в формате JSON. Поэтому для того, чтобы в результате получить словарь, можно взять строку str, полученную из свойства Response.text, и десериализовать ее с помощью метода json.loads(). Однако более простой способ выполнить эту задачу — использовать метод нашего объекта Response.json()<jupyter_code>response.json()<jupyter_output><empty_output><jupyter_text>Query String Parameters - параметры строки запросаGET запрос не имеет тела сообщения. Но, это не означает, что с его помощью нельзя передать серверу никакую информацию. Это можно делать с помощью GET параметров. Чтобы добавить GET параметры к запросу, нужно в конце URL-адреса поставить знак ? и задавать их после него по следующему правилу: **имя_параметра1=значение_параметра1&имя_параметра2=значение_параметра2.** Разделителем между параметрами служит знак &.Для передачи GET параметров запроса необходимо передать нужную информацию в именованный параметр params метода .get()<jupyter_code>import requests
# Поиск requests в репозиториях GitHub
response = requests.get(
    'https://api.github.com/search/repositories',
    params={'q': 'requests+language:python'},
)
# Просматриваем значения атрибутов результатов поиска репозитория requests
json_response = response.json()
repository = json_response['items'][0]
print(f'Repository name: {repository["name"]}')
print(f'Repository description: {repository["description"]}')<jupyter_output><empty_output><jupyter_text>Можно передавать значения в params метода get() не только в виде словаря, но и в виде списка кортежей или бинарном виде:<jupyter_code>params=[('q', 'requests+language:python'), ('p', 'some value')]
params=b'q=requests+language:python'<jupyter_output><empty_output><jupyter_text>Request Headers - использование заголовков в запросахДля того, чтобы используя requests, настроить содержимое заголовков запроса, необходимо передать словарь в именованный параметр **headers**. Например, добавим ключевые слова для уточнения результатов поиска, указав точно text-match текстовое соответствие для поиска (тип контента) в заголовок Accept.Заголовок Accept сообщает серверу, какие типы контента может обрабатывать ваше приложение. В нашем случае, поскольку вы хотите, что бы учитывались дополнительные уточняющие параметры поиска, вы устанавливаете для этого заголовка значение application / vnd.github.v3.text-match + json. Это значение является проприетарным для заголовка Accept, то есть зарезервированным GitHub для подобных случаев, и указывает на поиск содержимого в формате JSON.<jupyter_code>import requests
response = requests.get(
    'https://api.github.com/search/repositories',
    params={'q': 'requests+language:python'},
    headers={'Accept': 'application/vnd.github.v3.text-match+json'},
)
# выведем в консоли массив всех совпадений `text-matches`,
# заданные для уточнения результатов поиска
json_response = response.json()
repository = json_response['items'][0]
print(f'Text matches: {repository["text_matches"]}')<jupyter_output>Text matches: [{'object_url': 'https://api.github.com/repositories/4290214', 'object_type': 'Repository', 'property': 'description', 'fragment': 'Requests + Gevent = <3', 'matches': [{'text': 'Requests', 'indices': [0, 8]}]}]
{'fraction_non_alphanumeric': 0.07871174662568489, 'fraction_numerical': 0.007884538286783375, 'mean_word_length': 6.755440414507772, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 36, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '170314', 'license': 'MIT', 'n_tokens_mistral': 2753, 'n_tokens_neox': 3199, 'n_words': 786, 'path': 'Learning-requests.ipynb', 'repo_name': 'EmptyTuple/rotavator-', 'size': '7483'}