Использование прокси с Playwright и Puppeteer
Опубликовано: 23 июля 2026 · 6 мин чтения
Кратко: В Playwright передайте словарь proxy в launch() или, лучше, в new_context(), чтобы у каждого контекста был свой IP. В Puppeteer передайте --proxy-server в args и вызовите page.authenticate() для учётных данных. Используйте резидентный прокси, чтобы браузер выходил с реального домашнего IP, и отдельную sticky-сессию на каждый контекст/браузер, когда одновременно работаете с несколькими личностями.
Playwright
Playwright принимает словарь proxy с простым URL в server и отдельными полями для учётных данных. Самый простой способ — задать его в launch(), что применяется ко всему браузеру:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": "http://gw.roamproxy.com:41080",
"username": "YOUR_USERNAME",
"password": "YOUR_PASSWORD",
}
)
page = browser.new_page()
page.goto("https://ip.sb")
print(page.inner_text("body"))
browser.close()
Прокси на уровне контекста — один IP на личность
Более полезный приём — задавать прокси на new_context(). Каждый контекст — это изолированная сессия браузера: свои куки, хранилище и теперь свой IP — так что один процесс браузера может вести несколько личностей, которые не делят один выходной узел:
ctx_a = browser.new_context(proxy={
"server": "http://gw.roamproxy.com:41080",
"username": "USERNAME_session_a",
"password": "YOUR_PASSWORD",
})
ctx_b = browser.new_context(proxy={
"server": "http://gw.roamproxy.com:41080",
"username": "USERNAME_session_b",
"password": "YOUR_PASSWORD",
})
Дайте каждому контексту разную sticky-сессию в имени пользователя, и каждый получит стабильный, отдельный резидентный IP — о том, как работает строка сессии, см. в статье что такое прокси с ротацией.
Puppeteer
Puppeteer принимает прокси как флаг запуска Chromium и обрабатывает авторизацию на странице. Учётные данные не идут во флаге:
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({
args: ['--proxy-server=http://gw.roamproxy.com:41080'],
});
const page = await browser.newPage();
await page.authenticate({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' });
await page.goto('https://ip.sb');
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();
Puppeteer применяет прокси ко всему браузеру, поэтому, чтобы использовать несколько IP одновременно, нужно запускать несколько браузеров (каждый со своим --proxy-server и sticky-сессией) или поставить прокси-роутер впереди.
Проверьте выходной узел
Оба фрагмента кода выше переходят на эндпоинт проверки IP и выводят результат. Он должен показать резидентный выходной IP Roam и выбранную вами страну, а не настоящий адрес вашей машины. Если показан ваш настоящий IP, прокси не подключился — проверьте раздел частых вопросов.
Когда браузер не нужен
Playwright и Puppeteer — правильный инструмент, когда цель требует JavaScript или интерактивную проверку. Когда это не так — простой JSON API или статический HTML — полноценный браузер медленнее и тяжелее, чем нужно. Для скриптовых HTTP-запросов с точным, как у браузера, отпечатком используйте вместо этого curl_cffi, а о выборе между ними по слою защиты см. статью как обойти Cloudflare. Об управлении Playwright с помощью LLM см. browser-use с резидентными прокси.
Частые вопросы
Задавать прокси при запуске или на уровне контекста?
В Playwright предпочтительнее контекст. Задание прокси на launch() применяет один прокси ко всему браузеру; задание на new_context() позволяет каждому контексту иметь свой прокси — это нужно, когда один скрипт управляет несколькими личностями: каждый контекст становится отдельной сессией браузера с отдельным IP. В Puppeteer нет полноценной поддержки прокси на уровне контекста, поэтому для нескольких IP нужно либо запускать несколько браузеров, либо ставить прокси-роутер впереди.
Как передать имя пользователя и пароль?
В Playwright укажите их в словаре прокси как username и password рядом с server — никогда внутри URL сервера. В Puppeteer учётные данные не передаются в args; вы задаёте --proxy-server=host:port в args, а затем вызываете await page.authenticate({username, password}) перед первым переходом.
Нужен ли curl_cffi, если я уже использую настоящий браузер?
Нет — в этом и смысл использования браузера. Playwright и Puppeteer управляют настоящим Chromium, поэтому отпечаток TLS/JS уже подлинный. curl_cffi нужен, чтобы дать такой же отпечаток скриптовым HTTP-запросам, которые не используют браузер. С Playwright/Puppeteer нужно закрыть только сетевой слой, чем и занимается прокси.
Браузер запускается, но всё равно показывает мой настоящий IP — почему?
Обычно прокси задан не на том объекте или учётные данные встроены в URL сервера. Убедитесь, что значение server — это просто http://host:port, что username/password — отдельные ключи (Playwright) или заданы через page.authenticate() (Puppeteer), и что вы прикрепили прокси к тому контексту/браузеру, с которым реально переходите по страницам. Затем повторите проверку IP ниже.
Оба фреймворка ожидают простой прокси host:port плюс учётные данные — именно это и даёт Roam. Резидентные прокси с ротацией по $2/ГБ и статические резидентные по $4/IP в месяц, по HTTP и SOCKS5. Создайте аккаунт и получите 300 МБ бесплатного пробного трафика, чтобы направить свой первый браузер на резидентный выход.