Socks5Proxy

Настройка прокси в Puppeteer: подключение через --proxy-server и page.authenticate

Это руководство объясняет, как подключить HTTP-прокси Socks5Proxy через аргумент --proxy-server и аутентификацию page.authenticate в Puppeteer, подключение SOCKS5 и запуск браузеров с разными IP.

Как работает прокси в Puppeteer?

В Puppeteer прокси настраивается через аргументы при запуске Chrome. Адрес в --proxy-server применяется ко всем страницам браузера. Имя пользователя и пароль для HTTP-прокси нельзя передать через аргументы, поэтому они передаются через page.authenticate после открытия страницы. Тогда Puppeteer автоматически отвечает на запросы аутентификации прокси.

Пример использует IP 198.51.100.23, HTTP-порт 8000, SOCKS5-порт 1080, имя пользователя spx_user, пароль spx_pass.

npm install puppeteer

Как подключиться к HTTP-прокси с аутентификацией?

Добавьте --proxy-server=198.51.100.23:8000 в args для launch, а сразу после создания страницы через newPage передайте логин и пароль в page.authenticate. Аутентификацию нужно выполнять для каждой новой страницы.

HTTPS-сайты открываются нормально. Браузер создает CONNECT-туннель для шифрованного обмена.

import puppeteer from "puppeteer";

const browser = await puppeteer.launch({
  headless: true,
  args: ["--proxy-server=http://198.51.100.23:8000"],
});

const page = await browser.newPage();
await page.authenticate({ username: "spx_user", password: "spx_pass" });

await page.goto("https://api.ipify.org", { waitUntil: "domcontentloaded" });
console.log(await page.evaluate(() => document.body.innerText)); // proxy IP

await browser.close();

Как использовать прокси SOCKS5?

Вставьте адрес socks5:// в --proxy-server. Однако Chrome не поддерживает аутентификацию по логину и паролю для SOCKS-прокси, поэтому page.authenticate не применяется к SOCKS5. Для подключения через SOCKS5 используйте IP-авторизацию, зарегистрировав IPv4 сервера, где выполняется этот код, в консоли.

Если требуется подключение с именем пользователя и паролем, проще всего использовать HTTP-порт того же IP. Так как IP одинаковый, местоположение будет выглядеть одинаково для целевого сайта.

import puppeteer from "puppeteer";

const browser = await puppeteer.launch({
  args: ["--proxy-server=socks5://198.51.100.23:1080"], // server IP is authorized in the dashboard
});
const page = await browser.newPage();
await page.goto("https://api.ipify.org");
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();

Как запустить браузеры с разными IP?

Chrome использует один прокси на запущенный браузер. Для работы с разными IP нужно запускать отдельные браузеры. Код ниже получает список ip:port:user:pass через API и открывает 3 браузера с разными IP, выводя IP каждой страницы.

Множество открытых браузеров потребляет много памяти. Рекомендуется использовать очередь задач и ограничивать количество одновременно запущенных браузеров.

import puppeteer from "puppeteer";

const KEY = "YOUR_API_KEY";
const res = await fetch("https://socks5proxy.io/api/v1/proxies/download?format=ip:port:user:pass&protocol=http", {
  headers: { Authorization: "Bearer " + KEY },
});
const lines = (await res.text()).trim().split("\n").slice(0, 3);

await Promise.all(lines.map(async (line) => {
  const [ip, port, user, pass] = line.trim().split(":");
  const browser = await puppeteer.launch({ args: ["--proxy-server=http://" + ip + ":" + port] });
  try {
    const page = await browser.newPage();
    await page.authenticate({ username: user, password: pass });
    await page.goto("https://api.ipify.org", { timeout: 30000 });
    console.log(ip, await page.evaluate(() => document.body.innerText));
  } finally {
    await browser.close();
  }
}));

Как открывать страницы быстрее?

Через прокси загружаются все ресурсы (изображения, шрифты, видео), что увеличивает трафик. Если нужны только тексты и данные, отключите загрузку медиа через page.setRequestInterception для экономии трафика в общих тарифах.

Параметр waitUntil тоже важен. networkidle0 ждёт завершения всех запросов, что может быть медленно. Лучше использовать page.waitForSelector, чтобы переходить к следующему шагу, как только появятся нужные элементы.

await page.setRequestInterception(true);
page.on("request", (req) => {
  const type = req.resourceType();
  if (type === "image" || type === "font" || type === "media") req.abort();
  else req.continue();
});

Можно ли использовать разные IP для каждой страницы в одном браузере?

Параметр --proxy-server в Chrome применяется ко всему браузеру, что затрудняет использование разных IP для разных страниц. Puppeteer 22+ позволяет задавать proxyServer для каждого browser.createBrowserContext, разделяя прокси по контекстам. Контексты также изолируют куки и хранилища, что удобно для работы с аккаунтами.

Страницы, созданные в контексте, также можно аутентифицировать с помощью page.authenticate, передав логин и пароль. Это потребляет меньше памяти, чем запуск нескольких браузеров.

import puppeteer from "puppeteer";

const browser = await puppeteer.launch();
const context = await browser.createBrowserContext({ proxyServer: "http://198.51.100.23:8000" });
const page = await context.newPage();
await page.authenticate({ username: "spx_user", password: "spx_pass" });
await page.goto("https://api.ipify.org");
console.log(await page.evaluate(() => document.body.innerText));
await context.close();
await browser.close();

Что нужно настроить, чтобы выглядеть как пользователь из этой страны?

Установите Accept-Language через page.setExtraHTTPHeaders и временную зону через page.emulateTimezone согласно стране IP. Несоответствие может привести к неправильному языку или формату дат.

Размер экрана можно задать через page.setViewport, а для эмуляции мобильных устройств используйте настройки KnownDevices из Puppeteer в page.emulate.

await page.setExtraHTTPHeaders({ "Accept-Language": "ja-JP,ja;q=0.9" });
await page.emulateTimezone("Asia/Tokyo");
await page.setViewport({ width: 1366, height: 900 });

Как поддерживать стабильность браузера в длительных задачах?

Для стабильной работы лучше перезапускать браузер после обработки определенного числа страниц, а не держать его открытым долго. Долгая работа увеличивает потребление памяти и риск ошибок.

Обязательно вызывайте page.close в блоке try и finally для каждой страницы, а также добавляйте timeout в goto, чтобы избежать зависания на страницах без ответа. Если задача не удалась, попробуйте снова с другим прокси, запустив новый браузер.

Фиксируйте время ответа и ошибки по каждому прокси, чтобы выявлять медленные IP и обращаться в поддержку или менять настройки задач.

Как исправить частые ошибки?

net::ERR_INVALID_AUTH_CREDENTIALS или 407 означает, что неверны данные в page.authenticate или вызов сделан не после newPage. Убедитесь, что вызываете его перед goto для каждой страницы.

net::ERR_PROXY_CONNECTION_FAILED означает, что неверен адрес или порт. Убедитесь, что используете HTTP-порт для HTTP-адресов и SOCKS5-порт для SOCKS5. Если SOCKS5 отклоняет соединение, проверьте, добавлен ли исходящий IP сервера в список разрешённых для IP-авторизации.

Настройка прокси в Puppeteer: аутентификация через page.authenticate | Socks5Proxy