Как отправить запрос через интернет

Не знаете, как отправить запрос через интернет? Мы перевели с «технического

Бесплатная консультация юриста

+7 (800) 301-07-30

Реклама jurik.ru

В современной разработке взаимодействие с API и веб-сервисами — это ежедневная задача. Умение правильно формировать, отлаживать и автоматизировать HTTP-запросы является базовым навыком. В этой статье мы подробно разберем основные инструменты: консольную утилиту cURL, популярную библиотеку Python Requests, а также современные средства автоматической конвертации между ними.

Основы HTTP-запросов: что нужно знать

Любой HTTP-запрос состоит из нескольких ключевых компонентов. Понимание их роли критически важно для успешной интеграции:

  • Метод (Verb): GET, POST, PUT, PATCH, DELETE и др. Определяет действие над ресурсом.
  • URL (Endpoint): Адрес ресурса, к которому обращаемся (схема, хост, путь, query-параметры).
  • Заголовки (Headers): Метаданные запроса: Content-Type, Authorization, User-Agent, Accept, Cookie и кастомные заголовки API.
  • Тело запроса (Body/Payload): Данные, отправляемые на сервер (JSON, Form Data, Multipart, бинарные файлы). Обычно используется с POST/PUT/PATCH.
  • Параметры строки запроса (Query Params): Ключ-значение в URL после знака ? (фильтрация, пагинация, токены).

cURL: стандарт де-факто для командной строки

cURL (Client URL) — это мощнейший инструмент для передачи данных по сети. Он доступен в Linux, macOS и Windows (начиная с Windows 10 build 17063).

Базовый синтаксис

curl [опции] [URL]

Часто используемые флаги

Флаг Описание
-X, --request Указать HTTP-метод (GET, POST, PUT…)
-H, --header Добавить (можно многократно)
-d, --data Данные для отправки в теле (включает POST автоматически)
--data-urlencode Данные с URL-кодированием (для application/x-www-form-urlencoded)
-F, --form Отправка multipart/form-data (файлы, формы)
-u, --user Basic Auth (user:password)
-b, --cookie Отправить куки
-c, --cookie-jar Сохранить куки в файл
-v, --verbose Подробный вывод (заголовки запроса/ответа, handshake)
-s, --silent Тихий режим (скрыть прогресс-бар)
-S, --show-error Показывать ошибки даже в silent режиме
-L, --location Следовать редиректам (3xx)
--compressed Запросить сжатый ответ (gzip, deflate, br, zstd)
--fail-with-body Возвращать код ошибки при 4xx/5xx, но выводить тело ответа
--cert / --key Клиентские сертификаты для mTLS

Примеры реальных сценариев

GET запрос с авторизацией и параметрами

curl -sS -L --compressed 
 -H "Authorization: Bearer *" 
 -H "Accept: application/json" 
 "https://api.example.com/v1/resources?limit=10&sort=desc"

POST JSON с кастомными заголовками

curl -X POST "https://api.example.com/v1/orders" 
 -H "Content-Type: application/json" 
 -H "X-Request-ID: " 
 -d '{"product_id": 123, "quantity": 2, "metadata": {"source": "web"}}'

Отправка файла (multipart/form-data)

curl -X POST "https://api.example.com/upload" 
 -H "Authorization: Bearer " 
 -F "file=@/path/to/document.pdf" 
 -F "description=Monthly report"

Сложный пример из практики (браузероподобный запрос)

Часто приходится копировать запрос из DevTools (Copy as cURL). Такой запрос содержит множество заголовков для имитации браузера:

curl "https://www.python.org/" 
 --compressed 
 -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"  -H "Accept-Language: en-US,en;q=0.5" 
 -H "Accept-Encoding: gzip, deflate, br, zstd" 
 -H "Referer: https://www.google.com/" 
 -H "Connection: keep-alive" 
 -H "Cookie: _ga=*; session_id=*" 
 -v

Python Requests: «HTTP для людей»

Библиотека requests, де-факто стандарт для HTTP в Python. Установка: pip install requests.

Базовая структура

import requests

response = requests.request(
 method="GET",
 url="https://api.example.com/data",
 params={"key": "value"}, # Query parameters
 headers={"Authorization": "Bearer *"},
 data=None, # Body для form/data или bytes
 json=None, # Автоматически делает JSON и ставит Content-Type
 files=None, # Multipart files
 auth=("user", "pass"), # Basic Auth
 cookies={"session": "*"},
 timeout=30, # Критически важно!
 allow_redirects=True,
 verify=True, # SSL verification (не ставьте False в проде!)
 cert=("/path/client.crt", "/path/client.key") # mTLS
)

print(response.status_code)
print(response.headers)
print(response.json) # или .text, .content

Типичные ошибки при миграции с cURL

  1. Параметр data vs json:
    • В cURL: -d '{"a":1}' -H "Content-Type: application/json"
    • В Requests: используйте json={"a": 1}. Библиотека сама сериализует и выставит . Если передать строку в data, Content-Type нужно ставить вручную.
  2. Файлы (-F vs files):
    • cURL: -F "file=@test.txt"
    • Requests: files={"file": open("test.txt", "rb")}. Обратите внимание: если в cURL файл передавался через -d @file.json (как raw body), в Requests это data=open("file.json", "rb").read, а не files.
  3. URL-кодировка (--data-urlencode): В Requests передавайте словарь в data (для form) или params (для query).
  4. User-Agent: Requests по умолчанию шлет python-requests/2.x.x. Многие API блокируют его. Всегда задавайте свой: headers={"User-Agent": "MyApp/1.0"}.
  5. Редиректы: cURL по умолчанию не следует за редиректами (нужен -L). Requests следует по умолчанию (allow_redirects=True).
  6. SSL/TLS: cURL часто прощает самоподписанные сертификаты с -k. В Requests verify=False (небезопасно) или verify="/path/to/ca_bundle.pem".

Автоматизация конвертации: CurlFetch2Py

Ручное переписывание сложных cURL-команд (с десятками заголовков, куками, multipart-данными) чревато ошибками. На помощь приходит библиотека CurlFetch2Py.

Установка и базовое использование

pip install curl_fetch2py
from curl_fetch2py import CurlFetch2Py

converter = CurlFetch2Py

curl_command = '''
curl "https://api.topvisor.ru/v2/json/get/bank/history" 
 -H "Content-Type: application/json" 
 -H "User-Id: " 
 -H "Authorization: Bearer " 
 -d '{"fields": ["info", "sum", "date"], "orders": [{"name": "date", "direction": "DESC"}], "limit": 10}'
'''

parsed = converter.parse_curl_context(curl_command)

python_code = converter.to_requests_code(parsed)
print(python_code)

Что делает парсер за вас

  • Правильно определяет метод (POST, если есть -d/-F, иначе GET).
  • Парсит все заголовки (-H), нормализует ключи.
  • Разбирает тело: JSON, Form Data, Multipart (файлы через @).
  • Извлекает куки из -b / --cookie.
  • Обрабатывает аутентификацию (-u).
  • Поддерживает Fetch API формат (JS fetch(...)) через метод parse_fetch_context.

Пример результата генерации

import requests

url = "https://api.topvisor.ru/v2/json/get/bank/history"
headers = {
 "Content-Type": "application/json",
 "User-Id": "",
 "Authorization": "Bearer ",
}
json_data = {
 "fields": ["info", "sum", "date"],
 "orders": [{"name": "date", "direction": "DESC"}],
 "limit": 10,
}

response = requests.post(url, headers=headers, json=json_data, timeout=30)
print(response.status_code)
print(response.json)

Отладка и диагностика: «Почему не работает?»

Даже с идеальным кодом запросы могут падать. Алгоритм диагностики:

  1. Сравните «на проводах»: Используйте Wireshark, mitmproxy или Fiddler. Сравните байт-в-байт запрос из cURL (рабочий) и из Python (нерабочий). Обратите внимание на:
    • Порядок заголовков (редко важно, но бывает).
    • Наличие/отсутствие Content-Length vs Transfer-Encoding: chunked.
    • Точное содержимое тела (пробелы, переносы строк, кодировка UTF-8).
  2. Проверьте редиректы: Выведите response.history в Python. cURL без -L остановится на 301/302, а Requests уйдет дальше, возможно, теряя заголовки Authorization при смене хоста.
  3. User-Agent и бот-детекция: Если сервер возвращает 403/Cloudflare challenge — поставьте реальный User-Agent и, при необходимости, имитируйте TLS-фингерпринт (библиотека curl_cffi или httpx с http2=True).
  4. Кодировка тела: При отправке JSON через data=json_string убедитесь, что строка в UTF-8 и не содержит BOM. Лучше всегда использовать параметр json=dict_obj.
  5. Куки и сессии: Для цепочек запросов используйте requests.Session — он автоматически хранит куки и connection pooling.

Продвинутые темы и лучшие практики

Асинхронность (async/await)

Для высоконагруженных задач используйте httpx или aiohttp. Они поддерживают тот же API, что и requests, но асинхронны.

import httpx

async def fetch_all(urls):
 async with httpx.AsyncClient(timeout=30.0, headers={"User-Agent": "MyBot/1.0"}) as client:
 tasks = [client.get(url) for url in urls]
 responses = await asyncio.gather(*tasks)
 return responses

Retry и Backoff

Сеть ненадежна. Настройте повторные попытки с экспоненциальной задержкой.

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

retry_strategy = Retry(
 total=3,
 backoff_factor=1,
 status_forcelist=[429, 500, 502, 503, 504],
 allowed_methods=["HEAD", "GET", "OPTIONS", "POST"] # POST с идемпотентностью!
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session = requests.Session
session.mount("https://", adapter)
session.mount("http://", adapter)

Безопасность: секреты не в коде

Никогда не хардкодьте токены, API-ключи, пароли.

  • Используйте переменные окружения (os.getenv("API_TOKEN")).
  • В продакшене: Vault, AWS Secrets Manager, Doppler, .env файлы (только для дева).
  • В примерах выше чувствительные данные заменены на *.

mTLS (Mutual TLS)

Если API требует клиентский сертификат:

# cURL
curl --cert client.crt --key client.key "https://secure.api.com"

requests.get("https://secure.api.com", cert=("client.crt", "client.key"), verify="ca_bundle.pem")

Чек-лист перед отправкой в прод

  • [ ] Установлен адекватный timeout (connect + read).
  • [ ] Обработаны коды ошибок (4xx, 5xx) через response.raise_for_status или ручную проверку.
  • [ ] Логируются: URL, метод, статус код, время ответа, ID запроса (есть в заголовках), НЕ логируются тела с секретами/ПДн.
  • [ ] Используется Session для пулинга соединений.
  • [ ] Реализованы Retry с идемпотентностью (не ретраить платежи дважды без ключа идемпотентности).
  • [ ] Проверена работа за корпоративным прокси (переменные HTTP_PROXY, HTTPS_PROXY или параметр proxies в requests).
  • [ ] Тесты на моках (responses, httpretty, pytest-httpx) и интеграционные тесты на стенде.

Отправка HTTP-запросов — это не просто «вызов функции». Это работа с протоколом, сериализацией, безопасностью, отказоустойчивостью и наблюдаемостью. Начните с cURL для исследования и отладки, автоматизируйте рутину конвертации через CurlFetch2Py, пишите продакшн-код на requests (или httpx для асинхронности), всегда используйте таймауты и ретраи, и никогда не храните секреты в репозитории.

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