Ошибка 407 Proxy Authentication Required: почему прокси не пускает парсер
407 — единственный код, который вы гарантированно получили от прокси, а не от сайта. Это сужает поиск до четырёх мест, и ни одно из них не находится на стороне целевого ресурса.
Что означает 407 и чем он отличается от 403
Код 407 Proxy Authentication Required означает, что прокси не принял ваши учётные данные. По спецификации такой ответ обязан содержать заголовок Proxy-Authenticate — в нём прокси называет схему авторизации, которую ждёт. Клиент должен повторить запрос с заголовком Proxy-Authorization.
Отличие от 403 принципиальное. 403 обычно приходит от целевого сайта и означает «вас опознали и не пустили»; лечится сменой адреса, паузами, заголовками. 407 приходит от прокси и означает «я вас не узнал»; сменой IP или пауз не лечится вообще. Путать их дорого: люди неделями крутят задержки там, где не совпал пароль.
Пять причин по частоте
- Неверная пара логин-пароль: опечатка при копировании или тариф уже истёк.
- IP машины не добавлен в whitelist — при авторизации по адресу это выглядит ровно как неверный пароль.
- Протокол не тот, что слушает порт: SOCKS5-строка отправлена на HTTP-порт или наоборот.
- Софт не передаёт учётные данные в CONNECT — умеет поля только для адреса и порта.
- Спецсимволы пароля не закодированы в строке подключения: собака, двоеточие и слеш ломают разбор URL.
Проверка за одну минуту
Обмен с прокси происходит до запроса к сайту, поэтому его видно в подробном выводе curl. Это отсекает половину гипотез сразу.
# -v показывает обмен с прокси до того, как начнётся запрос к сайту
curl -v -x http://ЛОГИН:ПАРОЛЬ@ШЛЮЗ:ПОРТ https://example.com -o /dev/null
# Что искать в выводе:
# HTTP/1.1 200 Connection established -> прокси пустил, дело не в 407
# HTTP/1.1 407 Proxy Authentication Required
# Proxy-Authenticate: Basic realm="..." <- прокси называет схему,
# которую ждёт от клиентаЕсли здесь 200 Connection established, а парсер всё равно получает 407 — значит учётные данные не доходят из вашего кода, и разбираться нужно в нём, а не в прокси.
Порт и протокол — самая незаметная причина
HTTP и SOCKS5 слушают разные порты. Строка с верным логином, отправленная на порт другого протокола, даёт либо 407, либо обрыв соединения без внятного сообщения. Проверяются оба варианта за две команды.
# Тот же логин на порту другого протокола даст 407 или обрыв,
# хотя пара логин-пароль верная. Проверьте оба:
curl -sI -x http://ЛОГИН:ПАРОЛЬ@ШЛЮЗ:HTTP_ПОРТ https://example.com | head -1
curl -sI -x socks5h://ЛОГИН:ПАРОЛЬ@ШЛЮЗ:SOCKS_ПОРТ https://example.com | head -1Когда софт не умеет передавать пароль
Часть программ и почти все headless-браузеры принимают только адрес и порт: поля для логина у них нет, а Chromium вдобавок игнорирует учётные данные, переданные в аргументе запуска. Пароль в такой конфигурации передать физически нечем.
Решение — авторизация по IP. Адрес машины добавляется в whitelist, и прокси узнаёт клиента по самому подключению, без пароля. У нас оба способа активны одновременно, поэтому переключать ничего не нужно: серверная машина работает по whitelist, а скрипты с ноутбука продолжают ходить по логину.
Что не является причиной 407
- Лимит потоков: при его исчерпании подключения ждут очереди, а не получают 407.
- Блокировка на стороне сайта: до сайта запрос ещё не дошёл.
- Исчерпанный трафик на статических тарифах: это отдельная ошибка, не 407.
Как отличить отказ прокси от отказа сайта
Это стоит уметь до того, как начнёте менять настройки, потому что лечение у двух случаев противоположное. Здесь помогает свойство протокола: при работе по HTTPS прокси открывает туннель отдельной командой и после этого не может вставить ничего в поток. Значит любой ответ, пришедший внутри HTTPS, сформировал целевой сайт.
# Ответ от прокси помечен служебными заголовками. Смотреть их надо
# на plaintext http: внутри HTTPS прокси в тело ответа вставить ничего не может.
curl -sI -x http://ШЛЮЗ:ПОРТ http://neverssl.com | grep -iE '^via|^server|^x-'
# Типичные маркеры:
# Via: 1.1 squid
# Server: squid/5.7
# X-Squid-Error: ERR_ACCESS_DENIED 0 <- отказ именно прокси
# Если этих заголовков нет, а 403 пришёл внутри HTTPS — он от целевого сайта.Из этого следует практическое правило. Отказ прокси приходит раньше — на этапе установки туннеля, и в библиотеках он выглядит как ошибка прокси, а не как код ответа. Если же вы видите обычный код ответа внутри HTTPS-соединения, автор этого кода — сайт.
Что означают ошибки браузера
В headless-браузерах вместо кода вы получите текстовый идентификатор ошибки, и два из них похожи, но означают разные стадии.
- Ошибка туннеля — до прокси дошли, но установить туннель не удалось: нет авторизации, порт запрещён, целевой хост недоступен.
- Ошибка подключения к прокси — сам прокси недоступен как хост: не разрешилось имя или не открылся сокет. Стадия туннеля до этого не дошла.
Авторизация по IP и по логину одновременно
Whitelist для серверов и софта без полей авторизации, логин с паролем — для остального. Переключать не нужно, работают оба.
Смотреть тарифыПрокси под эту задачу
Проверить нашими инструментами
Читайте также
- Один шлюз вместо списка прокси: как настроить софт, который ждёт списокПарсеры считают масштаб числом прокси, а ротационный шлюз — это одна строка. Разбор по программам: где переключить режим, где продублировать строку и где честный ответ — купить список.
- 403 через прокси: отказал сайт, отказал прокси или дело вообще не в адресе403 приходит и от прокси, и от целевого сайта, и различить их можно не всегда. Разбор: где смотреть код Cloudflare, какие коды не лечатся сменой адреса и почему заголовки прокси — плохой тест.
- IP не меняется при ротации: виноват keep-alive, а не проксиАдрес выхода выбирается при установке соединения, а не при отправке запроса. Любой клиент с пулом соединений держит один IP — разбор механизма и однострочные починки для requests, httpx и aiohttp.
