Как отправить HTTP-запрос с requests

онлайн тренажер по питону
Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Установка и настройка библиотеки requests

Библиотека requests не входит в стандартную поставку Python, поэтому её необходимо установить отдельно. Выполните следующую команду в терминале:

pip install requests

Для проверки успешной установки выполните:

import requests
print(requests.__version__)

Что такое HTTP-запросы и зачем нужна библиотека requests

HTTP (HyperText Transfer Protocol) — это протокол передачи данных между клиентом и сервером. requests — это внешняя библиотека Python, которая значительно упрощает отправку HTTP-запросов по сравнению со встроенными модулями urllib.

Основные преимущества requests

  • Простота в использовании и читаемость кода
  • Поддержка всех методов HTTP (GET, POST, PUT, DELETE, PATCH)
  • Автоматическая работа с JSON-данными
  • Встроенная поддержка cookies и сессий
  • Гибкая настройка заголовков и параметров
  • Обработка ошибок и исключений
  • Поддержка прокси-серверов и SSL-сертификатов

Основные HTTP-методы с практическими примерами

GET-запросы: получение данных

GET-запрос используется для получения данных с сервера без их изменения.

import requests

# Простой GET-запрос
response = requests.get('https://api.github.com')
print(response.status_code)  # 200
print(response.text)         # Содержимое ответа

Передача параметров в GET-запросе

# Передача параметров через словарь
params = {
    'q': 'python',
    'sort': 'stars',
    'order': 'desc',
    'page': 1
}

response = requests.get('https://api.github.com/search/repositories', params=params)
print(response.url)  # Проверяем итоговый URL с параметрами

POST-запросы: отправка данных

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

# POST-запрос с данными формы
data = {
    'username': 'test_user',
    'password': 'secure_password',
    'email': 'test@example.com'
}

response = requests.post('https://httpbin.org/post', data=data)
print(response.json())

POST-запрос с JSON-данными

# Отправка JSON-данных
json_data = {
    'title': 'Новый пост',
    'body': 'Содержимое поста',
    'userId': 1
}

response = requests.post(
    'https://jsonplaceholder.typicode.com/posts',
    json=json_data
)
print(response.json())

PUT-запросы: обновление данных

PUT-запрос используется для полного обновления существующих ресурсов.

update_data = {
    'id': 1,
    'title': 'Обновленный заголовок',
    'body': 'Новое содержимое',
    'userId': 1
}

response = requests.put(
    'https://jsonplaceholder.typicode.com/posts/1',
    json=update_data
)
print(f"Статус: {response.status_code}")
print(response.json())

PATCH-запросы: частичное обновление

PATCH используется для частичного обновления ресурса.

patch_data = {'title': 'Частично обновленный заголовок'}

response = requests.patch(
    'https://jsonplaceholder.typicode.com/posts/1',
    json=patch_data
)
print(response.json())

DELETE-запросы: удаление данных

DELETE-запрос используется для удаления ресурсов на сервере.

response = requests.delete('https://jsonplaceholder.typicode.com/posts/1')
print(f"Статус удаления: {response.status_code}")

Работа с заголовками HTTP

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

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json',
    'Accept': 'application/json'
}

response = requests.get('https://api.example.com/data', headers=headers)
print(response.status_code)

# Просмотр заголовков ответа
print(response.headers)

Управление cookies

Cookies используются для сохранения состояния между запросами.

# Отправка cookies
cookies = {'session_id': '123456', 'user_pref': 'dark_theme'}
response = requests.get('https://httpbin.org/cookies', cookies=cookies)

# Извлечение cookies из ответа
print(response.cookies)

# Использование объекта RequestsCookieJar
jar = requests.cookies.RequestsCookieJar()
jar.set('cookie_name', 'cookie_value', domain='httpbin.org', path='/cookies')
response = requests.get('https://httpbin.org/cookies', cookies=jar)

Обработка JSON-данных

JSON — наиболее популярный формат обмена данными в современных API.

# Получение JSON-данных
response = requests.get('https://jsonplaceholder.typicode.com/posts')

# Автоматическая десериализация JSON
try:
    data = response.json()
    print(f"Получено {len(data)} постов")
    print(f"Первый пост: {data[0]['title']}")
except requests.exceptions.JSONDecodeError:
    print("Ответ не содержит валидного JSON")

Обработка ошибок и исключений

Правильная обработка ошибок критически важна для надежности приложения.

import requests
from requests.exceptions import RequestException, HTTPError, ConnectionError, Timeout

def safe_request(url, method='GET', **kwargs):
    try:
        response = requests.request(method, url, timeout=10, **kwargs)
        response.raise_for_status()  # Вызывает исключение для HTTP-ошибок
        return response
    
    except HTTPError as e:
        print(f"HTTP ошибка: {e}")
        print(f"Код ответа: {e.response.status_code}")
    
    except ConnectionError as e:
        print(f"Ошибка подключения: {e}")
    
    except Timeout as e:
        print(f"Превышено время ожидания: {e}")
    
    except RequestException as e:
        print(f"Общая ошибка запроса: {e}")
    
    return None

# Использование функции
response = safe_request('https://api.github.com')
if response:
    print("Запрос успешен")

Настройка тайм-аутов

Тайм-ауты предотвращают бесконечное ожидание ответа от сервера.

# Единый тайм-аут для подключения и чтения
response = requests.get('https://api.github.com', timeout=5)

# Раздельные тайм-ауты (подключение, чтение)
response = requests.get('https://api.github.com', timeout=(3, 10))

# Отключение тайм-аута (не рекомендуется)
response = requests.get('https://api.github.com', timeout=None)

Работа с сессиями

Сессии позволяют сохранять cookies и настройки между запросами.

# Создание сессии
session = requests.Session()

# Настройка общих заголовков
session.headers.update({
    'User-Agent': 'MyApp/1.0',
    'Accept': 'application/json'
})

# Выполнение запросов через сессию
response = session.get('https://httpbin.org/get')
print(response.json())

# Сессия автоматически сохраняет cookies
login_data = {'username': 'user', 'password': 'pass'}
session.post('https://httpbin.org/login', data=login_data)

# Последующие запросы будут использовать сохраненные cookies
protected_response = session.get('https://httpbin.org/protected')

# Закрытие сессии
session.close()

Загрузка файлов

requests поддерживает загрузку файлов различными способами.

# Загрузка одного файла
with open('document.pdf', 'rb') as f:
    files = {'file': f}
    response = requests.post('https://httpbin.org/post', files=files)

# Загрузка нескольких файлов
files = {
    'file1': open('document1.pdf', 'rb'),
    'file2': open('document2.pdf', 'rb')
}
response = requests.post('https://httpbin.org/post', files=files)

# Не забывайте закрывать файлы
for file in files.values():
    file.close()

# Загрузка файла с дополнительными параметрами
files = {
    'file': ('report.pdf', open('report.pdf', 'rb'), 'application/pdf')
}
response = requests.post('https://httpbin.org/post', files=files)

Скачивание файлов

# Скачивание небольших файлов
response = requests.get('https://httpbin.org/image/png')
with open('downloaded_image.png', 'wb') as f:
    f.write(response.content)

# Скачивание больших файлов частями
url = 'https://httpbin.org/drip?duration=10&numbytes=1024'
response = requests.get(url, stream=True)

with open('large_file.bin', 'wb') as f:
    for chunk in response.iter_content(chunk_size=8192):
        f.write(chunk)

Использование прокси-серверов

# Настройка прокси
proxies = {
    'http': 'http://proxy.example.com:8080',
    'https': 'https://proxy.example.com:8080'
}

response = requests.get('https://api.github.com', proxies=proxies)

# Прокси с аутентификацией
proxies = {
    'http': 'http://user:password@proxy.example.com:8080',
    'https': 'https://user:password@proxy.example.com:8080'
}

Продвинутые возможности

Кастомные адаптеры

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

# Настройка повторных попыток
retry_strategy = Retry(
    total=3,
    status_forcelist=[429, 500, 502, 503, 504],
    method_whitelist=["HEAD", "GET", "OPTIONS"]
)

adapter = HTTPAdapter(max_retries=retry_strategy)
session = requests.Session()
session.mount("http://", adapter)
session.mount("https://", adapter)

Потоковые запросы

# Потоковая обработка больших ответов
response = requests.get('https://httpbin.org/stream/1000', stream=True)

for line in response.iter_lines():
    if line:
        print(line.decode('utf-8'))

Практические примеры использования

Работа с REST API

class GitHubAPI:
    def __init__(self, token):
        self.base_url = 'https://api.github.com'
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'token {token}',
            'Accept': 'application/vnd.github.v3+json'
        })
    
    def get_user(self, username):
        response = self.session.get(f'{self.base_url}/users/{username}')
        response.raise_for_status()
        return response.json()
    
    def create_repo(self, name, description=None):
        data = {'name': name}
        if description:
            data['description'] = description
        
        response = self.session.post(f'{self.base_url}/user/repos', json=data)
        response.raise_for_status()
        return response.json()

# Использование
api = GitHubAPI('your_token_here')
user_info = api.get_user('octocat')

Веб-скрейпинг

def scrape_website(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }
    
    try:
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        return response.text
    except RequestException as e:
        print(f"Ошибка при скрейпинге {url}: {e}")
        return None

# Использование
html_content = scrape_website('https://example.com')

Часто задаваемые вопросы

Как проверить успешность запроса?

response = requests.get('https://api.github.com')

# Способ 1: проверка атрибута ok
if response.ok:
    print("Запрос успешен")

# Способ 2: проверка кода состояния
if response.status_code == 200:
    print("Запрос успешен")

# Способ 3: использование raise_for_status()
try:
    response.raise_for_status()
    print("Запрос успешен")
except requests.exceptions.HTTPError:
    print("Ошибка в запросе")

Как получить финальный URL после редиректов?

response = requests.get('https://bit.ly/example')
print(f"Финальный URL: {response.url}")
print(f"История редиректов: {response.history}")

Как отключить SSL-проверку?

# Отключение SSL-проверки (не рекомендуется для продакшена)
response = requests.get('https://self-signed.badssl.com/', verify=False)

# Указание пути к сертификату
response = requests.get('https://api.example.com', verify='/path/to/cert.pem')

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

# Отключение редиректов
response = requests.get('https://example.com', allow_redirects=False)

# Ограничение количества редиректов через адаптер
from requests.adapters import HTTPAdapter

adapter = HTTPAdapter(max_retries=3)
session = requests.Session()
session.mount('http://', adapter)
session.mount('https://', adapter)

Как добавить базовую HTTP-аутентификацию?

from requests.auth import HTTPBasicAuth

# Способ 1: использование HTTPBasicAuth
auth = HTTPBasicAuth('username', 'password')
response = requests.get('https://api.example.com', auth=auth)

# Способ 2: передача кортежа
response = requests.get('https://api.example.com', auth=('username', 'password'))

Оптимизация производительности

Переиспользование соединений

# Используйте сессии для множественных запросов
session = requests.Session()

# Выполнение множественных запросов
urls = ['https://api.github.com/users/user1', 'https://api.github.com/users/user2']
results = []

for url in urls:
    response = session.get(url)
    results.append(response.json())

session.close()

Настройка пула соединений

from requests.adapters import HTTPAdapter

# Увеличение размера пула соединений
adapter = HTTPAdapter(pool_connections=100, pool_maxsize=100)
session = requests.Session()
session.mount('http://', adapter)
session.mount('https://', adapter)

Безопасность при работе с requests

Защита от атак

# Всегда используйте HTTPS для передачи чувствительных данных
response = requests.get('https://api.example.com')

# Проверяйте SSL-сертификаты
response = requests.get('https://api.example.com', verify=True)

# Используйте переменные окружения для токенов
import os
token = os.environ.get('API_TOKEN')
headers = {'Authorization': f'Bearer {token}'}

Валидация данных

def validate_response(response):
    """Валидация ответа API"""
    if not response.ok:
        raise requests.exceptions.HTTPError(f"HTTP {response.status_code}")
    
    content_type = response.headers.get('Content-Type', '')
    if 'application/json' not in content_type:
        raise ValueError("Ответ не является JSON")
    
    return response.json()

# Использование
response = requests.get('https://api.example.com')
data = validate_response(response)

Заключение

Библиотека requests — это мощный и гибкий инструмент для работы с HTTP-запросами в Python. Она предоставляет простой интерфейс для решения сложных задач, от простого получения данных до создания полноценных API-клиентов.

Основные принципы эффективного использования requests:

  • Всегда обрабатывайте ошибки и исключения
  • Используйте сессии для множественных запросов
  • Настраивайте тайм-ауты для предотвращения блокировок
  • Применяйте правильную аутентификацию и безопасность
  • Оптимизируйте производительность через переиспользование соединений

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

Новости