# Прокси в Python Requests: словарь proxies, аутентификация, SOCKS5

Source: https://ipvolt.com/ru/guides/python-requests-proxy
Markdown: https://ipvolt.com/ru/guides/python-requests-proxy.md
Language: ru

[ipvolt — главная](https://ipvolt.com/ru.md) / [Руководства](https://ipvolt.com/ru/guides.md) / Прокси в Python Requests: словарь proxies, аутентификация, SOCKS5

Интеграция
Проверено: 2026-09-17
7 мин чтения
Автор: ipvolt

Настройка прокси в Python Requests: словарь proxies, значения по умолчанию в Session, учётные данные, SOCKS5 через requests[socks], переменные окружения и ProxyError.

## С чего начать

Словарь proxies, значения по умолчанию на уровне Session, кодирование учётных данных, SOCKS5, поведение с окружением и исключения, которые Requests выбрасывает при сбое на этапе прокси.

## Прокси для запроса через словарь proxies

Requests выбирает прокси из словаря, ключи которого — схемы целевого адреса. Значение для https используется для целевых адресов https://, а значение для http — для адресов http://; обычно оба указывают на один и тот же шлюз. Ключ all применяется к любой схеме, а ключ вида https://example.com привязывает один хост к определённому шлюзу.

Значение — это URL прокси с собственной схемой. http://host:port — обычный HTTP-прокси; для целевого адреса https:// Requests просит его открыть туннель CONNECT. Используйте https://host:port в качестве URL прокси только тогда, когда провайдер терминирует TLS на прокси. Всегда передавайте timeout; без него зависший прокси блокирует вызов бесконечно.

### requests.get с proxies · один запрос

```python
import requests

PROXIES = {
    "http": "http://proxy.example.invalid:8080",
    "https": "http://proxy.example.invalid:8080",
}

response = requests.get(
    "https://example.com/",
    proxies=PROXIES,
    timeout=(10, 20),
)
print(response.status_code)
```

## Используйте Session, чтобы все запросы разделяли прокси

Session хранит вместе пул соединений, cookies и настройки прокси. Задайте session.proxies один раз — и каждый запрос через эту Session будет использовать шлюз, при этом аргумент proxies в отдельном вызове по-прежнему его переопределяет. Здесь же решается, может ли окружение процесса влиять на настройки: trust_env=False запрещает Requests читать HTTP_PROXY, HTTPS_PROXY, NO_PROXY, учётные данные netrc и переменную REQUESTS_CA_BUNDLE, так что маршрут определяет только код.

### requests.Session · общие настройки прокси

```python
import requests

with requests.Session() as session:
    session.trust_env = False
    session.proxies.update({
        "http": "http://proxy.example.invalid:8080",
        "https": "http://proxy.example.invalid:8080",
    })
    for url in ("https://example.com/", "https://example.com/robots.txt"):
        response = session.get(url, timeout=(10, 20))
        print(url, response.status_code)
```

## Аутентификация на прокси: кодируйте учётные данные в URL

Requests берёт учётные данные прокси из самого URL прокси в виде http://username:password@host:port; заголовок Proxy-Authorization он добавляет за вас. Аргумент auth — это аутентификация на целевом сервере, и до прокси он не доходит.

Кодируйте имя пользователя и пароль по отдельности, чтобы символы вроде @, : или / не могли изменить структуру URL, и держите исходный PROXY_URL свободным от учётных данных. Сохраните скрипт ниже как proxy_check.py и запустите python proxy_check.py после установки Requests в виртуальное окружение командой python -m pip install requests. https://proxy.example.invalid:8443 — лишь нерабочая иллюстрация.

### proxy_check.py · Python 3 + Requests

```python
import os
from urllib.parse import quote, urlsplit, urlunsplit
import requests

gateway = urlsplit(os.environ["PROXY_URL"])
if gateway.scheme not in {"http", "https"} or not gateway.hostname:
    raise ValueError("Use your provider's HTTP(S) proxy URL")
if gateway.username is not None or gateway.path not in {"", "/"} or gateway.query or gateway.fragment:
    raise ValueError("Keep credentials and paths out of PROXY_URL")
username = quote(os.environ["PROXY_USERNAME"], safe="")
password = quote(os.environ["PROXY_PASSWORD"], safe="")
proxy = urlunsplit((gateway.scheme, f"{username}:{password}@{gateway.netloc}", "", "", ""))

with requests.Session() as session:
    session.trust_env = False
    with session.get(
        "https://example.com/",
        proxies={"http": proxy, "https": proxy},
        timeout=(10, 20),
        allow_redirects=False,
        stream=True,
    ) as response:
        response.raise_for_status()
        print({"status": response.status_code})
```

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

Когда trust_env оставлен со значением по умолчанию True, Requests заполняет из окружения через urllib.request.getproxies() любую схему, которую вы не задали. Он принимает HTTP_PROXY, HTTPS_PROXY, ALL_PROXY и NO_PROXY в верхнем или нижнем регистре, а на macOS также читает системную конфигурацию прокси. На рабочей станции это удобно, а в контейнерах — частый источник сюрпризов, когда унаследованный из образа HTTPS_PROXY направляет трафик, который вы считали прямым.

NO_PROXY — список имён хостов, суффиксов доменов или IP-адресов через запятую, которые обходят прокси. Для задания, маршрут которого должен быть воспроизводимым, задайте trust_env=False и передавайте proxies явно; для скрипта на рабочей станции достаточно установить переменные и вызывать Requests без аргумента proxies.

### HTTPS_PROXY · подхватывается, когда trust_env равен True

```sh
export HTTPS_PROXY='http://proxy.example.invalid:8080'
export NO_PROXY='localhost,127.0.0.1,.internal.example'
python -c 'import requests; print(requests.get("https://example.com/", timeout=(10, 20)).status_code)'
```

## SOCKS5-прокси: requests[socks], socks5 против socks5h

Поддержка SOCKS приходит из дополнения PySocks: установите его командой python -m pip install "requests[socks]", затем используйте URL прокси socks5:// или socks5h:// в том же словаре. socks5 резолвит имя целевого хоста локально и отправляет прокси IP-адрес; socks5h отправляет имя хоста, чтобы его резолвил прокси, — обычно именно этого ожидает удалённый шлюз. Имя пользователя и пароль указываются в URL точно так же, как для HTTP-прокси.

### socks5h-прокси · requests[socks]

```python
import requests

PROXIES = {
    "http": "socks5h://proxy.example.invalid:1080",
    "https": "socks5h://proxy.example.invalid:1080",
}
response = requests.get("https://example.com/", proxies=PROXIES, timeout=(10, 20))
print(response.status_code)
```

## Ротация между несколькими прокси

Когда заданию нужно распределить запросы по нескольким шлюзам, держите одну Session ради пула соединений и выбирайте аргумент proxies для каждого запроса. Пример перебирает список по кругу; реальное задание брало бы шлюзы из конфигурации, записывало, какой шлюз обслужил каждый запрос, и выводило шлюз из ротации после повторных сбоев вместо немедленного повтора. Должны ли последовательные запросы сохранять один и тот же исходящий адрес — это решение о модели сессии, и многие провайдеры выражают его через имя пользователя или выделенный порт. Следуйте документации провайдера, а не выводите её из одного успешного запроса.

### itertools.cycle · одна Session, несколько шлюзов

```python
from itertools import cycle
import requests

GATEWAYS = cycle([
    "http://proxy-a.example.invalid:8080",
    "http://proxy-b.example.invalid:8080",
])

with requests.Session() as session:
    session.trust_env = False
    for url in ("https://example.com/", "https://example.com/robots.txt"):
        gateway = next(GATEWAYS)
        response = session.get(url, proxies={"http": gateway, "https": gateway}, timeout=(10, 20))
        print(gateway, url, response.status_code)
```

## Понимайте, что измеряет таймаут

Кортеж задаёт отдельные таймауты на подключение и на чтение. Таймаут чтения ограничивает ожидание данных из сокета; это не общий крайний срок загрузки. Если вся задача должна завершиться к фиксированному времени, задайте отдельный бюджет по настенным часам в вашем планировщике заданий. Диагностика выше стримит и закрывает ответ, не загружая тело полностью.

Установка trust_env в False также отключает настройки набора CA-сертификатов, которые Requests берёт из окружения. Если в вашей организации используется собственный набор доверенных сертификатов, передайте одобренный файл явно через verify. Не используйте verify=False, чтобы заставить падающий тест пройти.

## Читайте ошибки: ProxyError, 407 и таймауты

То, как проявляется сбой прокси, зависит от схемы целевого адреса. Для целевого адреса https:// сбой происходит во время туннеля CONNECT, и Requests выбрасывает requests.exceptions.ProxyError, в сообщении которого содержится ответ прокси, например Tunnel connection failed: 407 Proxy Authentication Required. Для обычного адреса http:// туннеля нет, поэтому 407 приходит как обычный Response со status_code 407 и вовсе без исключения; проверяйте его явно.

Прежде чем добавлять логику повторов, прогоните тот же шлюз и целевой адрес в curl. Записывайте класс исключения, номер попытки и затраченное время, удалив учётные данные. Воспроизводимая ошибка аутентификации требует изменения конфигурации; её повторение при большей параллельности лишь добавляет шума.

- ProxyError с 407: прокси отклонил учётные данные из URL. Перепроверьте кодирование и формат имени пользователя у провайдера.
- ProxyError с Cannot connect to proxy или сообщением о разрешении имени: хост или порт шлюза неверны, либо эта сеть не может до него добраться.
- ConnectTimeout: часть connect из кортежа таймаутов истекла до того, как ответил прокси или целевой сервер. ReadTimeout: соединение сработало, но данные не пришли в пределах лимита чтения.
- SSLError после успешного туннеля: проверка сертификата целевого сервера не прошла, либо прокси перехватывает TLS. Оставьте проверку включённой и уточните у провайдера.
- Один успешный HTTP-запрос сам по себе не подтверждает местоположение точки выхода.

## Перед выпуском

- Используйте виртуальное окружение проекта.
- Кодируйте учётные данные отдельно от шлюза.
- Явно решите, может ли окружение влиять на настройки прокси.
- Помимо сетевых таймаутов держите крайний срок задания.

## Источники и дополнительное чтение

- [Requests: proxies, environment configuration and SOCKS](https://requests.readthedocs.io/en/latest/user/advanced/#proxies)
- [Requests: timeouts and errors](https://requests.readthedocs.io/en/latest/user/quickstart/#timeouts)
- [Requests API: Session.trust_env and Session.proxies](https://requests.readthedocs.io/en/latest/api/#requests.Session.trust_env)
- [urllib3: proxies and tunneling](https://urllib3.readthedocs.io/en/stable/advanced-usage.html#proxies)
- [Python: urllib.request.getproxies and environment variables](https://docs.python.org/3/library/urllib.request.html#urllib.request.getproxies)
- [Python: URL parsing and quoting](https://docs.python.org/3/library/urllib.parse.html)

## Связанные руководства

- [Прокси в curl: флаг -x, переменные окружения, SOCKS5, аутентификация](https://ipvolt.com/ru/guides/curl-proxy-setup.md)
- [Переменные окружения прокси: HTTP_PROXY и NO_PROXY](https://ipvolt.com/ru/guides/proxy-environment-variables.md)
- [Диагностика таймаутов прокси: по одному этапу за раз](https://ipvolt.com/ru/guides/proxy-timeout-troubleshooting.md)

## О ipvolt

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

[Читать оригинал на английском](https://ipvolt.com/guides/python-requests-proxy.md)

## Узнайте, когда откроется доступ.

ipvolt · В разработке

Мы строим прокси-инфраструктуру для разработчиков и команд, работающих с данными. Оставьте email, чтобы получить уведомление, когда ipvolt будет готов.

Одно письмо, когда откроется доступ. Больше ничего.

[Получить ранний доступ](https://ipvolt.com/ru/guides/python-requests-proxy#waitlist-closing)

[Конфиденциальность](https://ipvolt.com/privacy)

