Гайды · 6 мин
Прокси в Selenium, Playwright и Puppeteer: авторизация и ротация
- Редакция TrueSocks
- 6 мин чтения
Браузерная автоматизация и прокси - связка, на которой спотыкаются чаще всего. Адрес прокси задаётся в одну строку, а вот логин и пароль Chrome через ключ запуска не принимает, SOCKS5 с авторизацией работает не везде, а ротация в браузере ведёт себя иначе, чем в HTTP-клиенте. Ниже проверенные схемы для трёх инструментов: как передать авторизацию, как дать каждому контексту свой IP и как не раскрыть настоящий адрес.
Коротко
5 пунктов- Playwright принимает логин и пароль прокси отдельными полями при запуске браузера или создании контекста.
- В Puppeteer адрес задаётся ключом
--proxy-server, а авторизация вызовомpage.authenticate(). - Selenium с Chrome не умеет авторизацию прокси из коробки: используйте привязку по IP или локальный пересыльщик без пароля.
- SOCKS5 с логином и паролем Chromium не поддерживает, для браузерной автоматизации берите HTTP(S)-прокси.
- Для браузера нужна липкая сессия или статический адрес: смена IP посреди загрузки страницы ломает сессии на сайтах.
Как три инструмента работают с прокси
| Playwright | Puppeteer | Selenium | |
|---|---|---|---|
| Где задаётся прокси | Параметр proxy при запуске или в контексте | Ключ --proxy-server или опция контекста | Ключ Chrome или настройки Firefox |
| Логин и пароль | Поля username и password | page.authenticate() | Нет встроенного способа |
| Свой прокси на контекст | Да | Да, createBrowserContext | Нет, один браузер - один прокси |
| SOCKS5 с авторизацией в Chromium | Нет | Нет | Нет |
| Языки | Python, Node.js, Java, .NET | Node.js | Python, Java, C#, JS, Ruby |
Ограничение с SOCKS5 идёт от самого Chromium: браузер не поддерживает авторизацию на SOCKS-прокси. Поэтому для браузерной автоматизации проще всего заказать прокси с протоколом HTTP(S), он выбирается при оформлении заказа. Если без SOCKS5 не обойтись, используйте привязку по IP или локальный пересыльщик, о нём ниже.
Playwright
Playwright принимает прокси как объект с адресом и данными авторизации. Логин и пароль нужно передавать отдельными полями: учётные данные внутри строки server браузер не использует.
from playwright.sync_api import sync_playwright
PROXY = {
"server": "http://203.0.113.10:8000",
"username": "login",
"password": "password",
}
with sync_playwright() as p:
browser = p.chromium.launch(proxy=PROXY)
page = browser.new_page()
page.goto("https://api.ipify.org")
print(page.inner_text("body"))
browser.close()Свой прокси для каждого контекста
Контекст в Playwright - изолированная сессия со своими cookies и хранилищем, аналог отдельного профиля. Если задать прокси в контексте, в одном процессе браузера можно держать несколько независимых сессий с разными адресами. Заодно выставьте язык и часовой пояс под страну прокси.
const { chromium } = require("playwright");
const proxies = [
{ server: "http://203.0.113.10:8000", username: "login", password: "password" },
{ server: "http://203.0.113.11:8000", username: "login", password: "password" },
];
(async () => {
const browser = await chromium.launch();
for (const proxy of proxies) {
const context = await browser.newContext({
proxy,
locale: "de-DE",
timezoneId: "Europe/Berlin",
});
const page = await context.newPage();
await page.goto("https://api.ipify.org");
console.log(await page.textContent("body"));
await context.close();
}
await browser.close();
})();В объекте прокси есть ещё поле bypass: список доменов через запятую, к которым браузер пойдёт напрямую, например localhost,.internal.example. В старых версиях Playwright на Windows для прокси в контексте требовалось задать глобальный прокси при запуске браузера. Если видите такую ошибку, обновите Playwright или передайте в launch прокси-заглушку { server: "http://per-context" }.
Puppeteer
Puppeteer управляет Chrome напрямую, поэтому прокси задаётся ключом запуска браузера, а логин и пароль передаются отдельно на каждой вкладке.
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({
args: ["--proxy-server=http://203.0.113.10:8000"],
});
const page = await browser.newPage();
await page.authenticate({ username: "login", password: "password" });
await page.goto("https://api.ipify.org");
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();
})();Вызывайте page.authenticate() до первого перехода и для каждой новой вкладки. Чтобы в одном браузере работать с разными адресами, создайте контекст с собственным прокси: browser.createBrowserContext({ proxyServer: "http://203.0.113.11:8000" }). В версиях Puppeteer до 22 этот метод назывался createIncognitoBrowserContext.
Пакет proxy-chain
Если авторизация через authenticate неудобна, например страницы открываются сторонним кодом, используйте пакет proxy-chain. Он поднимает локальный прокси без пароля, который пересылает трафик на ваш прокси с авторизацией.
const puppeteer = require("puppeteer");
const proxyChain = require("proxy-chain");
(async () => {
const localUrl = await proxyChain.anonymizeProxy("http://login:[email protected]:8000");
// localUrl вида http://127.0.0.1:45678, без логина и пароля
const browser = await puppeteer.launch({ args: ["--proxy-server=" + localUrl] });
const page = await browser.newPage();
await page.goto("https://api.ipify.org");
await browser.close();
await proxyChain.closeAnonymizedProxy(localUrl, true);
})();Selenium
В Selenium прокси задаётся при создании драйвера и действует на весь браузер. Адрес без авторизации передаётся просто:
from selenium import webdriver
from selenium.webdriver.common.by import By
options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://203.0.113.10:8000")
driver = webdriver.Chrome(options=options)
driver.get("https://api.ipify.org")
print(driver.find_element(By.TAG_NAME, "body").text)
driver.quit()options = webdriver.FirefoxOptions()
options.set_preference("network.proxy.type", 1)
options.set_preference("network.proxy.socks", "203.0.113.10")
options.set_preference("network.proxy.socks_port", 1080)
options.set_preference("network.proxy.socks_version", 5)
options.set_preference("network.proxy.socks_remote_dns", True)
driver = webdriver.Firefox(options=options)Логин и пароль в ключе --proxy-server Chrome игнорирует, а окно авторизации прокси Selenium заполнить не может. Рабочие варианты:
- Привязка по IP. Разрешите доступ к прокси с адреса машины, где работает Selenium, и подключайтесь без пароля. Самый простой и надёжный путь для сервера с постоянным IP. Подробнее в статье логин или привязка по IP.
- Локальный пересыльщик. Утилита вроде gost слушает порт на
127.0.0.1без пароля и передаёт трафик на прокси с авторизацией. Работает и для SOCKS5. - selenium-wire. Популярная библиотека с поддержкой авторизации, но проект больше не развивается, поэтому для новых проектов лучше первые два варианта.
gost -L http://127.0.0.1:8080 -F http://login:[email protected]:8000
# в Selenium
options.add_argument("--proxy-server=http://127.0.0.1:8080")Ротация адресов в браузерной автоматизации
В HTTP-клиенте каждый запрос можно отправить через свой прокси. В браузере так не получится: страница грузит десятки ресурсов, держит соединения открытыми, и сайт ожидает, что вся сессия идёт с одного адреса. Поэтому единица ротации в браузере - контекст или экземпляр браузера, а не запрос.
- Задача
Пул статических адресов
ВыборОдин контекст Playwright или Puppeteer на один IPv4, задачи распределяются по контекстам. Предсказуемо и дёшево.
Смотреть: Пул статических адресов - Задача
Резидентские в режиме липкой сессии
ВыборОдин идентификатор сессии на контекст: адрес держится, пока контекст работает, новый контекст получает новый IP.
Смотреть: Резидентские в режиме липкой сессии - Задача
Аккаунты и долгие сессии
ВыборПостоянный ISP-адрес за каждым профилем, чтобы сайт видел привычный IP при каждом входе.
Смотреть: Аккаунты и долгие сессии
Утечки и согласованность профиля
Управляемый браузер - всё тот же браузер, и у него те же утечки. Проверьте три вещи при первом запуске:
- WebRTC. Chrome может отправить UDP-запрос к STUN-серверу мимо прокси. Ключ запуска
--force-webrtc-ip-handling-policy=disable_non_proxied_udpзапрещает такой трафик. - Часовой пояс и язык. В Playwright это
timezoneIdиlocaleконтекста, в Puppeteerpage.emulateTimezone("Europe/Berlin"), в Selenium с Chrome команда CDPEmulation.setTimezoneOverride. - DNS при SOCKS5. Chromium разрешает имена через SOCKS5-прокси сам, а в Firefox нужна настройка
network.proxy.socks_remote_dns, как в примере выше.
Как найти утечку за пять минут, рассказано в статье утечки WebRTC и DNS.
Ошибки и практические советы
| Симптом | Причина | Решение |
|---|---|---|
ERR_PROXY_CONNECTION_FAILED | Неверный адрес или порт, прокси не активен | Сверьте данные с выдачей, проверьте прокси через curl |
ERR_TUNNEL_CONNECTION_FAILED | Прокси отказал в туннеле, чаще всего из-за авторизации | Проверьте логин и пароль или привязку по IP |
| Окно ввода пароля в браузере | Авторизация не передана | Playwright: поля username и password; Puppeteer: authenticate |
Browser does not support socks5 proxy authentication | SOCKS5 с паролем в Chromium | HTTP(S)-прокси, привязка по IP или пересыльщик |
Таймаут на goto | Медленный прокси или тяжёлая страница | Увеличьте таймаут перехода, ждите domcontentloaded, а не полной загрузки |
- Проверяйте адреса до запуска. Короткий скрипт, который открывает api.ipify.org через каждый прокси, экономит часы отладки. Подробнее в статье как проверить прокси.
- Блокируйте лишнее. Картинки, шрифты и видео расходуют трафик резидентских прокси. В Playwright их можно отсечь через
page.route, в Puppeteer через перехват запросов. - Не храните пароли в коде. Читайте данные прокси из переменных окружения или файла, исключённого из репозитория.
- Соблюдайте правила сайтов. Умеренный темп и паузы между действиями нужны не только для стабильности, но и чтобы не создавать лишнюю нагрузку.
Для HTTP-запросов без браузера примеры собраны в статьях прокси в Python и прокси в curl, wget и Node.js. Сценарии сбора данных описаны на странице прокси для парсинга, а все типы адресов в каталоге.
Вопросы и ответы
Как передать логин и пароль прокси в Selenium?
Встроенного способа для Chrome нет. Используйте привязку прокси по IP, локальный пересыльщик без пароля, например gost, или библиотеку selenium-wire, учитывая, что она больше не развивается.
Можно ли в Playwright использовать разные прокси в одном браузере?
Да. Передайте параметр proxy в browser.new_context (в Node.js browser.newContext): у каждого контекста будут свои адрес, cookies и хранилище.
Почему SOCKS5 с паролем не работает в Puppeteer и Playwright?
Chromium не поддерживает авторизацию на SOCKS-прокси. Возьмите HTTP(S)-прокси, настройте привязку по IP или поднимите локальный пересыльщик без пароля.
Какие прокси лучше для браузерной автоматизации?
Статические IPv4 или ISP, если важна постоянная сессия, и резидентские в режиме липкой сессии, если нужно много разных адресов. Ротация на каждый запрос для браузера не подходит.
Прокси для этой задачи
Цена «от» за единицу на базовый срок, страны и скидка за объём видны на странице товара.
- Выбрать страну
Индивидуальные IPv4
68 стран, от 179 ₽ за IP / 30 дней
- Выбрать страну
Резидентские
60 стран, от 149 ₽ за 1 ГБ / 30 дней
- Выбрать страну
Прокси для парсинга
11 стран, от 59 ₽ за IP / 30 дней
- #Selenium
- #Playwright
- #Puppeteer
- #автоматизация
- #парсинг
Прокси предоставляются для законных задач. Спам, мошенничество и взлом запрещены, соблюдайте правила площадок. Правила сервиса
Читайте также
Все статьи- GDГайды
Прокси в Python: requests, httpx, aiohttp, Scrapy и SOCKS5
Как подключить прокси в Python: рабочие примеры для requests, httpx, aiohttp и Scrapy, логин и пароль в адресе, SOCKS5, ротация по списку и разбор ошибок 407 и 429.
10 мин - GDГайды
Прокси в curl, wget и Node.js: команды и примеры
Как работать через прокси в curl, wget и Node.js: HTTP(S) и SOCKS5 с логином и паролем, переменные окружения, fetch с undici, axios, ротация списка и диагностика.
6 мин - GDГайды
Ротация прокси и sticky-сессии: что это и когда что нужно
Что такое ротация прокси и липкая (sticky) сессия, как меняется IP у резидентских, мобильных и статических прокси и в каких задачах ротация помогает, а в каких мешает.
7 мин