# Использование прокси с Puppeteer и Chrome в безголовом режиме

Chrome получает прокси через флаг запуска, а Puppeteer передаёт учётные данные для каждой страницы. Один браузер соответствует одному выходному узлу, а закреплённая сессия сохраняет этот узел.


## Запуск с прокси и аутентификацией

```javascript
import puppeteer from "puppeteer";

const browser = await puppeteer.launch({
  headless: true,
  args: ["--proxy-server=http://res.hodlproxy.com:9000", "--no-first-run"],
});
const page = await browser.newPage();
await page.authenticate({ username: "USER-cc-us-sid-run1-ttl-30m", password: "PASS" });

await page.goto("https://api.ipify.org", { waitUntil: "domcontentloaded", timeout: 45000 });
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();
```

Вызывайте `page.authenticate` до первого перехода на каждой открываемой странице: Chrome запрашивает учётные данные прокси отдельно для каждой страницы. Имя пользователя содержит страну и идентификатор сессии, поэтому весь браузер использует один домашний выходной IP-адрес в течение заданного времени.


## Один прокси на браузер

Chrome применяет `--proxy-server` ко всему экземпляру браузера. Для нескольких стран или сессий запустите несколько браузеров (в безголовом режиме это требует мало ресурсов) либо используйте `puppeteer.launch` в пуле, где каждому рабочему процессу принадлежит идентификатор сессии. Библиотеки, обещающие отдельный прокси для каждой страницы, добавляют локальный промежуточный прокси; проще использовать отдельный браузер для каждой сессии.


## Блокировка изображений, шрифтов и медиафайлов

```javascript
await page.setRequestInterception(true);
page.on("request", (req) => {
  const t = req.resourceType();
  if (["image", "media", "font", "stylesheet"].includes(t)) return req.abort();
  req.continue();
});
```


## Согласованность

- Установите `Accept-Language` и часовой пояс в соответствии со страной выходного узла: `page.setExtraHTTPHeaders({\"Accept-Language\": \"de-DE,de;q=0.9\"})` и `page.emulateTimezone(\"Europe/Berlin\")`.
- Предотвратите утечки WebRTC с помощью `--force-webrtc-ip-handling-policy=disable_non_proxied_udp` в аргументах запуска.
- Используйте отдельный браузер для каждой учётной записи; сохраняйте его каталог пользовательских данных, чтобы при повторном входе браузер распознавался как то же устройство.


## Возможные ошибки

| Симптом | Причина | Решение |
| --- | --- | --- |
| net::ERR_TUNNEL_CONNECTION_FAILED | Шлюз отклонил CONNECT: неверные учётные данные или параметр либо нет выходного узла | Воспроизведите ошибку с cURL -v, чтобы увидеть код шлюза |
| net::ERR_PROXY_AUTH_UNSUPPORTED / запросы данных | authenticate() вызван после перехода | Вызовите page.authenticate до goto |
| Одинаковый IP-адрес во всех браузерах | Повторно используется один идентификатор сессии | Используйте отдельный -sid- для каждого браузера или не указывайте его |
| Очень медленная первая загрузка | Домашний выходной IP-адрес и ресурсоёмкая страница | Заблокируйте ресурсы и увеличьте тайм-аут до 45 с |


## Вопросы

**Может ли Puppeteer использовать SOCKS5 с паролем?**

Chrome не поддерживает аутентификацию SOCKS5. Используйте HTTP-прокси на порту 9000 с page.authenticate либо добавьте IP-адрес сервера в белый список и передайте --proxy-server=socks5://res.hodlproxy.com:9001.

Источник: https://hodlproxy.com/ru/guides/puppeteer-proxy
