Как выполнять HTTP запросы в Python: обзор инструментов
Основной подход: библиотека requests
Библиотека requests предоставляет высокоуровневый интерфейс для HTTP запросов. Она проще в использовании по сравнению с urllib и поддерживает все основные методы: GET, POST, PUT, DELETE и другие. Для начала работы необходимо установить библиотеку: pip install requests.
import requests
response = requests.get('https://api.example.com/data')
print(response.status_code)
print(response.json())Python urls (работа с url в python (requests))
В этом примере выполняется GET запрос, проверяется статус ответа и извлекаются данные в формате JSON. Библиотека автоматически обрабатывает кодировку, заголовки и cookies.
Типичные ошибки:
- Ошибка соединения (ConnectionError) - если сервер недоступен.
- Таймаут (Timeout) - если ответ не получен вовремя. Рекомендуется всегда задавать таймауты:
requests.get(url, timeout=5). - HTTP ошибки (404, 500) - статус коды можно проверять через
response.raise_for_status().
Как сделать GET запрос с параметрами строки запроса?
params = {'key1': 'value1', 'key2': 'value2'}
response = requests.get('https://httpbin.org/get', params=params)
print(response.url) # https://httpbin.org/get?key1=value1&key2=value2Параметры автоматически кодируются и добавляются к URL.
Проблема: если параметры содержат специальные символы, requests их URL-кодирует, но иногда нужно избежать двойного кодирования. Используйте params с готовыми строками.
Как отправить POST запрос с данными формы?
data = {'username': 'user', 'password': 'pass'}
response = requests.post('https://httpbin.org/post', data=data)
print(response.json())Данные формы автоматически кодируются в application/x-www-form-urlencoded.
Как отправить POST запрос с JSON?
import json
payload = {'key': 'value'}
response = requests.post('https://httpbin.org/post', json=payload)
print(response.json())Библиотека автоматически устанавливает заголовок Content-Type: application/json.
Ошибка: если передать словарь в data вместо json, данные будут отправлены как форма, а не как JSON.
Как работать с сессиями и поддерживать cookies?
session = requests.Session()
session.get('https://httpbin.org/cookies/set?name=value')
response = session.get('https://httpbin.org/cookies')
print(response.json()) # cookies сохраняются между запросамиСессии также используют пул соединений для повышения производительности.
Проблема: cookies могут не сохраняться, если сервер использует HttpOnly или Secure флаги, но requests их обрабатывает.
Как установить пользовательские заголовки?
headers = {'User-Agent': 'MyApp/1.0'}
response = requests.get('https://httpbin.org/headers', headers=headers)
print(response.json())Вариант: библиотека urllib (стандартная библиотека)
Модуль urllib.request позволяет выполнять HTTP запросы без сторонних зависимостей. Однако требует больше ручной работы.
Как сделать GET запрос с помощью urllib?
from urllib.request import urlopen
response = urlopen('https://api.example.com/data')
print(response.status)
data = response.read().decode('utf-8')Ответ нужно декодировать вручную. Для JSON потребуется дополнительно импортировать json.
Ошибки: Необходимо обрабатывать исключения (URLError, HTTPError). Нет автоматического таймаута.
Как сделать POST запрос с данными?
import urllib.request
import urllib.parse
data = urllib.parse.urlencode({'key': 'value'}).encode('utf-8')
req = urllib.request.Request('https://httpbin.org/post', data=data)
response = urllib.request.urlopen(req)
print(response.read().decode())Данные кодируются вручную.
Проблема: нет автоматического управления cookies, требуется использовать HTTPCookieProcessor.
Вариант: библиотека httpx
httpx - современная библиотека с поддержкой синхронного и асинхронного режимов, HTTP/2.
Как сделать GET запрос с httpx?
import httpx
response = httpx.get('https://httpbin.org/get')
print(response.status_code)
print(response.json())Интерфейс похож на requests, но добавлена поддержка HTTP/2 и асинхронных вызовов.
Ошибка: httpx требует установки отдельно (pip install httpx). Для HTTP/2 нужен дополнительный пакет pip install httpx[http2].
Вариант: библиотека aiohttp (асинхронная)
Для высоконагруженных приложений, где требуется много параллельных запросов, используется aiohttp.
Как выполнить асинхронный GET запрос?
import aiohttp
import asyncio
async def fetch():
async with aiohttp.ClientSession() as session:
async with session.get('https://httpbin.org/get') as response:
return await response.json()
result = asyncio.run(fetch())
print(result)Требуется понимание асинхронного программирования.
Проблемы: сложность отладки, необходимость правильно управлять сессиями.
Расширенные примеры работы с URL в Python
1. Обработка параметров с кодировкой специальных символов
import requests
params = {'q': 'python requests+urllib', 'page': 1}
response = requests.get('https://httpbin.org/get', params=params)
print('URL:', response.url)
# Вывод: URL: https://httpbin.org/get?q=python+requests%2Burllib&page=1# Результат: URL: https://httpbin.org/get?q=python+requests%2Burllib&page=1
Параметры автоматически URL-кодируются. Знак '+' кодируется как %2B, пробел как +.
2. Загрузка файлов с сервера
import requests
url = 'https://www.python.org/static/img/python-logo.png'
response = requests.get(url)
if response.status_code == 200:
with open('python-logo.png', 'wb') as f:
f.write(response.content)
print('File downloaded successfully')
else:
print('Failed to download')Используется атрибут response.content для бинарных данных.
3. Отправка файлов на сервер (multipart/form-data)
import requests
files = {'file': ('test.txt', b'Hello, world!', 'text/plain')}
response = requests.post('https://httpbin.org/post', files=files)
print(response.json())# Результат (часть ответа):
{
"files": {"file": "Hello, world!"},
...
}Второй элемент кортежа - имя файла, третий - MIME тип (опционально).
4. Использование прокси-сервера
import requests
proxies = {
'http': 'http://user:pass@proxy.example.com:8080',
'https': 'https://user:pass@proxy.example.com:8080'
}
response = requests.get('https://httpbin.org/ip', proxies=proxies)
print(response.json())Прокси указываются отдельно для http и https. Требуется аутентификация, если нужна.
5. Работа с таймаутами и повторными попытками
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
import requests
session = requests.Session()
retry = Retry(total=3, backoff_factor=1, 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', timeout=5)
print(response.status_code)
except requests.exceptions.RetryError as e:
print('Max retries exceeded:', e)Настройка повторных попыток с экспоненциальной задержкой.
6. Аутентификация (Basic и Digest)
import requests
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
# Basic аутентификация
response = requests.get('https://httpbin.org/basic-auth/user/pass',
auth=HTTPBasicAuth('user', 'pass'))
print(response.status_code) # 200
# Digest аутентификация
response = requests.get('https://httpbin.org/digest-auth/auth/user/pass',
auth=HTTPDigestAuth('user', 'pass'))
print(response.status_code) # 2007. Использование cookies из браузера (пример с requests)
import requests
url = 'https://example.com'
cookies = {'sessionid': 'abc123'}
response = requests.get(url, cookies=cookies)
print(response.cookies) # также можно получить cookies из ответа8. Работа с URL с помощью urllib.parse
from urllib.parse import urlparse, urlencode, urljoin, quote, unquote
# Разбор URL
parsed = urlparse('https://user:pass@example.com:8080/path?query=1#frag')
print('Scheme:', parsed.scheme)
print('Netloc:', parsed.netloc)
print('Path:', parsed.path)
print('Query:', parsed.query)
print('Fragment:', parsed.fragment)
# Кодирование строки
encoded = quote('привет мир')
print('Encoded:', encoded) # %D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80
# Декодирование
decoded = unquote(encoded)
print('Decoded:', decoded)
# Объединение URL
base = 'https://example.com/api/v2/'
relative = '../users'
full_url = urljoin(base, relative)
print('Joined URL:', full_url) # https://example.com/api/usersМодуль urllib.parse полезен для манипуляций с URL.
9. Асинхронные запросы с aiohttp (загрузка нескольких ресурсов параллельно)
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
'https://httpbin.org/delay/1',
'https://httpbin.org/delay/2',
'https://httpbin.org/delay/3'
]
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
results = await asyncio.gather(*tasks)
for i, result in enumerate(results):
print(f'{i}: length = {len(result)}')
asyncio.run(main())Все запросы выполняются параллельно. Время выполнения минимально.
10. Отправка запроса с кастомным SSL сертификатом
import requests
response = requests.get('https://self-signed.badssl.com/', verify=False)
# Или указать путь к сертификату:
# response = requests.get('https://example.com', verify='/path/to/cert.pem')
print(response.status_code)Использование verify=False отключает проверку SSL (не рекомендуется в production).