Руководство

Как использовать прокси в Python Requests: настройка и ротация IP

Узнайте, как настроить прокси в Python Requests: аутентификация, SOCKS5, переменные окружения и расширенная ротация IP с логикой повторных попыток для устойчивого веб-скрейпинга.

Roman Bulatov
Эксперт по прокси и сетевой инфраструктуре · · 5 мин чтения

Почему важна настройка прокси

Когда вы собираете данные из веба или открываете контент с географическими ограничениями, IP-адрес часто решает, получится запрос или нет. Прокси позволяют направлять запросы через промежуточный сервер, скрывая исходный адрес и распределяя нагрузку. В библиотеке Python requests прокси подключаются просто, но в реальной работе одного статического прокси мало. Ниже — путь от базовой настройки до устойчивой системы с ротацией прокси.

Базовая настройка прокси через словарь proxies

Самый простой способ использовать прокси — передать словарь в параметр proxies. Ключи — это протоколы (http, https), а значения — URL прокси.

import requests

proxies = {
    'http': 'http://proxy.example.com:8080',
    'https': 'http://proxy.example.com:8080',
}
response = requests.get('http://httpbin.org/ip', proxies=proxies)
print(response.json())

Если прокси нужен только для одного протокола, второй можно не указывать. Requests перейдёт на прокси http для https, если https не задан, но это часто приводит к ошибкам HTTPS — поэтому всегда указывайте оба.

Прокси с аутентификацией

Многие платные или приватные прокси требуют логин и пароль. Укажите их прямо в URL:

proxies = {
    'http': 'http://user:pass@proxy.example.com:8080',
    'https': 'http://user:pass@proxy.example.com:8080',
}

Requests сам обрабатывает заголовок Proxy-Authorization. Для более сложной аутентификации (например, NTLM) стоит посмотреть на библиотеку requests-ntlm.

SOCKS5 и SOCKS5h: в чём разница

Прокси SOCKS часто быстрее для трафика TCP, но требуют пакета PySocks (pip install PySocks). Есть два варианта: socks5 разрешает DNS локально (на клиенте), а socks5h — удалённо (на прокси).

# Удалённый DNS (рекомендуется для приватности)
proxies = {
    'http': 'socks5h://proxy.example.com:1080',
    'https': 'socks5h://proxy.example.com:1080',
}

Используйте socks5h, чтобы DNS-запросы не утекали к вашему провайдеру или в локальную сеть. Если DNS предоставляет прокси, он также может кэшировать или фильтровать результаты — учитывайте этот компромисс.

Переменные окружения

Requests также учитывает стандартные переменные окружения HTTP_PROXY, HTTPS_PROXY и NO_PROXY. Это удобно, если нужно задать прокси глобально, не меняя код.

import os
os.environ['HTTP_PROXY'] = 'http://proxy.example.com:8080'
os.environ['HTTPS_PROXY'] = 'http://proxy.example.com:8080'
os.environ['NO_PROXY'] = 'localhost,127.0.0.1'

Учтите, что словарь proxies имеет приоритет над переменными окружения, если заданы и он, и они.

Сессии для постоянных настроек прокси

Если вы делаете несколько запросов, объект Session сохраняет настройки прокси, пулы соединений и куки. Задайте session.proxies один раз и переиспользуйте сессию.

session = requests.Session()
session.proxies = proxies
response = session.get('http://httpbin.org/ip')

Это избавляет от повторной аутентификации при каждом запросе и повышает производительность.

Продвинутая ротация IP: пулы ротируемых прокси

Статические прокси быстро блокируются. Ротация по пулу распределяет запросы между IP-адресами. Используйте itertools.cycle, чтобы перебирать их бесконечно.

import itertools

proxy_pool = itertools.cycle([
    'http://proxy1.com:8080',
    'http://proxy2.com:8080',
    'http://proxy3.com:8080',
])

for _ in range(10):
    proxy = next(proxy_pool)
    response = requests.get('http://httpbin.org/ip', proxies={'http': proxy})

Для больших пулов читайте прокси из файла или обращайтесь к динамическому источнику, например к бесплатному списку прокси ProxyVerity. Всегда проверяйте прокси перед интенсивным использованием — быстрый тест с известным эндпоинтом помогает избежать незаметных сбоев.

Логика повторных попыток с экспоненциальной задержкой

Временные сбои (тайм-ауты, ошибки 5xx) неизбежны. Requests может повторять запросы автоматически через HTTPAdapter с политикой Retry.

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

session = requests.Session()
retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
session.mount('http://', HTTPAdapter(max_retries=retries))
session.mount('https://', HTTPAdapter(max_retries=retries))

backoff_factor задаёт паузы 0,5 с, 1 с, 2 с, 4 с, 8 с после последовательных сбоев — распределение запросов помогает не упираться в лимиты частоты.

Обработка тайм-аутов и ошибок

Всегда задавайте тайм-аут, чтобы запрос не зависал. Перехватывайте исключения, связанные с прокси, чтобы аккуратно обрабатывать повреждённые или не отвечающие прокси.

try:
    response = requests.get('http://example.com', proxies=proxies, timeout=10)
    response.raise_for_status()
except requests.exceptions.Timeout:
    print('Request timed out')
except requests.exceptions.ProxyError:
    print('Proxy error – remove this proxy')
except requests.exceptions.RequestException as e:
    print(e)

Задавайте timeout кортежем, чтобы разделить тайм-аут подключения и тайм-аут чтения: timeout=(3, 8).

Создание устойчивого парсера

Объедините ротацию IP, повторные попытки и обработку ошибок в переиспользуемую функцию загрузки.

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

proxy_list = ['http://proxy1.com:8080', 'http://proxy2.com:8080']
proxy_cycle = itertools.cycle(proxy_list)

session = requests.Session()
retries = Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503])
session.mount('http://', HTTPAdapter(max_retries=retries))

def fetch(url):
    for _ in range(len(proxy_list)):
        proxy = next(proxy_cycle)
        try:
            response = session.get(url, proxies={'http': proxy}, timeout=5)
            return response
        except (requests.exceptions.ProxyError, requests.exceptions.Timeout):
            continue
    return None

Эта функция пробует каждый прокси по разу, затем прекращает попытки. Для большей устойчивости логируйте сбои, удаляйте мёртвые прокси из пула и подключите проверку прокси от ProxyVerity, чтобы обновлять список.

Как выбрать подходящие прокси

Не все прокси одинаковы. У бесплатных публичных прокси часто короткий срок жизни, низкая скорость или они раскрывают ваши данные. Для рабочего использования рассмотрите надёжных провайдеров или соберите собственный пул из проверенных бесплатных прокси с фильтрацией по расположению и уровню анонимности. Наш инструмент определения IP помогает убедиться, что прокси работает правильно.

Безопасность и законность

Прокси пропускают ваш трафик через посредника. Публичные прокси могут записывать, изменять или похищать данные — никогда не отправляйте через них чувствительную информацию. Всегда используйте сквозной HTTPS для шифрования передаваемых данных, хотя прокси всё равно видит IP-адрес назначения и рукопожатие. С юридической точки зрения при скрапинге необходимо соблюдать robots.txt и условия использования сайта. Ротация IP для обхода ограничений частоты запросов может нарушать эти условия. Используйте прокси ответственно и только в этичных целях.