got-scraping в Node.js: руководство по прокси и генерации заголовков

Полное руководство по got-scraping в Node.js: генерация браузерных заголовков, резидентные прокси, retry hooks и продакшн-паттерны для масштабного скрейпинга.

got-scraping in Node.js: A Developer's Guide to Headers, HTTP/2 & Residential Proxies

Если вы когда-либо пытались скрейпить веб-сайты через Node.js и получали 403 Forbidden после десятого запроса — вы не одиноки. Библиотека got-scraping в Node.js от Apify решает две главные проблемы: генерацию правдоподобных браузерных заголовков и нативную поддержку HTTP/2. В этом руководстве мы разберём, как интегрировать got-scraping с резидентными прокси, настроить ротацию IP и построить надёжную инфраструктуру для сбора данных.

Что такое got-scraping в Node.js и почему обычные запросы блокируются

Антибот-системы современных сайтов анализируют не только IP-адрес, но и сигнатуру HTTP-клиента. Когда вы отправляете запрос через got или axios без настроенных заголовков, сервер видит несоответствие: TLS-отпечаток говорит «это Node.js», а заголовки отсутствуют или идут в неправильном порядке. Результат — блокировка, часто с первого запроса.

Проблема усугубляется тем, что браузеры отправляют заголовки в строго определённом порядке. Согласно документации MDN, такие заголовки, как Accept, Accept-Language, Accept-Encoding и Sec-CH-UA, должны идти до Cookie и Referer. Обычные HTTP-клиенты не гарантируют порядок заголовков, что сразу выдаёт автоматизированный клиент.

Библиотека got-scraping — это расширение got, созданное специально для веб-скрейпинга. Она интегрирует пакет header-generator, который создаёт связные наборы заголовков, имитирующие реальные браузеры на конкретных операционных системах и устройствах. Кроме того, got-scraping поддерживает HTTP/2, что критически важно: многие антибот-системы проверяют версию протокола и ALPN-согласование.

Сравнение HTTP-клиентов для скрейпинга

Возможность got axios got-scraping
Генерация браузерных заголовков Нет Нет Да (header-generator)
HTTP/2 Через плагин Нет Нативно
Порядок заголовков как в браузере Нет Нет Да
Поддержка proxyUrl (HTTP/2) Ограниченная Нет Да
Retry hooks Да Через interceptors Да (расширенные)

Генератор заголовков got scraping: как это работает

Пакет header-generator — ядро got-scraping. Он не просто подставляет случайные значения, а создаёт связные наборы заголовков. Если вы указываете браузер Chrome 120 на Windows 11, генератор выдаст именно те заголовки, которые отправляет реальный Chrome 120 на Windows 11 — включая Sec-CH-UA, Sec-CH-UA-Platform, Accept-Language и правильный порядок.

Это критически важно, потому что антибот-системы, такие как Cloudflare и Akamai, проверяют связность набора. Если User-Agent говорит «Chrome на Windows», а Sec-CH-UA-Platform отсутствует или содержит «macOS» — запрос помечается как подозрительный. got scraping header generator решает эту проблему, создавая комбинации, которые проходят даже глубокие проверки связности.

Генератор поддерживает три категории параметров:

  • browserschrome, firefox, safari, edge
  • devicesdesktop, mobile
  • operatingSystemswindows, macos, linux, android, ios

Каждый сгенерированный набор включает около 15–20 заголовков, что соответствует реальному браузерному запросу. Сравните это с типичным axios.get(), который отправляет 3–4 заголовка — этого достаточно для блокировки на любом защищённом сайте.

Идиоматичный API: got.extend, useHeaderGenerator и proxyUrl

got-scraping построен на паттерне got.extend() — идиоматичном способе создания кастомных инстансов got с предустановленными опциями. Вместо того чтобы передавать заголовки и прокси при каждом запросе, вы создаёте расширенный клиент один раз. Это особенно удобно для got-scraping proxy конфигураций, где параметры прокси и заголовков нужно держать в одном месте.

Функция useHeaderGenerator — это got-плагин, который подключает генератор заголовков к каждому запросу. Она принимает headerGeneratorOptions с теми же параметрами браузеров, устройств и ОС.

const { gotScraping } = require('got-scraping');

const client = gotScraping.extend({
  headerGeneratorOptions: {
    browsers: ['chrome', 'edge'],
    devices: ['desktop'],
    operatingSystems: ['windows', 'macos'],
  },
  http2: true,
  timeout: { request: 30000 },
  retry: { limit: 3 },
});

const response = await client.get('https://example.com/data');
console.log(response.body);

Опция proxyUrl поддерживает как HTTP/1.1, так и HTTP/2 прокси. Это важно, потому что многие прокси-провайдеры работают только по HTTP/1.1, что может вызвать несоответствие между HTTP/2 запросом и HTTP/1.1 прокси-туннелем. got-scraping корректно обрабатывает оба сценария.

Маршрутизация через резидентные прокси ProxyHat

Когда заголовки и TLS-отпечаток выглядят правдоподобно, следующим фильтром становится IP-адрес. Дата-центр IP-адреса легко определяются по ASN: если запрос приходит из диапазона AWS или DigitalOcean, антибот-система немедленно повышает риск-скор, даже при идеальных заголовках.

Резидентные прокси используют IP-адреса реальных интернет-провайдеров, что делает их неотличимыми от обычных пользователей. ProxyHat предоставляет резидентные, мобильные и дата-центр прокси через единый шлюз gate.proxyhat.com. Для nodejs scraping proxy конфигураций это означает единый эндпоинт с гибким гео-таргетингом.

Для HTTP-подключения используйте порт 8080:

const proxyUrl = 'http://user-country-US:password@gate.proxyhat.com:8080';

const client = gotScraping.extend({
  headerGeneratorOptions: {
    browsers: ['chrome'],
    devices: ['desktop'],
    operatingSystems: ['windows'],
  },
  proxyUrl,
  http2: true,
});

const res = await client.get('https://httpbin.org/ip');
console.log(res.body);

Для SOCKS5-подключения используйте порт 1080:

const socksProxyUrl = 'socks5://user-country-DE:password@gate.proxyhat.com:1080';

const client = gotScraping.extend({
  headerGeneratorOptions: {
    browsers: ['firefox'],
    devices: ['desktop'],
    operatingSystems: ['linux'],
  },
  proxyUrl: socksProxyUrl,
});

Geo-таргетинг и сессионные флаги передаются в имени пользователя. Например, user-country-US-session-abc123 направляет запрос через резидентный IP в США с закреплённой сессией. Это позволяет поддерживать cookies и состояние между запросами. Подробнее о доступных локациях — на странице локаций ProxyHat.

Рабочий пример: ротация резидентных прокси с retry hooks

В продакшене недостаточно одного прокси — нужна ротация. got-scraping предоставляет хуки beforeRequest, beforeRetry и afterResponse, которые позволяют динамически менять прокси между запросами и при ошибках. Это идиоматичный способ реализации got-scraping proxy ротации без внешних библиотек.

Следующий пример создаёт клиент got-scraping, который генерирует уникальный идентификатор сессии для каждого запроса, маршрутизирует через резидентные прокси ProxyHat и автоматически ретраит при 403 и 429.

const { gotScraping } = require('got-scraping');
const crypto = require('crypto');

const PROXYHAT_USER = 'your-username';
const PROXYHAT_PASS = 'your-password';
const GATEWAY = 'gate.proxyhat.com';

function makeProxyUrl(country = 'US') {
  const session = crypto.randomBytes(6).toString('hex');
  const username = `${PROXYHAT_USER}-country-${country}-session-${session}`;
  return `http://${username}:${PROXYHAT_PASS}@${GATEWAY}:8080`;
}

const client = gotScraping.extend({
  headerGeneratorOptions: {
    browsers: ['chrome', 'edge'],
    devices: ['desktop'],
    operatingSystems: ['windows', 'macos'],
  },
  http2: true,
  timeout: { request: 30000 },
  retry: {
    limit: 4,
    statusCodes: [403, 429, 500, 502, 503],
    backoffLimit: 5000,
  },
  hooks: {
    beforeRequest: [
      (options) => {
        options.proxyUrl = makeProxyUrl('US');
      },
    ],
    beforeRetry: [
      (error, retryCount, options) => {
        console.log(`Retry ${retryCount}: ${error.message}`);
        options.proxyUrl = makeProxyUrl('US');
      },
    ],
    afterResponse: [
      (response, retryWithMergedOptions) => {
        if (response.statusCode === 403) {
          console.log('403 — ротация прокси и ретрай');
          return retryWithMergedOptions({
            proxyUrl: makeProxyUrl('US'),
          });
        }
        return response;
      },
    ],
  },
});

async function scrape(urls) {
  const results = [];
  for (const url of urls) {
    try {
      const res = await client.get(url);
      results.push({ url, status: res.statusCode, body: res.body });
    } catch (err) {
      console.error(`Failed: ${url} — ${err.message}`);
    }
  }
  return results;
}

const targets = [
  'https://httpbin.org/ip',
  'https://httpbin.org/headers',
  'https://httpbin.org/user-agent',
];

scrape(targets).then(console.log);

Ключевые моменты этого примера:

  • Уникальная сессия на запрос — каждый запрос получает свежий IP через crypto.randomBytes
  • Retry с ротацией — при 403/429 меняется не только задержка, но и прокси
  • afterResponse-хук — перехватывает 403 даже без исключения, позволяя ретрай с новым прокси
  • backoffLimit: 5000 — максимальная задержка 5 секунд между ретраями

Продакшн-паттерны: конкурентность, cookie jars и Crawlee

Ограничение конкурентности с p-limit

При скрейпинге сотен URL важно ограничить параллельность, чтобы не перегружать целевой сервер и не исчерпать лимиты прокси. Пакет p-limit — стандартный способ контроля конкурентности в Node.js.

const pLimit = require('p-limit');

const limit = pLimit(10); // максимум 10 одновременных запросов

async function scrapeConcurrent(urls) {
  const tasks = urls.map(url =>
    limit(() => client.get(url).then(res => ({
      url,
      status: res.statusCode,
    })))
  );
  return Promise.allSettled(tasks);
}

Лимит 10–20 одновременных соединений — хороший баланс между скоростью и блокировками. При использовании резидентных прокси ProxyHat можно увеличить конкурентность до 50–100, в зависимости от пула доступных IP. Но помните: агрессивная конкурентность повышает риск триггера антибот-систем, даже с резидентными IP.

Cookie jars для поддержания сессий

Некоторые сайты требуют cookies для прохождения антибот-проверок. got-scraping поддерживает tough-cookie через опцию cookieJar. Это особенно полезно при многошаговом скрейпинге: первый запрос получает cookies, последующие используют их автоматически.

const { CookieJar } = require('tough-cookie');

const jar = new CookieJar();

const sessionClient = gotScraping.extend({
  headerGeneratorOptions: {
    browsers: ['chrome'],
    devices: ['desktop'],
    operatingSystems: ['windows'],
  },
  proxyUrl: makeProxyUrl('US'),
  cookieJar: jar,
});

// Первый запрос — получает cookies
await sessionClient.get('https://example.com/');
// Второй — использует cookies из jar
await sessionClient.get('https://example.com/dashboard');

При использовании cookie jar важно закрепить сессию прокси через -session-abc123 в имени пользователя, чтобы cookies соответствовали одному IP. Если IP меняется между запросами, а cookies остаются — это может вызвать подозрение.

Масштабирование: переход на Crawlee и CheerioCrawler

Когда логика скрейпинга усложняется — очередь URL растёт до тысяч, нужны парсинг HTML, дедупликация и хранение результатов — стоит перейти на Crawlee, фреймворк от Apify, построенный поверх got-scraping. CheerioCrawler использует got-scraping под капотом и добавляет:

  • Очередь запросов с дедупликацией
  • Автоматический retry с экспоненциальной задержкой
  • Управление cookies и сессиями
  • Интеграцию с прокси через ProxyConfiguration
  • Контроль конкурентности из коробки
const { CheerioCrawler, ProxyConfiguration } = require('crawlee');

const proxyConfiguration = new ProxyConfiguration({
  proxyUrls: [
    'http://user-country-US-session-s1:pass@gate.proxyhat.com:8080',
    'http://user-country-US-session-s2:pass@gate.proxyhat.com:8080',
    'http://user-country-US-session-s3:pass@gate.proxyhat.com:8080',
  ],
});

const crawler = new CheerioCrawler({
  proxyConfiguration,
  maxConcurrency: 10,
  maxRequestRetries: 3,
  requestHandler: async ({ $, request }) => {
    const title = $('title').text();
    console.log(`${request.url}: ${title}`);
  },
});

await crawler.run([
  'https://example.com/page1',
  'https://example.com/page2',
]);

Crawlee автоматически ротирует прокси из ProxyConfiguration между запросами, что снимает необходимость ручного управления в хуках. Для больших проектов это значительно упрощает код и повышает надёжность.

Когда без headless-браузера не обойтись

got-scraping эффективен для сайтов, где контент приходит в HTML-ответе. Но если сайт рендерит контент через JavaScript (SPA на React/Vue), или использует продвинутые антибот-проверки (Cloudflare Turnstile, Akamai Bot Manager с canvas-фингерпринтингом), HTTP-клиент не справится.

В таких случаях переходите на Playwright или Puppeteer через Crawlee's PlaywrightCrawler. Но помните: headless-браузер потребляет в 10–20 раз больше ресурсов — один инстанс Chrome требует около 150–300 МБ RAM. Для контейнеризации используйте Docker с образами на базе Debian, а для горизонтального масштабирования — Kubernetes или аналогичные оркестраторы. Типичная конфигурация: 4–8 браузеров на ядро CPU, 512 МБ RAM на инстанс.

Этика и правовые аспекты

Прежде чем начать скрейпинг, учитывайте правовые рамки. В США сбор публичных данных обычно не нарушает Computer Fraud and Abuse Act (CFAA) после прецедента hiQ Labs v. LinkedIn (2022), но Terms of Service конкретного сайта могут запрещать автоматизированный доступ. В ЕС на сбор персональных данных распространяется GDPR, даже если данные получены из публичного источника.

Практические принципы:

  • Собирайте только публичные данные — не пытайтесь обходить аутентификацию или paywall
  • Уважайте robots.txt — это не просто рекомендация, а сигнал добросовестности
  • Соблюдайте рейт-лимиты — не отправляйте больше запросов, чем необходимо
  • Предпочитайте официальные API, когда они доступны
  • Не храните персональные данные дольше, чем необходимо для вашей задачи

Подробнее о вариантах использования прокси — на странице веб-скрейпинга и SERP-трекинга. Тарифы ProxyHat — на странице цен. Документация по подключению — на docs.proxyhat.com.

Ключевые выводы

  • Заголовки решают половину проблемы — got-scraping с header-generator создаёт связные наборы заголовков, неотличимые от реальных браузеров
  • Резидентные прокси закрывают вторую половину — даже с идеальными заголовками дата-центр IP выдаёт автоматизацию по ASN
  • Ротация сессий — ключ к масштабированию — уникальная сессия на запрос через -session-xxx в имени пользователя ProxyHat
  • Retry hooks — не опция, а необходимость — перехват 403/429 с автоматической сменой прокси повышает success rate до 95%+
  • Ограничивайте конкурентность — p-limit с 10–20 одновременными запросами балансирует скорость и блокировки
  • Масштабируйте через Crawlee — при росте очереди URL переход на CheerioCrawler добавляет очередь, дедупликацию и управление сессиями

Готовы начать?

Доступ к более чем 50 млн резидентных IP в 148+ странах с AI-фильтрацией.

Смотреть ценыРезидентные прокси
← Вернуться в Блог