Работа с HTTP в Python: практическое применение requests
Основные методы работы с HTTP запросами в Python
Библиотека requests предоставляет удобный интерфейс для отправки HTTP запросов. Установка выполняется командой pip install requests. После импорта (import requests) можно вызывать методы get() и post(). Эти методы возвращают объект ответа, содержащий статус код, заголовки, тело и другую информацию.
import requests
# GET запрос
response = requests.get('https://httpbin.org/get')
print(response.status_code)
print(response.text)
# POST запрос с JSON данными
payload = {'key': 'value'}
response = requests.post('https://httpbin.org/post', json=payload)
print(response.json())
Python requests get (get-запрос через requests в python)
Пояснение: метод get() отправляет GET запрос, post() отправляет POST запрос. Аргумент json автоматически сериализует словарь в JSON и устанавливает заголовок Content-Type: application/json. Ответ можно прочитать как текст (.text), как JSON (.json()), или как байты (.content).
Типичная проблема: при вызове .json() на не JSON ответе возникает исключение ValueError. Решение: проверять статус код (response.raise_for_status()) или использовать try-except.
try:
data = response.json()
except ValueError:
print('Ответ не содержит JSON')
Get html python (получение html-содержимого через http в python)
Цель: базовое получение и отправка данных через HTTP.
Как отправить GET запрос с параметрами?
Для передачи параметров запроса используется аргумент params, который принимает словарь или список кортежей.
params = {'q': 'python requests', 'page': 1}
response = requests.get('https://httpbin.org/get', params=params)
print(response.url) # https://httpbin.org/get?q=python+requests&page=1
Url запрос python (работа с url в python)
Пояснение: библиотека самостоятельно кодирует параметры и добавляет их к URL. Если значение параметра None, оно будет пропущено.
Ошибка: при передаче параметров с кириллицей может некорректно кодироваться. Решение: requests кодирует в UTF-8 по умолчанию, но можно передать уже закодированную строку.
Как отправить POST запрос с JSON или формой?
Для JSON используется аргумент json, для формы data.
# JSON
response = requests.post('https://httpbin.org/post', json={'key': 'value'})
# Форма (application/x-www-form-urlencoded)
response = requests.post('https://httpbin.org/post', data={'key': 'value'})
# Форма с файлом (multipart)
files = {'file': ('filename.txt', b'content')}
response = requests.post('https://httpbin.org/post', files=files)
Python urllib request (отправка запросов с помощью urllib.request в python)
Пояснение: при передаче data со словарём данные кодируются как форма. Для загрузки файлов используется аргумент files.
Проблема: если нужно отправить JSON, но передать data=json.dumps(payload), то заголовок Content-Type не будет установлен. Решение: использовать json или явно задать заголовки.
response = requests.post(url, data=json.dumps(payload), headers={'Content-Type': 'application/json'})
Files upload python (загрузка файлов на сервер с помощью python (requests, flask))
Как обработать ошибки HTTP?
Метод raise_for_status() вызывает исключение HTTPError если статус код 4xx или 5xx.
response = requests.get('https://httpbin.org/status/404')
if response.ok:
print('Успех')
else:
print(f'Ошибка {response.status_code}')
# Или с исключением
try:
response.raise_for_status()
except requests.exceptions.HTTPError as err:
print(f'HTTP ошибка: {err}')
Python requests method (методы http-запросов в python (get, post, put, delete) с requests)
Пояснение: response.ok возвращает True для кодов 200-399. Исключения удобны для прерывания выполнения при ошибке.
Ошибка: raise_for_status() не вызывается автоматически. Программист должен явно её вызывать.
Как использовать сессии для сохранения состояния?
Объект Session позволяет сохранять куки, заголовки и параметры между запросами.
with requests.Session() as session:
session.headers.update({'User-Agent': 'my-app'})
response1 = session.get('https://httpbin.org/cookies/set?name=value')
response2 = session.get('https://httpbin.org/cookies')
print(response2.json()) # {'cookies': {'name': 'value'}}
Python request data (извлечение данных из http-запроса (request) в python)
Пояснение: сессия автоматически управляет куками, переданными сервером. Можно задать базовый URL через session.mount или использовать адаптеры.
Проблема: если сессия не закрыта, ресурсы могут не освободиться. Использование менеджера контекста гарантирует закрытие.
Как настроить таймаут и обработку таймаута?
Аргумент timeout задаёт максимальное время ожидания ответа.
try:
response = requests.get('https://httpbin.org/delay/5', timeout=3)
except requests.exceptions.Timeout:
print('Запрос превысил время ожидания')
Python send request (отправка http-запроса в python (requests.get/post))
Пояснение: таймаут применяется ко всем операциям (соединение, чтение). Можно задать кортеж (connect_timeout, read_timeout).
Ошибка: отсутствие таймаута может привести к зависанию программы. Рекомендуется всегда указывать таймаут.
Как отправить запрос с аутентификацией?
Для базовой HTTP аутентификации используется аргумент auth.
from requests.auth import HTTPBasicAuth
response = requests.get('https://httpbin.org/basic-auth/user/pass',
auth=HTTPBasicAuth('user', 'pass'))
# Сокращенная форма
response = requests.get(url, auth=('user', 'pass'))
Python post file (отправка файла через post-запрос (requests.post(file)) в python)
Пояснение: для Digest аутентификации используется HTTPDigestAuth. Для OAuth2 нужны отдельные библиотеки.
Проблема: пароль может быть виден в коде. Рекомендуется хранить учётные данные в переменных окружения.
Как игнорировать ошибки SSL сертификата?
Установка verify=False отключает проверку SSL (небезопасно).
response = requests.get('https://self-signed.badssl.com/', verify=False)
# Отключение предупреждения
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
Python requests параметры (передача параметров в get/post запросах requests в python)
Пояснение: в production следует использовать собственный сертификат через аргумент verify='/path/to/cert.pem'.
Ошибка: SSLError при невалидном сертификате. Решение: настроить verify или добавить сертификат CA.
Как использовать прокси?
Прокси задаются через словарь proxies.
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
response = requests.get('http://example.org', proxies=proxies)
# Для аутентификации на прокси
proxies = {
'http': 'http://user:pass@10.10.1.10:3128'
}
Пояснение: можно использовать SOCKS прокси, установив pip install requests[socks] и указав socks5://....
Проблема: при использовании прокси без аутентификации может возникать ошибка ConnectionError. Проверьте доступность прокси.
Расширенные примеры использования requests
Потоковая загрузка файлов
Для скачивания больших файлов используется параметр stream=True, чтобы содержимое не загружалось сразу в память.
import requests
url = 'https://www.example.com/largefile.zip'
response = requests.get(url, stream=True)
response.raise_for_status()
with open('largefile.zip', 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
Файл largefile.zip сохранен по частям без загрузки в память целиком.
Пояснение: iter_content возвращает итератор по фрагментам ответа. Необходимо обязательно закрывать ответ, но менеджер контекста делает это автоматически.
Повторные попытки при ошибках (Retry)
Используется HTTPAdapter с политикой повторных попыток.
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
retry = Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504])
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
try:
response = session.get('https://httpbin.org/status/500')
print(response.status_code)
except requests.exceptions.RetryError:
print('Все попытки исчерпаны')
После трех попыток выбрасывается RetryError, если сервер продолжает возвращать 500.
Пояснение: backoff_factor определяет задержку между попытками (0.5, 1, 2 секунды). status_forcelist определяет коды, при которых нужно повторить.
Использование собственных заголовков и кук
Можно передать заголовки через аргумент headers и куки через cookies.
import requests
headers = {
'User-Agent': 'Mozilla/5.0',
'Accept': 'application/json'
}
cookies = {'session_id': 'abc123'}
response = requests.get('https://httpbin.org/headers', headers=headers, cookies=cookies)
print(response.json())
{
"headers": {
"Accept": "application/json",
"Cookie": "session_id=abc123",
"User-Agent": "Mozilla/5.0",
...
}
}
Пояснение: заголовки перезаписывают значения по умолчанию. Куки можно также управлять через session.cookies.
Загрузка файла на сервер с метаданными
Передача файла вместе с дополнительными полями формы.
import requests
url = 'https://httpbin.org/post'
files = {
'file': ('report.pdf', open('report.pdf', 'rb'), 'application/pdf'),
'description': (None, 'Annual report')
}
response = requests.post(url, files=files)
print(response.json())
{
"files": {"file": "...base64..."},
"form": {"description": "Annual report"}
}
Пояснение: кортеж может содержать имя файла, тело, MIME-тип и необязательные заголовки. Для полей без файла (None) передаются как обычные данные формы.
Отправка запроса с keep-alive и пулом соединений
По умолчанию requests использует пул соединений. Можно настроить его размер.
import requests
from requests.adapters import HTTPAdapter
session = requests.Session()
adapter = HTTPAdapter(pool_connections=10, pool_maxsize=20)
session.mount('https://', adapter)
# Все запросы через эту сессию будут использовать пул из 10 соединений
responses = [session.get('https://httpbin.org/get') for _ in range(10)]
Выполнено 10 запросов с переиспользованием TCP соединений.
Пояснение: pool_connections количество соединений для одного хоста, pool_maxsize общий размер пула. Это повышает производительность при множестве запросов.
Асинхронные запросы с использованием threading и requests
Для параллельной отправки можно объединить requests с потоками.
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
urls = ['https://httpbin.org/delay/1' for _ in range(5)]
def fetch(url):
return requests.get(url).status_code
with ThreadPoolExecutor(max_workers=5) as executor:
futures = {executor.submit(fetch, url): url for url in urls}
for future in as_completed(futures):
print(future.result())
200 200 200 200 200 (Все запросы выполнены почти одновременно, каждый с задержкой 1 секунда)
Пояснение: ThreadPoolExecutor позволяет отправлять запросы параллельно. Каждый поток имеет собственное соединение. Для большого числа запросов лучше использовать aiohttp или grequests.