IPv4kupit-proxy-ipv4.ru

Ошибка 403 при работе через прокси: почему сайт отказывает и что менять

Ошибка 403 при работе через прокси: почему сайт отказывает и что менять, раздел «Проверка и диагностика» справочника по прокси IPv4

Код 403 приходит от целевого сайта, который запрос принял, прочитал и отклонил. Узел-посредник тут ни при чём: он честно донёс обращение до площадки, и площадка ответила отказом по содержанию запроса. Значит разбирать нужно сам запрос: темп обращений, набор и порядок заголовков, cookies, отпечаток шифрованного рукопожатия, доступность конкретного раздела.

Разбор страницы «Ошибка 403 при работе через прокси: почему сайт отказывает и что менять» по разделам

Ниже отказ разложен по шести слоям от самого частого к самому редкому, по каждому дан признак, который отличает его от остальных, и правка, которая его снимает. Отдельно разобрано, как снять реальный ответ вместе с телом страницы отказа, чем 403 отличается от 429 и 503 и как выстроить прогон, чтобы отказы перестали появляться.

Почему 403 приходит от площадки и что это меняет

Проверка источника отказа занимает одну команду. Тот же запрос отправляется на нейтральный эхо-сервис через тот же выход. Ответ 200 оттуда означает, что канал рабочий: соединение поднялось, туннель встал, ответ вернулся. После этого все дальнейшие правки касаются только запроса.

# канал живой?
curl -s -o /dev/null -w '%{http_code}\n' -x http://185.24.87.14:8000 https://ifconfig.me
# 200

# а целевая площадка?
curl -s -o /dev/null -w '%{http_code}\n' -x http://185.24.87.14:8000 https://example.com/catalog
# 403

Два разных кода на двух доменах через один выход дают однозначный вывод: узел пропустил оба обращения, отказ вынесла площадка. Мы начинаем любой разбор именно с этой пары команд, потому что она за пять секунд отсекает подозрения на настройки доступа.

Отсюда второе наблюдение, менее очевидное. Площадка видит запрос целиком: строку запроса, все заголовки в том порядке, в котором они пришли, набор cookies, параметры шифрованного рукопожатия, темп обращений с одного адреса. Отказ выносится по совокупности признаков, и один и тот же адрес получает 200 в одном сценарии и 403 в другом. Смена адреса без правки запроса переносит проблему на новый адрес.

Отказ приходит быстро. Обычно за первые сотни миллисекунд, потому что вердикт выносит слой перед приложением.

Шесть слоёв отказа: от частого к редкому

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

Слой первый: частота обращений выше принятой

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

Второй признак: отказ приходит на все адреса пула одновременно, если прогон разложен на несколько выходов и темп на каждом одинаково высокий. Третий признак: пауза в несколько минут снимает отказ без единой правки в запросе.

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

ВеличинаКак задаётсяЧто происходит при завышении
Пауза между запросамиЗадержка в настройках прогонаСчётчик площадки переполняется
Одновременные потокиЛимит в софтеВсплеск обращений в первую секунду
Ширина ротацииРазмер пула под прогонНагрузка садится на узкую группу выходов
Повторы после отказаПолитика ретраевОтказы множатся, счётчик растёт дальше

Отдельно про повторы. Скрипт получил 403 и тут же отправил тот же запрос заново, потом ещё раз, потом с задержкой в секунду. Счётчик площадки при этом продолжает расти, и вместо восстановления прогон загоняет себя глубже. Правильный порядок: отказ фиксируется, темп снижается, запрос уходит в отложенную очередь. Пакеты дают до 1000 потоков на стандартных вариантах и до 3000 на корпоративном, при этом сама цифра лимита к порогу площадки отношения не имеет, её задаёт сайт. Рабочие связки по темпу и ширине пула описаны там, где берутся прокси для парсинга и сбора данных.

Слой второй: заголовки не похожи на браузер

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

Библиотека по умолчанию шлёт три-четыре поля. Браузер шлёт полтора десятка, в фиксированном порядке, с осмысленными значениями. Разница читается автоматом.

# то, что уходит из библиотеки без настройки
GET /catalog HTTP/1.1
Host: example.com
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate
Accept: */*
# то, что уходит из браузера
GET /catalog HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Accept-Encoding: gzip, deflate, br
Sec-Ch-Ua: "Chromium";v="124", "Not:A-Brand";v="24"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
Connection: keep-alive

Порядок полей значит не меньше состава. Браузеры отправляют заголовки в устойчивой последовательности, и площадка сверяет её вместе с содержимым User-Agent. Набор, собранный вручную по алфавиту или в случайном порядке, выдаёт себя даже при полном составе полей.

ПолеЧто показывает площадкеЧастая ошибка
User-AgentПрограмма и версияОставлено значение библиотеки
Accept-LanguageОжидаемый язык ответаОтсутствует целиком
Accept-EncodingПоддерживаемое сжатиеНет br, хотя заявлен свежий Chrome
Sec-Fetch-*Контекст переходаПропущены при заявленном Chromium
Sec-Ch-UaВерсия движкаВерсия расходится с User-Agent
RefererОткуда пришёл переходСтоит на первом же обращении к сайту

Правка занимает один проход по коду. Мы снимаем настоящий набор из браузера через панель разработчика, копируем его как команду curl и переносим в прогон целиком, вместе с порядком. Дальше набор держится согласованным: версия в Sec-Ch-Ua совпадает с версией в User-Agent, язык в Accept-Language совпадает с ожидаемым, Referer появляется только со второго перехода.

Слой третий: нет привычного набора cookies

Третий слой узнаётся по характерной картине: главная страница отдаётся кодом 200, внутренний раздел отвечает 403. Площадка ставит служебные cookies на первом заходе и ждёт их на всех последующих обращениях. Прогон, который ходит сразу на карточки, эти поля не получает и не отправляет.

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

# первый заход: забираем cookies
curl -s -c jar.txt -x http://185.24.87.14:8000 https://example.com/ -o /dev/null

# второй заход в раздел: отдаём их обратно
curl -s -b jar.txt -c jar.txt -x http://185.24.87.14:8000 https://example.com/catalog -o page.html -w '%{http_code}\n'

# что вообще положила площадка
cat jar.txt

Код 200 на втором запросе при отказе на прямом обращении в раздел подтверждает слой однозначно. Правка простая: прогон начинается с главной страницы, банка cookies живёт на протяжении сессии и привязывается к тому же выходу, с которого была получена. Смена выхода посреди сессии обнуляет доверие: площадка видит, что её cookies пришли с другого адреса.

Отсюда практический вывод про ротацию. Сессия и выход держатся вместе от начала до конца, а новая сессия берёт новый выход. Ротация внутри пула автоматическая, поэтому схема укладывается в один параметр прогона: сессия открывается, отрабатывает свои страницы и закрывается вместе с банкой cookies.

Слой четвёртый: отпечаток рукопожатия расходится с User-Agent

Четвёртый слой встречается там, где перед сайтом стоит защита с разбором шифрованного рукопожатия. Клиент заявляет себя браузером в заголовке, а параметры согласования шифрования у него совсем другие: свой набор наборов шифров, свой порядок расширений, своя поддержка версий протокола. Несовпадение читается до отправки первого прикладного заголовка.

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

Что сравнивает площадкаБраузерБиблиотека по умолчанию
Набор шифров и его порядокУстойчивый для версииПорядок берётся из системной библиотеки
Расширения рукопожатияПолный набор, включая перемешиваниеСокращённый набор
Заявленные версии протоколаСвежая версия с откатомЧасто только одна версия
Согласование прикладного протоколаh2 и запасной вариантНередко отсутствует
Порядок прикладных заголовковФиксированный для движкаПорядок словаря в коде

Правка идёт в сторону настоящего браузерного стека. Прогон переносится в браузер под управлением, либо берётся клиент, который повторяет рукопожатие движка целиком. Антидетект-браузеры делают ровно это: движок настоящий, поэтому рукопожатие совпадает с заявленным заголовком автоматически. Профили при этом мы разводим по разным выходам, и связка профиля с адресом держится постоянной на всю сессию. Настройки под такие браузеры собраны на странице про прокси для антидетект-браузеров.

# посмотреть, какую версию протокола и какой набор согласовал клиент
curl -v -x http://185.24.87.14:8000 https://example.com -o /dev/null 2>&1 | grep -E 'SSL connection|ALPN|TLSv'

Слой пятый: раздел закрыт для всех

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

Проверяется за десять секунд: тот же адрес открывается в браузере напрямую. Отказ там означает, что вопрос в самом разделе. Тело ответа в таком случае обычно короткое и типовое, с формулировкой веб-сервера.

<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>

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

Слой шестой: сработала защита перед сайтом

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

# смотрим ответ целиком: заголовки и тело страницы отказа
curl -s -D headers.txt -x http://185.24.87.14:8000 https://example.com/catalog -o body.html
head -20 headers.txt
grep -iE 'ray|request-id|challenge|blocked' body.html | head

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

Что в теле ответаЧто это означаетКуда смотреть дальше
Короткая страница веб-сервераПуть закрыт настройкамиМаршрут перехода и доступность раздела
Страница с идентификатором обращенияОтработала защита перед сайтомОтпечаток рукопожатия и полнота заголовков
Страница с проверкой в браузереОжидается исполнение скриптаПрогон переносится в браузерный движок
Форма ввода символов с картинкиПоведение сочтено автоматическимТемп, ширина ротации, набор cookies
Обычная страница сайта с текстом отказаОтказ вынесло само приложениеУчётная запись и права на разделе

Правка идёт по совокупности: браузерный движок для исполнения скриптов, полный и согласованный набор заголовков, живая банка cookies, спокойный темп и широкая ротация выходов. Каждый пункт по отдельности отказ не снимает, вместе они дают рабочий прогон.

Как снять реальный ответ и прочитать страницу отказа

Отладка начинается с того, чтобы увидеть ответ целиком. Код без тела говорит мало, тело без заголовков тоже. Мы снимаем обе части одной командой и раскладываем их по файлам.

curl -s -D headers.txt -o body.html -w 'code=%{http_code} size=%{size_download} time=%{time_total}\n' \
  -x http://185.24.87.14:8000 \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' \
  -H 'Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8' \
  https://example.com/catalog

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

Дальше читаем заголовки ответа. Служебные поля защитного слоя, поля кеша, поле Retry-After, поле Set-Cookie с новой служебной строкой. Каждое из них сужает круг.

# коды по серии запросов, чтобы увидеть картину во времени
for i in $(seq 1 40); do
  printf '%s ' "$(curl -s -o /dev/null -w '%{http_code}' -x http://185.24.87.14:8000 https://example.com/catalog)"
  sleep 1
done
echo
# 200 200 200 200 200 403 403 403 403 403 403 ...

Полоса двухсоток, которая обрывается на отказ, указывает на темп. Отказ с первого же запроса указывает на запрос сам по себе. Чередование кодов указывает на ротацию: часть выходов уже под ограничением, часть ещё нет. Как правильно замерять серию и не путать кеш с реальным ответом, разобрано в материале про замер скорости и времени отклика.

Чем 403 отличается от 429 и 503

Три кода приходят в похожих обстоятельствах и требуют разных действий. Различить их помогает таблица и одно наблюдение: только 429 прямо называет причину, остальные два оставляют её на догадку.

КодЧто говорит площадкаТело ответаЧто делать
403Запрос прочитан и отклонёнСтраница отказа или защитыПравить запрос: темп, заголовки, cookies, отпечаток
429Частота обращений превышенаКороткое, часто с полем Retry-AfterЖдать указанное время, снижать темп
503Приём запросов временно закрытСтраница обслуживания или защитыОтложить прогон, проверить сайт глазами
401Раздел требует подтверждения праваПустое, с полем WWW-AuthenticateУчётная запись на самой площадке
407Право доступа к пулу не подтвержденоПустое, с полем Proxy-AuthenticateПривязка адреса и пара логина с паролем
404Путь отсутствуетСтраница сайтаСверить адрес и параметры запроса

Код 407 в этом ряду стоит особняком: его выписывает узел-посредник до целевого сайта, и на нейтральном эхо-сервисе он воспроизводится точно так же. Полный разбор этого случая вынесен в соседнюю статью раздела диагностики.

Поле Retry-After в ответе означает, что площадка сама называет паузу. Его стоит читать и соблюдать: игнорирование поля быстро переводит ограничение в постоянный отказ. При коде 503 полезно открыть сайт в браузере: страница обслуживания видна сразу, и тогда прогон просто откладывается.

Почему повтор того же запроса ничего не даёт

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

Работающий порядок выглядит иначе. Отказ фиксируется вместе с кодом, размером тела и временем ответа. Запрос уходит в отложенную очередь. Прогон продолжается на других задачах, темп снижается, и отложенная очередь перебирается позже, уже с изменённым запросом или с другого выхода. Повтор без правки допустим ровно в одном случае: когда предыдущий отказ пришёл на пике темпа и пауза заведомо превышает окно счётчика.

# порядок обработки отказа: без слепых повторов
import time, collections

deferred = collections.deque()

def handle(url, code, body_len):
    if code == 200:
        return "ok"
    if code == 403:
        deferred.append((url, time.time() + 900))   # разбираем позже
        return "отложено, темп снижен"
    if code == 429:
        return "пауза по полю Retry-After"
    return "разбор по коду " + str(code)

Число 900 в примере это пятнадцать минут ожидания. Цифра подбирается под площадку: где-то хватает трёх минут, где-то нужен час. Замер делается один раз на небольшой серии и дальше остаётся в настройках прогона.

Как выстроить прогон, чтобы 403 не появлялись

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

НастройкаКак подобратьПризнак того, что цифра завышена
Пауза между запросамиЗамер серией по сорок обращенийПолоса отказов после первых успехов
Потоки в софтеСкорость умножить на время откликаВсплеск обращений и отказ в первую минуту
Ширина ротацииОбщая скорость делить на темп с выходаОтказы возвращаются на те же выходы
Набор заголовковСнимок из панели разработчикаОтказ на самом первом запросе
Длина сессииЧисло страниц до смены выходаОтказ появляется в середине сессии

Пауза замеряется серией. Запускаем сорок обращений с шагом в секунду, смотрим, на каком номере появляется первый отказ, увеличиваем шаг и повторяем. Цифра, при которой сорок обращений проходят подряд, берётся с запасом примерно в треть. Такой замер занимает четверть часа и экономит дни разбора.

Ширина ротации считается из общей скорости. Нужно 5 000 страниц в час, безопасный темп с одного выхода 20 обращений в минуту: 5 000 делим на 60 и на 20, выходит примерно 4 выхода в постоянной работе плюс запас на отдых каждого. Пул около 12 000 адресов такую ширину закрывает с большим запасом, ротация внутри него автоматическая, поэтому раскладка не требует ручного управления списком. Трафик безлимитный, так что объём выкачанных страниц на расчёт не влияет вовсе.

Сессии выстраиваются по площадке. Одна сессия это вход через главную, набор служебных cookies, серия страниц и закрытие. Выход держится один на всю сессию. Длина сессии подбирается тем же замером: увеличиваем число страниц, пока отказ не появится в середине, и берём цифру ниже границы. Готовые связки под парсеры и антидетект-браузеры собраны на странице, где берутся адреса под массовый сбор данных.

Заголовки собираются один раз и живут в конфиге прогона. Пересобирать их приходится редко, а вот сверять на согласованность полезно при каждом обновлении версии в User-Agent: версия движка стоит сразу в трёх полях, и расхождение между ними даёт отказ на любом темпе. Отдельно проверяется, что запросы к службе имён идут через выход, иначе картина по адресу выходит неполной. Как это устроено, разобрано в материале про запросы к службе имён и их утечку.

Перед крупным запуском список адресов перечитывается из кабинета. Он обновляется в режиме реального времени, и сохранённый когда-то файл постепенно устаревает: часть строк перестаёт отвечать, прогон получает лишние ошибки, и они смешиваются с настоящими отказами площадки. Список забирается ссылкой или файлом в форматах IP:PORT и IP:PORT:LOGIN:PASS. Откуда берутся сами узлы, показано на странице про пул на собственных серверных мощностях, а сокетный вариант подключения разобран там, где берётся доступ по протоколу SOCKS5.

Что проверить, когда 403 появился на рабочем прогоне

Прогон работал неделю и начал отдавать отказы. Разбор идёт по цепочке от внешних причин к внутренним, и первые три шага занимают несколько минут.

ШагВопросЧем проверяемВывод
1Канал живой?Запрос на эхо-сервис через тот же выходКод 200 означает, что отказ от площадки
2Раздел открыт вообще?Тот же путь в браузере напрямуюОтказ там означает закрытый путь
3Отказ от темпа?Серия с паузой в несколько секундПроходит означает превышение темпа
4Заголовки согласованы?Снимок из панели разработчика и сверкаРасхождение версий даёт стабильный отказ
5Cookies живые?Заход через главную с сохранением банкиКод 200 после этого подтверждает слой
6Отпечаток совпадает?Тот же запрос из настоящего браузераПроходит означает расхождение рукопожатия

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

Мы советуем держать результаты замеров в конфиге прогона рядом с настройками потоков: темп с одного выхода, длина сессии, набор заголовков, дата последней сверки. Тогда возврат к площадке через месяц начинается с готовых цифр, и вся настройка сводится к одной серии из сорока обращений. Состав пакета по потокам, привязкам и трафику описан там, где берётся пул IPv4 с безлимитным трафиком.

Частые вопросы

Подойдут ли прокси под мою задачу, если площадка отвечает отказом?

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

Можно ли отобрать прокси по стране, чтобы обойти отказ?

Нет, пул это микс со всего мира, выборка по отдельной стране не делается. Отказ 403 выносится по содержанию запроса, поэтому снимается правкой темпа, заголовков, cookies и отпечатка. Разнообразие подсетей в общем пуле работает на ширину ротации, и её обычно хватает с запасом.

Есть ли лимиты по потокам и как они связаны с отказами?

У каждого пакета свой лимит: стандартные варианты дают до 1000 потоков, корпоративный до 3000. Пакеты по потокам не складываются, при двух привязанных адресах общее число делится пополам. Порог площадки задаётся ей самой и с лимитом пакета не связан, поэтому число потоков в софте подбирается под темп, который принимает конкретный сайт.

Чем проверять прокси перед прогоном?

Рекомендуется чекер от Zennolab, у него есть демонстрационная версия. Он проходит список пачкой и показывает отвечающие строки и время отклика. Перед крупным запуском список полезно перечитать из кабинета: он обновляется в режиме реального времени.

Остальную диагностику удобно смотреть по порядку: сначала проверка работы прокси командами и в браузере, затем какие заголовки уходят на сервер при разборе анонимности, отдельно ошибка 407 от узла-посредника со всеми причинами по списку. Когда прогон настроен и отказы ушли, дальше пригодится материал про сбор прайсов и остатков поставщиков.

Материал сайта kupit-proxy-ipv4.ru. Рабочие адреса IPv4 и SOCKS5: iprazon.com.