Headless-браузеры рендерят JavaScript, поэтому справляются с современными сайтами, которые обычным HTTP-клиентам не по зубам. Но браузер всё равно отправляет все запросы с одного IP, и автоматизация спалится в тот момент, когда сайт включит лимит запросов или снимет фингерпринт этого адреса. Использование прокси с Playwright и Puppeteer распределяет трафик по разным IP и, при правильной настройке, заставляет вашу автоматизацию выглядеть как обычные пользователи. Ниже — рабочая настройка для обоих, на Python и Node.
Задавайте прокси при запуске браузера. Аутентификацию передавайте отдельными полями username и password — не вшивайте учётные данные в URL сервера:
from playwright.sync_api import sync_playwright
PROXY = {
"server": "http://gate.jibaoproxy.com:10001",
"username": "USERNAME",
"password": "PASSWORD",
}
with sync_playwright() as p:
browser = p.chromium.launch(proxy=PROXY, headless=True)
page = browser.new_page()
page.goto("https://httpbin.org/ip")
print(page.inner_text("body"))
browser.close()
JIBAO отдаёт на шлюзе и HTTP, и SOCKS5. Для браузерной автоматизации используйте HTTP-эндпоинт: Playwright и Puppeteer не поддерживают SOCKS5-прокси с аутентификацией, так что HTTP-с-авторизацией — надёжный выбор.
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: true,
proxy: {
server: 'http://gate.jibaoproxy.com:10001',
username: 'USERNAME',
password: 'PASSWORD',
},
});
const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');
console.log(await page.innerText('body'));
await browser.close();
})();
Самый чистый способ ротации в Playwright — один IP на один BrowserContext. Каждый контекст — изолированная сессия (свои cookie и кэш), так что привязка каждого к отдельному выходному IP даёт параллельные личности из одного процесса браузера:
from playwright.sync_api import sync_playwright
def ctx_proxy(session_id):
return {
"server": "http://gate.jibaoproxy.com:10001",
"username": f"USERNAME-session-{session_id}",
"password": "PASSWORD",
}
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
for i in range(3):
context = browser.new_context(proxy=ctx_proxy(f"ctx{i}"))
page = context.new_page()
page.goto("https://httpbin.org/ip")
print(i, page.inner_text("body"))
context.close()
browser.close()
Каждый контекст использует отдельный токен sticky-сессии, поэтому IP остаётся стабильным внутри контекста (хорошо для логин-флоу), но различается между контекстами (хорошо для параллельной работы со множеством аккаунтов). Именно этот паттерн автоматизируют анти-детект браузеры вроде GoLogin и Dolphin Anty — см. наш гайд по настройке прокси в анти-детект браузерах.
Puppeteer задаёт прокси-сервер как флаг запуска Chromium, а затем аутентифицируется на объекте страницы:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: 'new',
args: ['--proxy-server=http://gate.jibaoproxy.com:10001'],
});
const page = await browser.newPage();
await page.authenticate({ username: 'USERNAME', password: 'PASSWORD' });
await page.goto('https://httpbin.org/ip');
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();
})();
Поскольку прокси задаётся флагом уровня процесса, один браузер Puppeteer использует один IP. Чтобы ротировать, запускайте свежий браузер на каждую личность (тяжелее) либо ведите ротацию через шлюз, меняющий IP на каждое соединение.
Любой флоу, создающий сессионную cookie, обязан держать один и тот же IP на всю её жизнь. Cookie, выпущенная на IP-A и внезапно появившаяся с IP-B, читается как перехват сессии и приводит к повторной авторизации или бану. Держите один контекст (или один браузер) на каждый залогиненный аккаунт, закреплённый за одним токеном sticky-сессии, на всё время сессии.
Резидентный IP необходим, но недостаточен. Сайты также читают TLS/JA4-рукопожатие вашего браузера, порядок HTTP/2-фреймов, canvas, WebGL и свойства navigator. Голый headless Chromium палит navigator.webdriver = true и headless-фингерпринт, который сводит на нет даже лучший IP. Смягчайте это stealth-плагинами и реалистичными флагами запуска:
// Node: puppeteer-extra + stealth
const puppeteer = require('puppeteer-extra');
const Stealth = require('puppeteer-extra-plugin-stealth');
puppeteer.use(Stealth());
// Реалистичные флаги запуска
const browser = await puppeteer.launch({
headless: 'new',
args: [
'--proxy-server=http://gate.jibaoproxy.com:10001',
'--disable-blink-features=AutomationControlled',
'--window-size=1920,1080',
],
});
Чтобы точно увидеть, какие сигналы вы палите, прогоните свой автоматизированный браузер через бесплатный чекер фингерпринтов JA3/JA4 от JIBAO. О том, почему рукопожатия попадают под флаг, подробнее в обходе TLS-фингерпринтинга и полном рецепте обхода Cloudflare.
headless=False, чтобы видеть, что целевой сайт реально показывает вашему боту.Получите $5 бесплатного баланса и резидентные IP, которые держат Playwright и Puppeteer вне бан-листа.
Начать бесплатноНовым пользователям — 5U при регистрации, бонус к первому пополнению. Акция ограничена по времени.