Использование прокси с 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 МБ бесплатного пробного трафика, чтобы направить свой первый браузер на резидентный выход.