Playwright — самый мощный фреймворк для браузерной автоматизации в 2026 году. Но без правильно настроенных мобильных прокси ваш скрейпер будет заблокирован в течение нескольких минут на любом серьёзном целевом сайте.
IP-адреса датацентров определяются по ASN ещё до отправки первого запроса. Резидентские прокси помогают, но быстро сгорают под нагрузкой скрейпинга. Мобильные прокси от реальных операторов 4G/5G — единственный класс IP-адресов, который выдерживает длительную браузерную автоматизацию.
Это руководство охватывает полную боевую конфигурацию: интеграцию SOCKS5, автоматическую ротацию IP через API ProxyGrow и паттерны, которые удержат ваш скрейпер живым даже на самых защищённых ресурсах.
Попробуйте настоящие мобильные прокси
Украина · Румыния · Латвия — IP-адреса операторов 4G/5G, мгновенная активация.
Зачем Playwright нужны мобильные прокси
Playwright управляет реальным движком Chromium, Firefox или WebKit. Браузер отправляет настоящие TLS-отпечатки, реальные HTTP/2-заголовки, подлинные значения navigator — и реальный IP-адрес.
Если этот IP принадлежит датацентровому ASN, никакая подмена браузерного отпечатка вас не спасёт. Платформа всё знает ещё до загрузки страницы.
Мобильные прокси решают проблему на сетевом уровне:
- Тип ASN: Kyivstar (AS15895), Orange Romania (AS8708), LMT Latvia (AS12578) — это ASN мобильных операторов, а не диапазоны датацентров
- Репутация CGNAT: мобильные IP разделяются тысячами реальных пользователей, поэтому массовые блокировки затрагивают живой трафик — и сайты их избегают
- История IP: операторские IP не попадают в коммерческие чёрные списки так, как датацентровые
Предварительные требования
npm init -y
npm install playwright axios
npx playwright install chromium
Вам понадобятся:
- SOCKS5-прокси ProxyGrow (хост, порт, логин, пароль)
- URL ротации IP (указан в ваших учётных данных ProxyGrow)
Базовая настройка Playwright + SOCKS5
Playwright принимает параметр proxy напрямую в chromium.launch() или browser.newContext().
const { chromium } = require('playwright');
const PROXY_HOST = 'your-proxy-host.proxygrow.net';
const PROXY_PORT = 10500;
const PROXY_USER = 'your-username';
const PROXY_PASS = 'your-password';
(async () => {
const browser = await chromium.launch({
proxy: {
server: `socks5://${PROXY_HOST}:${PROXY_PORT}`,
username: PROXY_USER,
password: PROXY_PASS,
},
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://httpbin.org/ip');
const body = await page.textContent('body');
console.log('Current IP:', JSON.parse(body).origin);
await browser.close();
})();
Запустите этот код — и вы увидите украинский, румынский или латвийский мобильный IP оператора, а не ваш реальный адрес или адрес датацентра.
Ротация IP через API между запросами
ProxyGrow предоставляет эндпоинт ротации. Его вызов инициирует смену IP на модеме (новое CGNAT-назначение от оператора). Именно так правильно делать ротацию — а не переключаться между разными прокси-серверами.
const { chromium } = require('playwright');
const axios = require('axios');
const PROXY_HOST = 'your-proxy-host.proxygrow.net';
const PROXY_PORT = 10500;
const PROXY_USER = 'your-username';
const PROXY_PASS = 'your-password';
const ROTATION_URL = 'https://your-proxy-host.proxygrow.net/rotate?token=YOUR_TOKEN';
async function rotateIP() {
try {
const response = await axios.get(ROTATION_URL, { timeout: 10000 });
console.log('IP rotated:', response.data);
// Wait for the new IP to stabilize
await new Promise(resolve => setTimeout(resolve, 3000));
} catch (err) {
console.error('Rotation failed:', err.message);
}
}
async function scrapeWithRotation(urls) {
const browser = await chromium.launch({
proxy: {
server: `socks5://${PROXY_HOST}:${PROXY_PORT}`,
username: PROXY_USER,
password: PROXY_PASS,
},
});
for (const url of urls) {
// Rotate IP before each target
await rotateIP();
const context = await browser.newContext({
userAgent: 'Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36',
viewport: { width: 390, height: 844 },
locale: 'en-US',
});
const page = await context.newPage();
try {
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
const title = await page.title();
console.log(`[${url}] Title: ${title}`);
} catch (err) {
console.error(`[${url}] Failed: ${err.message}`);
} finally {
await context.close();
}
}
await browser.close();
}
const targets = [
'https://example.com/product/1',
'https://example.com/product/2',
'https://example.com/product/3',
];
scrapeWithRotation(targets);
Ключевые архитектурные решения:
- Для каждого запроса создаётся новый
context, чтобы куки и хранилище не переходили между сессиями - User agent установлен как реальный Android Mobile UA — соответствует IP мобильного оператора
- Viewport задан в мобильных размерах — снова согласуется с типом оператора
- Ротация IP происходит перед каждым контекстом, давая каждому запросу свежий IP
Обход антибот-защиты
Современные антибот-системы (Cloudflare, DataDome, PerimeterX, Akamai) анализируют десятки сигналов помимо IP-адреса. Вот паттерны, которые имеют наибольшее значение.
Совпадение User Agent с типом IP
Если ваш IP принадлежит мобильному оператору, а UA говорит HeadlessChrome/124 — вы немедленно попадаете под подозрение. Реальные мобильные пользователи не запускают headless-браузеры.
Используйте реалистичный Android или iOS user agent:
const mobileUA = 'Mozilla/5.0 (Linux; Android 14; SM-S928B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.82 Mobile Safari/537.36';
Правильное отключение режима headless
У Playwright есть режим --headless=new, снижающий вероятность обнаружения, но некоторые сайты проверяют строку Headless в свойствах navigator. Используйте headless: false для максимально устойчивой конфигурации или подавите специфичные для ботов свойства navigator:
const context = await browser.newContext();
await context.addInitScript(() => {
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3] });
Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] });
});
Добавление задержек, имитирующих поведение человека
Боты скрейпят на машинной скорости. Реальные пользователи делают паузы, прокручивают страницу и кликают непоследовательно. Добавьте случайные задержки:
function randomDelay(min = 800, max = 3000) {
const ms = Math.floor(Math.random() * (max - min + 1)) + min;
return new Promise(resolve => setTimeout(resolve, ms));
}
await page.goto(url);
await randomDelay();
await page.mouse.move(200, 300);
await randomDelay(200, 600);
await page.mouse.move(400, 500);
await randomDelay();
Прохождение Cloudflare-проверок
Turnstile и JS-челленджи от Cloudflare требуют выполнения JavaScript и браузера, проходящего проверку окружения. С Playwright + мобильный прокси:
- Установите
headless: falseили используйтеheadless: 'new' - Дождитесь решения челленджа перед продолжением работы
- Ротируйте IP только между сессиями, а не в середине сессии
await page.goto(url);
// Wait for CF to resolve — up to 15s
await page.waitForFunction(
() => !document.title.includes('Just a moment'),
{ timeout: 15000 }
).catch(() => console.log('CF challenge may still be active'));
Боевой паттерн: пул прокси с очередью
Для крупномасштабного скрейпинга с несколькими прокси:
const { chromium } = require('playwright');
const axios = require('axios');
const PROXIES = [
{ host: 'proxy1.proxygrow.net', port: 10500, user: 'user1', pass: 'pass1', rotateUrl: 'https://...' },
{ host: 'proxy2.proxygrow.net', port: 10501, user: 'user2', pass: 'pass2', rotateUrl: 'https://...' },
{ host: 'proxy3.proxygrow.net', port: 10502, user: 'user3', pass: 'pass3', rotateUrl: 'https://...' },
];
let proxyIndex = 0;
function getNextProxy() {
const proxy = PROXIES[proxyIndex % PROXIES.length];
proxyIndex++;
return proxy;
}
async function scrapeURL(url) {
const proxy = getNextProxy();
// Rotate IP on the selected proxy
await axios.get(proxy.rotateUrl, { timeout: 10000 }).catch(() => {});
await new Promise(r => setTimeout(r, 2500));
const browser = await chromium.launch({
proxy: {
server: `socks5://${proxy.host}:${proxy.port}`,
username: proxy.user,
password: proxy.pass,
},
});
const context = await browser.newContext({
userAgent: 'Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36',
viewport: { width: 393, height: 852 },
});
const page = await context.newPage();
await page.goto(url, { waitUntil: 'networkidle', timeout: 45000 });
const html = await page.content();
await browser.close();
return html;
}
Лучшие ГЕО для скрейпинга с Playwright
| Целевой сайт по ГЕО | Рекомендуемое ГЕО ProxyGrow | Оператор |
|---|---|---|
| США/Глобальный | Румыния | Orange Romania (AS8708) |
| Специфика ЕС | Латвия | LMT (AS12578) |
| СНГ/Восточная Европа | Украина | Kyivstar (AS15895) |
| Любой EU e-commerce | Румыния или Латвия | Orange / LMT |
Румынские и латвийские IP расположены в ЕС, что позволяет проходить гео-ограничения на сайтах, ориентированных на ЕС, и избегать блокировок, связанных с GDPR.
Playwright vs. Puppeteer vs. Selenium
Для автоматизации с интенсивным использованием прокси:
| Функция | Playwright | Puppeteer | Selenium |
|---|---|---|---|
| Нативный SOCKS5 | Да | Требует флаг | Ограниченно |
| Несколько браузеров | Да | Только Chromium | Да |
| Изоляция контекста | Да (быстро) | Вручную | По сессии |
| Stealth-плагины | playwright-extra | puppeteer-extra | Флаги webdriver |
| Имитация мобильного UA | Первый класс | Вручную | Вручную |
Playwright выигрывает для прокси-скрейпинга, потому что его модель контекстов идеально ложится на изоляцию прокси на уровне запроса без создания новых процессов браузера.
Быстрый чек-лист настройки
✔ Установить playwright и axios
✔ Использовать SOCKS5 (не HTTP) для лучшего покрытия протоколов
✔ Установить мобильный user agent, соответствующий ГЕО оператора
✔ Установить мобильный viewport (390x844 или аналогичный)
✔ Создавать новый контекст для каждой сессии скрейпинга
✔ Ротировать IP через API между сессиями, а не в середине сессии
✔ Добавить случайные задержки между действиями
✔ Подавить свойство navigator.webdriver
✔ Сопоставить локаль с ГЕО прокси
Распространённые ошибки
Использование HTTP-прокси вместо SOCKS5
HTTP-прокси не могут передавать все типы трафика. SOCKS5 является протоконезависимым и более чисто обрабатывает WebSocket-соединения, бинарные протоколы и TLS.
Ротация IP в середине сессии
Если вы инициируете ротацию во время загрузки страницы, соединение обрывается и запросы завершаются с ошибкой. Всегда ротируйте IP перед открытием нового контекста браузера.
Десктопный UA с мобильным IP
IP Kyivstar или LMT, отправляющий трафик десктопного Chrome — статистическая аномалия. Большинство трафика мобильных операторов поступает с мобильных устройств. Используйте соответствующий мобильный UA.
Отсутствие ожидания после ротации
После вызова эндпоинта ротации модему нужно 2-4 секунды для завершения переподключения и получения нового IP от оператора. Пропустите это ожидание — и ваш первый запрос уйдёт с прежнего IP.
Попробуйте настоящие мобильные прокси
Украина · Румыния · Латвия — IP-адреса операторов 4G/5G, мгновенная активация.