Аутентификация Playwright SOCKS5 Proxy: Почему Она Не Работает, 4 Решения

Playwright принимает сервер socks5://, а затем отклоняет ваше имя пользователя и пароль. Ограничение связано с Chromium, а не с Playwright, и оно существует с 2021 года — вот четыре способа его обойти, ранжированные по эффективности.

Аутентификация Playwright SOCKS5 proxy не существует, и знание этого заранее сэкономит вам вечер. Передайте сервер socks5:// вместе с именем пользователя и паролем, и Playwright откажется до того, как браузер начнет навигацию. Запрос функции, на который все ссылаются, microsoft/playwright#10567, был открыт в ноябре 2021 года, все еще открыт и все еще имеет метку P3-collecting-feedback. Ограничение не связано с Playwright: оно находится в Chromium. В этом посте показаны точные строки ошибок, объясняется, почему ни одно расширение или конфигурационный флаг не спасет вас, и дается четыре решения — однострочная замена на HTTP, белый список IP, локальный релей и Firefox.

Ошибка, которую вы ищете

Каждая версия этой проблемы выдает одну из двух строк. В Node вы получаете Error: Browser does not support socks5 proxy authentication; в Python, более старые версии добавляют префикс playwright._impl._api_types.Error:, а новые — playwright._impl._errors.Error:. Сообщение одинаково, и оно выбрасывается при запуске, а не при навигации:

const { chromium } = require('playwright');

// Fails immediately — no page is ever created
const browser = await chromium.launch({
  proxy: {
    server: 'socks5://gate.quantumproxies.io:PORT',
    username: 'USER',
    password: 'PASS',
  },
});
// Error: Browser does not support socks5 proxy authentication

// Python raises the same thing:
// playwright._impl._errors.Error: Browser does not support
// socks5 proxy authentication

Существует более тихий вариант. Если вы уберете поля учетных данных и вставите их в строку сервера — socks5://USER:PASS@host:1080 — ничего не выбрасывается. Chromium просто игнорирует часть URL с информацией о пользователе, пытается выполнить неаутентифицированное рукопожатие, и шлюз его отклоняет. Затем вы видите net::ERR_SOCKS_CONNECTION_FAILED или обычный тайм-аут при первом goto(), что заставляет людей искать несуществующие сетевые ошибки.

Где на самом деле ломается аутентификация Playwright SOCKS5 proxy

Собственная документация Playwright ясна: поля username и password в опции прокси описываются как учетные данные для использования "если HTTP proxy требует аутентификации". SOCKS поддерживается только как схема. В основе, Chromium никогда не реализовывал подпереговоры имени пользователя/пароля из RFC 1929 для SOCKS5, поэтому запись в трекере проблем Chromium по аутентификации SOCKS5 (40323993) собрала годы комментариев, почему расширение SwitchyOmega предупреждает пользователей в момент выбора SOCKS5 с учетными данными, и почему Brave и Edge ведут себя идентично. Это один движок, один пробел, унаследованный всем, что на нем построено.

Это также причина, по которой трюк, который спасает пользователей Selenium, здесь не помогает. Расширение Manifest V3 может ответить на вызов прокси через chrome.webRequest.onAuthRequired, но этот хук срабатывает на HTTP 407 Proxy Authentication Required ответах. Рукопожатие SOCKS5 — это побайтное согласование на сокете до существования любого HTTP, поэтому нет события для перехвата. И не путайте опцию контекста httpCredentials с аутентификацией прокси: она отвечает на 401 вызовы с посещаемого вами сайта, никогда не с прокси. Для полной картины по всем скрытым фреймворкам наша карта аутентифицированных прокси в антидетект-фреймворках охватывает, кто что поддерживает.

Решение 1: используйте HTTP-эндпоинт того же шлюза

Это решение для примерно девяти пользователей из десяти, и оно занимает одну строку. Серьезные провайдеры предоставляют тот же пул IP по обоим протоколам на разных портах — каждый план QuantumProxies включает HTTP и SOCKS5 эндпоинты с теми же учетными данными и той же синтаксисом сессии. Поменяйте схему и порт, оставьте все остальное, и нативные поля учетных данных Playwright выполнят свою работу:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(proxy={
        # was: "socks5://gate.quantumproxies.io:SOCKS_PORT"
        "server": "http://gate.quantumproxies.io:PORT",
        "username": "USER",
        "password": "PASS",
    })
    page = browser.new_page()
    page.goto("https://httpbin.org/ip")
    print(page.text_content("body"))   # must be the proxy exit IP
    browser.close()

Вы ничего не теряете. Для браузерного трафика HTTP-прокси открывает туннель CONNECT и передает те же зашифрованные байты, что и туннель SOCKS5; различия между двумя протоколами важны для UDP и не-HTTP трафика, а не для загрузки страницы. Наш разбор различий между SOCKS5 и HTTP прокси содержит детали. И поскольку объект прокси также принимается newContext(), те же учетные данные дают вам ротацию по контексту, как описано в нашем руководстве по интеграции прокси Playwright.

Решение 2: белый список IP сохраняет socks5:// в живых

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

const { chromium } = require('playwright');

const browser = await chromium.launch({
  proxy: { server: 'socks5://gate.quantumproxies.io:PORT' }, // no creds
});
const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');
console.log(await page.textContent('body'));
await browser.close();

Белый список аутентифицирует машину, а не скрипт, и это весь компромисс. VPS или офисный выход с постоянным адресом работают идеально; эфемерные CI-раннеры, автоматически масштабируемые контейнеры и все, что находится за вращающимся NAT, потерпят неудачу в момент изменения адреса. Проверьте выход перед тем, как доверять запуску — тихое прямое соединение выглядит точно так же, как работающий прокси, пока ваша цель не начнет блокировать ваш собственный IP. Наш бесплатный проверщик качества IP показывает, что на самом деле является выходом, а не просто то, что он ответил.

Сравнение четырех решений для аутентификации Playwright SOCKS5 proxy: HTTP-эндпоинт, белый список IP, локальный релей и Firefox
Замена на HTTP-эндпоинт стоит одной строки и не требует дополнительных возможностей. Все, что справа от него, покупает вам схему socks5:// по определенной цене.

Решение 3: локальный релей, который удаляет учетные данные

Когда IP не может быть добавлен в белый список и у провайдера нет HTTP-порта, поставьте переводчик перед браузером. Шаблон всегда один и тот же: локальный слушатель без аутентификации пересылает на вышестоящий SOCKS5-эндпоинт с прикрепленными учетными данными. С gost это одна команда:

# Local no-auth HTTP listener -> authenticated upstream SOCKS5
gost -L=http://127.0.0.1:8080 \
     -F=socks5://USER:PASS@gate.quantumproxies.io:PORT

# Playwright then points at the local hop, with no credentials:
#   proxy: { server: 'http://127.0.0.1:8080' }

Два правила. Привяжите слушатель к 127.0.0.1, никогда к 0.0.0.0 — прокси без аутентификации, доступный из интернета, это открытый релей, который будет найден и использован в течение нескольких часов. И относитесь к релею как к процессу, который вы должны контролировать: если он умирает, Chromium возвращается к ошибке соединения, а не к прямому запросу, что, по крайней мере, громко. Этот подход стал достаточно распространенным, что практики публикуют небольшие специализированные реле, мы сравниваем варианты в нашем руководстве по инструментам релея аутентификации SOCKS5.

Решение 4: используйте Firefox вместо Chromium

Firefox реализует аутентификацию имени пользователя/пароля SOCKS5 нативно, что и является разницей, на которую постоянно указывает ветка обсуждения Playwright. Поменяйте тип браузера, и ошибка исчезнет:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.firefox.launch(proxy={
        "server": "socks5://gate.quantumproxies.io:PORT",
        "username": "USER",
        "password": "PASS",
    })
    page = browser.new_page()
    page.goto("https://httpbin.org/ip")
    print(page.text_content("body"))   # confirm the exit before trusting it
    browser.close()

Выполняйте шаг проверки каждый раз. Отсутствие ошибки в Playwright не является доказательством использования учетных данных — только эхо IP является таковым. И будьте ясны в том, что вы покупаете: другой движок рендеринга, другую поверхность отпечатка и скрытую экосистему, которая сильно склоняется к Chromium. Если ваша цель уже принимает Firefox, это бесплатно. Если вы выбрали Chromium по причинам антибота, смена движков для решения проблемы прокси — неправильный обмен — выберите решение 1 и оставьте ваш браузер.

Решение в одной строке каждое

Контрольный список конфигураций Playwright SOCKS5 proxy, которые работают в Chromium, против конфигураций, которые выдают ошибку или тихо терпят неудачу
Chromium принимает схему SOCKS5 и никогда учетные данные. Все, что справа от этого списка, терпит неудачу — половина без ошибки.

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

Поддерживает ли Playwright аутентификацию SOCKS5 proxy?

Не с Chromium. Опция прокси Playwright документирует имя пользователя и пароль как учетные данные HTTP(S), и у Chromium нет реализации имени пользователя/пароля SOCKS5, чтобы передать их, поэтому запуск выдает ошибку. Firefox в Playwright поддерживает это. Вопрос отслеживания, microsoft/playwright#10567, открыт с ноября 2021 года без запланированного исправления.

Что означает 'Browser does not support socks5 proxy authentication'?

Это означает, что вы передали учетные данные вместе с сервером socks5:// для запуска Chromium. Playwright проверяет комбинацию и отказывается, вместо того чтобы открывать браузер, который бы тихо их игнорировал. Либо перейдите на HTTP-порт шлюза и сохраните поля учетных данных, либо аутентифицируйтесь по белому списку IP и удалите их полностью.

Как использовать SOCKS5 proxy с Playwright в Python?

Передайте proxy={"server": "socks5://host:port"} без имени пользователя или пароля, и пусть провайдер авторизует публичный IP вашей машины. Если IP не стабилен, используйте HTTP-эндпоинт того же шлюза с учетными данными или перенаправьте через локальный релей. Всегда подтверждайте выход через эхо IP.

Может ли расширение Chrome добавить аутентификацию SOCKS5?

Нет. Трюк с расширением, используемый для аутентифицированных HTTP-прокси, полагается на chrome.webRequest.onAuthRequired, который срабатывает на HTTP 407 ответах. SOCKS5 аутентифицируется во время рукопожатия сокета, до существования любого HTTP-запроса, поэтому ни один API расширения не может его увидеть. Расширения переключателей прокси предупреждают об этом ограничении по той же причине.

Является ли SOCKS5 быстрее, чем HTTP для скрапинга Playwright?

Не существенно. HTTPS-трафик через HTTP-прокси использует туннель CONNECT, поэтому оба протокола передают один и тот же зашифрованный поток с сопоставимой нагрузкой. Реальные преимущества SOCKS5 — поддержка UDP и нейтральность протокола, ни одно из которых не используется при загрузке страницы браузера. Выбирайте тот эндпоинт, который аутентифицируется без проблем.

Краткая версия: перестаньте пытаться заставить Chromium делать то, чего он никогда не делал. Переместите задачу на HTTP-эндпоинт или добавьте в белый список и уберите учетные данные — и если вам нужно сохранить socks5:// с вращающимся выходом, поставьте релей в середине, а не обходной путь в вашем коде. Как только аутентификация решена, то, что определяет, будет ли запуск успешным, это пул за ним: резидентные выходы по более чем 200 странам, с ротацией по запросу или липкими сессиями, когда потоку нужна одна идентичность.

Получите HTTP и SOCKS5 эндпоинты в одном плане