Per-Context Proxy: независимая сеть для каждого браузера
Настройте отдельный прокси для каждого BrowserContext и автоматически согласуйте его региональные параметры.
Нужна поддерживаемая продуктовая документация?
У этой статьи есть соответствующая страница в центре документации. Используйте docs для каноничного сценария настройки, актуальных флагов и долгосрочной справки.
Сетевой маршрут каждого контекста
При запуске нескольких идентичностей или региональных рабочих процессов в браузере одного прокси на всю сессию недостаточно. Если каждый контекст использует один и тот же IP-адрес, трафик от разных идентичностей может быть связан через этот общий сетевой путь. Системы отслеживания наблюдают за паттернами IP, и два аккаунта, исходящие с одного адреса в схожее время, легко коррелируются.
Per-context proxy решает эту проблему, назначая выделенный прокси каждому BrowserContext. Каждый контекст маршрутизируется через отдельный прокси-сервер, получает собственный публичный IP и географические метаданные (часовой пояс, локаль, язык), полученные из местоположения выхода прокси. В сочетании с изоляцией отпечатков по контексту каждый контекст становится полностью независимой идентичностью без общих сетевых или отпечаточных сигналов.
В этой статье рассматривается работа per-context proxy в BotBrowser, настройка в Puppeteer и Playwright, а также оптимизация производительности для многорегиональных развертываний.
Влияние на приватность
Единый прокси создает общую сетевую идентичность для всех контекстов. Даже с разными профилями отпечатков общий IP становится точкой корреляции. Рассмотрим следующие риски:
- Корреляция по IP: два аккаунта, обращающиеся к одному сервису с одного IP, могут быть связаны, независимо от различий отпечатков
- Географическая несогласованность: контекст, настроенный с немецким профилем отпечатка, но маршрутизируемый через американский прокси, создает очевидное несоответствие между заявленным местоположением и сетевым происхождением
- Анализ тайминга: несколько идентичностей, использующих один прокси, могут быть коррелированы по паттернам тайминга трафика, так как все запросы исходят из одной сетевой точки
Per-context proxy устраняет эти риски. Каждый контекст имеет собственный прокси, собственный публичный IP и собственные географические метаданные. Между контекстами нет общих сетевых сигналов.
Сетевая модель контекста
Сетевая изоляция на уровне BrowserContext
В Chromium BrowserContext представляет собой изолированную среду просмотра. Каждый контекст имеет собственный контейнер cookies, localStorage, sessionStorage, IndexedDB и кеш. Стандартный Chromium предоставляет эту изоляцию хранилища из коробки.
BotBrowser расширяет эту изоляцию на сетевой уровень. Когда BrowserContext получает собственный прокси, весь HTTP-, HTTPS- и WebSocket-трафик из этого контекста маршрутизируется через указанный прокси-сервер. Другие контексты в том же экземпляре браузера не затрагиваются. Это настоящая сетевая изоляция на уровне контекста, а не перехватчик на уровне страницы, который может пропустить ранние запросы или WebSocket-соединения.
Автоматическое определение географии
Когда контекст подключается через прокси, BotBrowser определяет IP выхода прокси и автоматически выводит географические настройки для этого конкретного контекста:
- Часовой пояс: определяется по геолокации IP прокси (например,
America/New_Yorkдля прокси на восточном побережье США) - Локаль: соответствует стране прокси (например,
en-US) - Языки: устанавливаются на основе региона прокси (например,
en-US,en) - Геолокация: координаты приближенно вычисляются по IP
Это происходит независимо для каждого контекста. Контекст с американским прокси получает американские географические настройки, а контекст с немецким прокси в том же браузере получает немецкие настройки. Ручная настройка часового пояса, локали или языка не требуется.
Интеграция с отпечатками по контексту
Per-context proxy работает совместно с изоляцией отпечатков по контексту BotBrowser (ENT Tier3). Каждый контекст может получить:
- Уникальный профиль отпечатка через
--bot-profile - Независимый прокси и публичный IP
- Соответствующие географические метаданные, полученные из прокси
- Изолированное хранилище (cookies, localStorage, IndexedDB)
Это означает, что каждый контекст является полностью независимой идентичностью. Между контекстами нет общих сигналов отпечатков, сетевых путей или хранилища.
Назначение маршрута
Puppeteer: многорегиональная настройка
В Puppeteer per-context proxy настраивается через CDP (Chrome DevTools Protocol). Вы создаете BrowserContext, назначаете настройки прокси и профиль отпечатка через BotBrowser.setBrowserContextFlags, затем создаете страницы в этом контексте.
const puppeteer = require('puppeteer-core');
const browser = await puppeteer.launch({
executablePath: process.env.BOTBROWSER_EXEC_PATH,
headless: true,
defaultViewport: null,
args: ['--bot-profile=path/to/default-profile.enc'],
});
const client = await browser.target().createCDPSession();
// Контекст США с американским прокси
const usCtx = await browser.createBrowserContext({
proxyServer: 'socks5://user:pass@us-proxy.example.com:1080',
});
await client.send('BotBrowser.setBrowserContextFlags', {
browserContextId: usCtx._contextId,
botbrowserFlags: [
'--bot-profile=path/to/us-profile.enc',
'--proxy-ip=203.0.113.1',
],
});
const usPage = await usCtx.newPage();
// Контекст UK с британским прокси
const ukCtx = await browser.createBrowserContext({
proxyServer: 'socks5://user:pass@uk-proxy.example.com:1080',
});
await client.send('BotBrowser.setBrowserContextFlags', {
browserContextId: ukCtx._contextId,
botbrowserFlags: [
'--bot-profile=path/to/uk-profile.enc',
'--proxy-ip=198.51.100.1',
],
});
const ukPage = await ukCtx.newPage();
// Контекст DE с немецким прокси
const deCtx = await browser.createBrowserContext({
proxyServer: 'socks5://user:pass@de-proxy.example.com:1080',
});
await client.send('BotBrowser.setBrowserContextFlags', {
browserContextId: deCtx._contextId,
botbrowserFlags: [
'--bot-profile=path/to/de-profile.enc',
'--proxy-ip=192.0.2.1',
],
});
const dePage = await deCtx.newPage();
// Каждый контекст навигирует со своим прокси и географической идентичностью
await Promise.all([
usPage.goto('https://example.com'),
ukPage.goto('https://example.com'),
dePage.goto('https://example.com'),
]);
await browser.close();
Важно: BotBrowser.setBrowserContextFlags должен быть вызван до создания любой страницы в этом контексте. Процесс рендерера читает свои флаги при запуске. Если страница уже существует, новые флаги не применятся.
Puppeteer: прокси только через botbrowserFlags
Вы также можете настроить прокси полностью через botbrowserFlags, без передачи proxyServer в createBrowserContext:
const ctx = await browser.createBrowserContext();
await client.send('BotBrowser.setBrowserContextFlags', {
browserContextId: ctx._contextId,
botbrowserFlags: [
'--bot-profile=path/to/profile.enc',
'--proxy-server=socks5://user:pass@proxy.example.com:1080',
'--proxy-ip=203.0.113.1',
],
});
const page = await ctx.newPage();
Этот подход настраивает все параметры прокси (сервер, IP, правила обхода) в одном месте.
Playwright: прокси по контексту
Playwright предоставляет нативную поддержку прокси по контексту через browser.newContext():
const { chromium } = require('playwright-core');
const browser = await chromium.launch({
executablePath: 'path/to/botbrowser/chrome',
args: ['--bot-profile=path/to/profile.enc'],
headless: true,
});
// Контекст США
const usContext = await browser.newContext({
proxy: { server: 'socks5://us-proxy:1080', username: 'user', password: 'pass' },
});
// Контекст Германии
const deContext = await browser.newContext({
proxy: { server: 'socks5://de-proxy:1080', username: 'user', password: 'pass' },
});
// Каждый контекст автоматически получает географические настройки своего прокси
const usPage = await usContext.newPage();
const dePage = await deContext.newPage();
await usPage.goto('https://example.com');
await dePage.goto('https://example.com');
BotBrowser автоматически определяет часовой пояс, локаль и язык для каждого контекста на основе IP выхода его прокси.
Пропуск определения IP с --proxy-ip
Прокси каждого контекста вызывает запрос определения IP для вычисления географических настроек. Если вы уже знаете IP выхода прокси, этот шаг можно пропустить с помощью --proxy-ip:
await client.send('BotBrowser.setBrowserContextFlags', {
browserContextId: ctx._contextId,
botbrowserFlags: [
'--bot-profile=path/to/profile.enc',
'--proxy-server=socks5://user:pass@proxy.example.com:1080',
'--proxy-ip=203.0.113.1', // Пропустить запрос IP, использовать этот IP для гео-определения
],
});
Это устраняет задержку запроса IP для каждого контекста, что особенно полезно при последовательном создании множества контекстов.
Региональные параметры в текущей версии
Каждый региональный параметр определяется отдельно. Явно заданный часовой пояс, локаль, язык или положение сохраняет приоритет в этом контексте. Параметры со значением auto следуют прокси-маршруту контекста. Это позволяет закрепить обязательное значение и согласовать остальные с маршрутом.
Храните назначение прокси и региональные исключения в одной записи развёртывания. После изменения создавайте новый контекст и проверяйте каждый контекст по его собственному плану маршрута.
Политика UDP для каждого контекста
Транспортная политика теперь тоже задаётся на уровне контекста. --bot-udp-proxy определяет, использует ли контекст UDP-прокси и HTTP/3, поэтому контексты с общим профилем могут иметь разные ответы в одной сессии:
--bot-udp-proxy=false # значение по умолчанию для сессии
--bot-udp-proxy=true # исключение для контекста, которому нужен HTTP/3
Флаг без значения означает true. Задайте значение по умолчанию в основной командной строке, затем переопределите его для отдельного контекста через отпечаток по контексту. Контекст без собственного значения наследует значение по умолчанию, а политику можно изменить после создания контекста.
Запишите в план развёртывания два момента. Политика действует только в том контексте, где она задана, поэтому ограничение одной задачи не отключает HTTP/3 у соседних. Она применяется только к профилям, у которых уже есть право на UDP, то есть выбирает между утверждёнными вариантами поведения, а не открывает новый маршрут. Политика UDP по контексту требует ENT Tier3.
Типичные сценарии
Многорегиональное тестирование в одном браузере
Запускайте контексты США, UK и Германии одновременно в одном экземпляре браузера. Каждый контекст получает разный прокси, профиль отпечатка и географическую идентичность:
const regions = [
{
name: 'US',
proxy: 'socks5://user:pass@us.proxy.example.com:1080',
ip: '203.0.113.1',
profile: 'path/to/us-profile.enc',
},
{
name: 'UK',
proxy: 'socks5://user:pass@uk.proxy.example.com:1080',
ip: '198.51.100.1',
profile: 'path/to/uk-profile.enc',
},
{
name: 'DE',
proxy: 'socks5://user:pass@de.proxy.example.com:1080',
ip: '192.0.2.1',
profile: 'path/to/de-profile.enc',
},
];
const client = await browser.target().createCDPSession();
for (const region of regions) {
const ctx = await browser.createBrowserContext({
proxyServer: region.proxy,
});
await client.send('BotBrowser.setBrowserContextFlags', {
browserContextId: ctx._contextId,
botbrowserFlags: [
`--bot-profile=${region.profile}`,
`--proxy-ip=${region.ip}`,
],
});
const page = await ctx.newPage();
await page.goto('https://example.com');
// Проверить географическую идентичность
const tz = await page.evaluate(() =>
Intl.DateTimeFormat().resolvedOptions().timeZone
);
const lang = await page.evaluate(() => navigator.language);
console.log(`${region.name}: timezone=${tz}, language=${lang}`);
}
Per-Context: разный профиль + разный прокси
Каждый контекст может использовать совершенно разный профиль отпечатка. Профиль Windows с американским прокси и профиль macOS с британским прокси, все в одном браузере:
// Идентичность Windows + прокси США
const winCtx = await browser.createBrowserContext({
proxyServer: 'socks5://user:pass@us-proxy.example.com:1080',
});
await client.send('BotBrowser.setBrowserContextFlags', {
browserContextId: winCtx._contextId,
botbrowserFlags: [
'--bot-profile=path/to/windows-profile.enc',
'--proxy-ip=203.0.113.1',
],
});
// Идентичность macOS + прокси UK
const macCtx = await browser.createBrowserContext({
proxyServer: 'socks5://user:pass@uk-proxy.example.com:1080',
});
await client.send('BotBrowser.setBrowserContextFlags', {
browserContextId: macCtx._contextId,
botbrowserFlags: [
'--bot-profile=path/to/macos-profile.enc',
'--proxy-ip=198.51.100.1',
],
});
Переключение прокси в реальном времени
Для сценариев, требующих смены прокси контекста после создания (например, географическая ротация внутри сессии), используйте BotBrowser.setBrowserContextProxy (ENT Tier3):
const ctx = await browser.createBrowserContext();
const page = await ctx.newPage();
const client = await browser.target().createCDPSession(); // must use browser-level session
// Начать с прокси США
await client.send('BotBrowser.setBrowserContextProxy', {
browserContextId: ctx._contextId,
proxyServer: 'socks5://user:pass@us-proxy.example.com:1080',
proxyIp: '203.0.113.1',
});
await page.goto('https://example.com');
// Переключиться на прокси UK в реальном времени
await client.send('BotBrowser.setBrowserContextProxy', {
browserContextId: ctx._contextId,
proxyServer: 'socks5h://user:pass@uk-proxy.example.com:1080',
proxyIp: '198.51.100.1',
proxyBypassList: 'localhost;127.0.0.1',
proxyBypassRgx: 'cdn\\.example\\.com|/static/',
});
await page.goto('https://example.co.uk');
// Переключиться на прокси Японии
await client.send('BotBrowser.setBrowserContextProxy', {
browserContextId: ctx._contextId,
proxyServer: 'socks5://user:pass@jp-proxy.example.com:1080',
proxyIp: '192.0.2.1',
});
await page.goto('https://example.jp');
После каждого переключения BotBrowser заново определяет географические настройки и применяет их к контексту. Обновление географии вступает в силу при следующей навигации основного фрейма.
Оптимизация производительности
Используйте --proxy-ip для снижения нагрузки запросов
Когда вы знаете IP выхода каждого прокси, всегда передавайте --proxy-ip. Без него BotBrowser выполняет запрос определения IP для каждого контекста при первой навигации. При более чем 10 контекстах эти запросы накапливаются:
// Без --proxy-ip: каждый контекст делает запрос определения IP
// С --proxy-ip: гео-определение мгновенное, без сетевого запроса
const contexts = proxies.map(async (proxy) => {
const ctx = await browser.createBrowserContext({ proxyServer: proxy.server });
await client.send('BotBrowser.setBrowserContextFlags', {
browserContextId: ctx._contextId,
botbrowserFlags: [
'--bot-profile=path/to/profile.enc',
`--proxy-ip=${proxy.knownIp}`,
],
});
return ctx;
});
Общие ресурсы сессии
Контексты одной сессии повторно используют общие ресурсы, сохраняя раздельными данные, профиль и прокси-маршрут. Определяйте безопасную ёмкость на реальных страницах и конфигурации workers.
Комбинация с отпечатками по контексту
Когда вы назначаете и прокси, и профиль отпечатка для каждого контекста, каждый контекст становится полностью независимой идентичностью без накладных расходов отдельных экземпляров браузера:
// Один экземпляр браузера, 3 полные идентичности
const identities = [
{ profile: 'profiles/win-us.enc', proxy: 'socks5://us:1080', ip: '203.0.113.1' },
{ profile: 'profiles/mac-uk.enc', proxy: 'socks5://uk:1080', ip: '198.51.100.1' },
{ profile: 'profiles/linux-de.enc', proxy: 'socks5://de:1080', ip: '192.0.2.1' },
];
for (const id of identities) {
const ctx = await browser.createBrowserContext({ proxyServer: id.proxy });
await client.send('BotBrowser.setBrowserContextFlags', {
browserContextId: ctx._contextId,
botbrowserFlags: [
`--bot-profile=${id.profile}`,
`--proxy-ip=${id.ip}`,
],
});
// Каждый контекст: уникальный отпечаток + уникальный прокси + уникальная гео = полная независимость
}
Проверка версии
После настройки per-context proxy проверьте каждый контекст независимо:
async function verifyContext(context, label) {
const page = await context.newPage();
// Проверить публичный IP
await page.goto('https://httpbin.org/ip');
const ipData = await page.evaluate(() => document.body.textContent);
console.log(`[${label}] IP: ${ipData.trim()}`);
// Проверить часовой пояс
const tz = await page.evaluate(() =>
Intl.DateTimeFormat().resolvedOptions().timeZone
);
console.log(`[${label}] Часовой пояс: ${tz}`);
// Проверить язык
const lang = await page.evaluate(() => navigator.language);
console.log(`[${label}] Язык: ${lang}`);
// Проверить локаль
const locale = await page.evaluate(() =>
Intl.NumberFormat().resolvedOptions().locale
);
console.log(`[${label}] Локаль: ${locale}`);
await page.close();
}
await verifyContext(usCtx, 'US');
await verifyContext(ukCtx, 'UK');
await verifyContext(deCtx, 'DE');
Убедитесь, что каждый контекст показывает разный IP, часовой пояс и локаль, соответствующие географическому расположению прокси.
Эксплуатационные вопросы
Какой уровень лицензии требуется для per-context proxy?
Per-context proxy с изоляцией отпечатков требует ENT Tier3. Переключение прокси в реальном времени через BotBrowser.setBrowserContextProxy также требует ENT Tier3.
Можно ли использовать Playwright для per-context proxy?
Да. Playwright нативно поддерживает прокси по контексту через browser.newContext({ proxy: ... }). BotBrowser автоматически определяет географические настройки для каждого контекста Playwright.
Нужно ли вызывать setBrowserContextFlags до создания страницы?
Да. Процесс рендерера читает свои флаги при запуске. Если страница уже существует в контексте, новые флаги не применятся. Правильный порядок: createBrowserContext -> setBrowserContextFlags -> newPage.
Можно ли изменить прокси контекста после создания?
Да, через BotBrowser.setBrowserContextProxy (ENT Tier3). Это позволяет переключать прокси в реальном времени без пересоздания контекста. Географические настройки перевычисляются при следующей навигации основного фрейма.
Какие протоколы прокси поддерживаются?
Все протоколы, поддерживаемые --proxy-server, работают по контексту: socks5://, socks5h://, http://, https://. Все поддерживают встроенную аутентификацию (user:pass@host:port).
Сколько контекстов может работать одновременно? Расход памяти зависит от страниц и ресурсов. Определите поддерживаемое количество на репрезентативной нагрузке и оставьте резерв для пиков навигации.
BotBrowser автоматически определяет географию для каждого контекста? Да. Каждый контекст с отдельным прокси получает независимое гео-определение. BotBrowser определяет IP выхода и настраивает часовой пояс, локаль и язык для этого конкретного контекста.
Что произойдет, если не задать --proxy-ip?
BotBrowser выполнит автоматический запрос определения IP при первой навигации каждого контекста. Это работает корректно, но добавляет небольшую задержку. Установка --proxy-ip устраняет этот запрос.
Может ли каждый контекст использовать свою политику маршрута? Да. Назначьте документированные параметры прокси вместе с конфигурацией контекста и проверьте его по собственному плану маршрута.
Согласованность контекстов
Per-context proxy обеспечивает полную сетевую изоляцию для каждого BrowserContext в рамках одного экземпляра браузера. Каждый контекст маршрутизируется через собственный прокси, получает независимый публичный IP и географические метаданные (часовой пояс, локаль, язык), автоматически полученные из местоположения выхода прокси. В сочетании с профилями отпечатков по контексту каждый контекст работает как полностью независимая идентичность.
Для основ работы с прокси смотрите Настройка прокси. Для переключения прокси смотрите Динамическое переключение прокси. Для изоляции нескольких идентичностей смотрите Изоляция многоаккаунтного браузера. Также используйте Предотвращение утечек DNS и Предотвращение утечек WebRTC.
Похожие статьи
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.