Руководство по прокси для Python Requests: синтаксис, аутентификация, ротация, повторные попытки

Словарь proxies — это три строки кода, но ошибки прокси в Requests заполнили десятилетие на Stack Overflow. Вот полная настройка — синтаксис, аутентификация, переменные окружения, ротация, повторные попытки и SOCKS5 — с отмеченными острыми углами.

Python Requests по-прежнему является стандартным HTTP-клиентом для скрапинга и автоматизации, и указание ему на прокси — это задача из трех строк: передайте словарь proxies, и каждый запрос будет исходить с IP прокси вместо вашего. Тем не менее, 'python requests proxy не работает' остается в топе поиска более десяти лет — исходный вопрос на Stack Overflow о словаре proxies датируется 2011 годом, его лучший ответ имеет более 480 голосов, и он все еще редактировался в январе 2026 года. У синтаксиса есть острые углы: отсутствие схемы вызывает исключение, неправильная схема внутри ключа https вызывает ошибки SSL, а переменные окружения тихо переопределяют код. Это руководство по прокси для Python Requests охватывает все: синтаксис, аутентификацию, переменные окружения, ротацию, повторные попытки, SOCKS5 и ошибки, с которыми вы действительно столкнетесь.

Словарь proxies: синтаксис прокси для Python Requests

Аргумент proxies сопоставляет протокол с URL прокси. Два ключа покрывают обычный скрапинг — один для простых HTTP-целей, другой для HTTPS-целей — и оба обычно указывают на один и тот же прокси:

import requests

proxies = {
    "http": "http://USER:PASS@gate.quantumproxies.io:PORT",
    "https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}

r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=(5, 30))
print(r.json())  # {'origin': '<proxy exit IP>'}

Три правила предотвращают 90% ошибок настройки:

Аутентификация прокси: имя пользователя и пароль

Аутентифицированные прокси используют HTTP Basic auth, встроенный в URL: http://USER:PASS@host:port. Если пароль содержит @, : или /, сначала закодируйте его в URL с помощью urllib.parse.quote(password, safe="") — некодированные специальные символы разделяют URL в неправильном месте и вызывают ошибки аутентификации, которые выглядят как неработающие прокси. Ответ 407 Proxy Authentication Required означает, что сам прокси отклонил вас: неправильные учетные данные или план с белым списком IP, вызванный с незарегистрированного адреса. Оба случая разобраны в нашем руководстве по устранению неполадок 407. Для чего-либо, кроме одноразового скрипта, прикрепите прокси к Session — вы получите пул соединений, сохранение cookies и одно место для настройки всего:

import requests

session = requests.Session()
session.proxies = {
    "http": "http://USER:PASS@gate.quantumproxies.io:PORT",
    "https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}
session.headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"})

r = session.get("https://httpbin.org/ip", timeout=(5, 30))
print(r.status_code, r.json())

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

Requests также читает настройки прокси из окружения — те же переменные, которые curl и большинство Unix-инструментов уважают: HTTP_PROXY, HTTPS_PROXY, ALL_PROXY и NO_PROXY (список хостов для исключения, например localhost,127.0.0.1,.internal). Это самый чистый способ проксировать стороннюю библиотеку, использующую Requests под капотом, не касаясь ее кода. Приоритеты работают по принципу явное побеждает неявное: аргумент proxies= в вызове выигрывает, затем session.proxies, затем окружение. Два связанных инструмента стоит знать: session.trust_env = False отключает все обращения к окружению — исправление, когда корпоративная переменная прокси перехватывает ваш скрапер — и urllib.request.getproxies() возвращает настройки прокси на уровне ОС (включая системную конфигурацию macOS и Windows) в точности в том виде, который ожидает Requests.

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

Ротация: один шлюз лучше списка прокси

Традиционный рецепт ротации — загрузить список IP, random.choice() для каждого запроса, удалить неработающие — это механизм, который вам больше не нужно строить. Вращающийся шлюз делает это на стороне сервера: вы настраиваете одну конечную точку, и провайдер назначает свежий выходной IP из пула при каждом запросе. Через вращающиеся резидентные прокси этот пул составляет более 90 миллионов домашних IP в более чем 200 странах, так что тысяча запросов выглядит как тысяча разных посетителей без единой строки логики ротации:

import requests

proxies = {
    "http": "http://USER:PASS@gate.quantumproxies.io:PORT",
    "https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}

for _ in range(3):
    r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=(5, 30))
    print(r.json()["origin"])  # a different exit IP on each iteration

Когда поток охватывает несколько запросов — вход, добавление в корзину, оформление заказа — ротация на каждый запрос нарушает сессию. Липкие сессии решают это: параметр сессии в имени пользователя прокси закрепляет один выходной IP на заданное время, затем вращается. Та же конечная точка, одно изменение строки. Если вы масштабируетесь за пределы простых циклов, асинхронный Python с httpx или aiohttp увеличивает пропускную способность, а система middleware Scrapy предоставляет ротацию, повторные попытки и обработку банов в виде конфигурации фреймворка.

Повторные попытки и таймауты, которые переживут плохие выходы

Даже премиальные пулы иногда предоставляют медленный или умирающий выход, поэтому в производственном коде нужны две защиты: таймаут на каждый запрос (по умолчанию Requests ждет бесконечно) и автоматические повторные попытки с обратной задержкой. Таймаут принимает кортеж (connect, read) — быстрое завершение на недоступных прокси, разрешение медленных чтений страниц. Повторные попытки монтируются на транспортном уровне через urllib3:

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

retry = Retry(
    total=4,
    backoff_factor=1,  # exponential backoff between attempts
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods=["GET", "HEAD"],
)

session = requests.Session()
session.mount("http://", HTTPAdapter(max_retries=retry))
session.mount("https://", HTTPAdapter(max_retries=retry))
session.proxies = {
    "http": "http://USER:PASS@gate.quantumproxies.io:PORT",
    "https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}

r = session.get("https://httpbin.org/ip", timeout=(5, 30))

С вращающимся шлюзом эта комбинация тихо мощная: каждая повторная попытка проходит через другой выходной IP автоматически, так что один ненадежный адрес никогда не сможет провалить запрос четыре раза подряд.

SOCKS5 прокси с Requests

Поддержка SOCKS — это дополнение: установите его с помощью pip install requests[socks]. Затем синтаксис словаря идентичен — меняется только схема. Предпочитайте socks5h:// вместо socks5://: h передает разрешение DNS на прокси, что предотвращает утечки DNS из вашей реальной сети и разрешает гео-заблокированные имена хостов из местоположения выхода. Каждый план QuantumProxies предоставляет как HTTP, так и SOCKS5 прокси на одном шлюзе, так что смена протоколов — это замена схемы, а не новая покупка:

proxies = {
    "http": "socks5h://USER:PASS@gate.quantumproxies.io:PORT",
    "https": "socks5h://USER:PASS@gate.quantumproxies.io:PORT",
}
Контрольный список, сравнивающий рабочие конфигурации прокси для Python Requests с пятью распространенными ошибками, которые их ломают
Пять ошибок вызывают большинство сбоев: отсутствие схемы, https:// в ключе https, некодированные пароли, отсутствие дополнительных настроек SOCKS и отсутствие таймаута.

Расшифровка распространенных ошибок прокси для Python Requests

Для более глубокого анализа трассировок стека и их коренных причин смотрите отладка ProxyError, SSLError и ConnectTimeout в Requests.

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

Как использовать прокси с Python Requests?

Передайте словарь proxies с ключами http и https любому методу запроса: requests.get(url, proxies={...}). Каждое значение — это полный URL прокси, включая схему, а учетные данные встраиваются как http://user:pass@host:port. Прикрепите тот же словарь к Session, чтобы применять его ко всем запросам автоматически.

Почему мой прокси для Python Requests не работает?

Проверьте четырех обычных подозреваемых по порядку: отсутствие схемы http:// в URL прокси, использование https:// внутри ключа https, специальные символы в пароле, которые не были закодированы в URL, и переменные окружения, переопределяющие ваш код. Проверьте те же учетные данные с помощью curl — если curl успешен, проблема в вашем словаре.

Поддерживает ли Python Requests прокси SOCKS5?

Да, после установки дополнительной зависимости с pip install requests[socks]. Используйте схему socks5h:// в вашем словаре proxies, чтобы разрешение DNS происходило на стороне прокси — простая схема socks5:// разрешает имена хостов локально, что приводит к утечкам DNS и может нарушить гео-направленный скрапинг.

Как установить прокси с помощью переменных окружения?

Экспортируйте HTTP_PROXY и HTTPS_PROXY с полным URL прокси, и, при необходимости, NO_PROXY для хостов, которые нужно исключить. Requests автоматически подхватывает их, что также проксирует сторонние библиотеки, построенные на Requests. Чтобы ваш код полностью игнорировал окружение, установите session.trust_env = False.

Вот весь набор инструментов: словарь с двумя ключами, учетные данные в URL, повторные попытки монтируются один раз, а ротация осуществляется шлюзом вместо вашего кода. Единственное, что никакой синтаксис не исправит, — это качество IP — идеально настроенный прокси дата-центра все равно будет заблокирован там, где резидентный выход пройдет без проблем. Соедините чистый код с чистыми IP, и Requests справится с удивительно большими нагрузками.

Получите резидентные прокси, которые работают с первого раза