Блог Froxy | Новости, полезные статьи о использовании прокси

Заголовки Axios в скрапинге: кейсы и рекомендации

Written by Команда Froxy | 16.04.2026 7:00:00

Представим, что вы написали простой скрипт с использованием популярной JS-библиотеки Axios и отправили запрос к конкретной странице целевого сайта. Его сервер вернул вполне ожидаемый код 200, но вместо полноценного HTML-содержимого отдал абсолютно пустую веб-страницу, описание ошибки доступа или что-то без нужной вам смысловой нагрузки, например, без цен или без важных блоков. Знакомо? С такими проблемами сталкивается каждый второй разработчик парсеров.

С большой вероятностью вы не стали углубляться в HTTP-заголовки, и потому ваш парсер раскрыли при первом же подключении. Ниже постараемся помочь с настройкой дефолтных заголовков Axios при скрапинге.

Что за HTTP-заголовки и какую роль они играют в защите от ботов?

Технически, HTTP-заголовки — это служебные поля, которые заполняются и передаются вместе с телом запроса к веб-серверу или возвращаются вместе с его ответом. Внутри этих полей указываются важные метаданные о соединении, клиенте и контексте запроса. В частности, они позволяют синхронизировать такие детали, как язык, кодировку, текущее время, версию HTTP-протокола, поддерживаемые типы содержимого, методы сжатия и пр. Например, куки – это тоже один из HTTP-заголовков.

Набор актуальных на текущий момент заголовков постоянно меняется, здесь нет единого стандарта. Плюс допускается создание уникальных заголовков, обычно они начинаются с префикса «X-». Наиболее полный список заголовков проще изучить на Wikipedia или на портале для разработчиков MDN.

Примерно так это выглядит на практике (каждый заголовок передаёт свои параметры после двоеточия):

GET / HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.9,ru;q=0.8
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1

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

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

HTTP-заголовки можно смело отнести к цифровым отпечаткам. Но следует помнить, что эти два понятия не равны между собой – заголовки могут передать только небольшую часть того, что в реальности анализируют антибот-системы.

Минимальный набор метаданных в HTTP-заголовках для парсинга с Axios

Axios — это изоморфный HTTP-клиент для среды node.js и для реальных браузеров. В JavaScript-парсерах он подключается как любая другая npm-библиотека:

npm install axios

В коде:

import axios from 'axios';

Но его же можно задействовать и на уровне веб-страниц:

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

На чём хотелось бы акцентировать особое внимание: Axios позволяет устанавливать заголовки глобально – чтобы их можно было задать один раз. Тогда все последующие запросы будут передавать в заголовках установленные ранее значения.

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

Итак, как выглядит минимальный «джентльменский» набор общих заголовков для Axios при парсинге:

headers: {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
    'Accept-Language': 'en-US,en;q=0.9,en-US;q=0.8,en;q=0.7',
    'Accept-Encoding': 'gzip, deflate, br, zstd',
    'Referer': 'https://www.google.com/',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'cross-site',
    'Sec-Fetch-User': '?1',
    'Upgrade-Insecure-Requests': '1'
}

Теперь вызываем пояснительную бригаду – какой заголовок и за что отвечает:

  • User-Agent – это строка идентификации браузера, одновременно указывает на операционную систему устройства и версию движка для рендеринга страниц. Это самый очевидный фильтр ботов, который применяют одним из первых. Например, по дефолту Axios в качестве юзер-агента передаёт версию библиотеки (axios/1.13.5), что позволяет однозначно её идентифицировать со стороны сервера.
  • Accept – заголовок, который определяет какие типы контента клиент готов принять (html, json, xml, image и т.п.). Боты часто отправляют либо слишком общий, либо слишком узкий набор атрибутов.
  • Accept-Language – описывает предпочитаемые языки пользователя. В парсерах, в том числе на базе Axios, используют типовые заголовки для английского языка «en-US/en;q=0.9» или не используют поле вообще.
  • Accept-Encoding – сообщает серверу какие методы сжатия поддерживает клиент. Практически все современные браузеры отправляют связку из br и gzip. Но в дефолтных заголовках Axios параметр отсутствует.
  • Referer – сообщает серверу с какой страницы пришёл клиент. Этот параметр сложно назвать обязательным, но он вполне срабатывает в совокупности факторов. Боты часто делают прямые запросы без реферера или с неправильным (подозрительным) источником, например, что-то вида «api.example.com».
  • Sec-Fetch-* – это семейство заголовков, которые отвечают за защиту от CSRF/XSRF-атак. Если этих заголовков нет или значения в них неверные, бота можно выявить со 100% вероятностью.
  • Upgrade-Insecure-Requests – заголовок, который просит сервер перейти на безопасный протокол HTTPS. Его почти всегда отправляют все современные браузеры. В ботах параметр обычно отсутствует.
  • Cookie / Set-Cookie – многие сайты сохраняют данные в куки, чтобы поддерживать активную сессию и авторизацию пользователя. Здесь же могут быть записаны CSRF-токены. Боты в большинстве случаев игнорируют куки или отправляют старые/пустые значения.
  • Priority / Purpose – это новые заголовки, которые активно используются в браузере Google Chrome, они нужны для приоритизации запросов. Боты такие заголовки не отправляют, хотя сами могут представляются юзер-агентом Хрома, что сразу же наводит на подозрение в обмане.
  • Последовательность заголовков – сервер может анализировать не столько сами заголовки или их наполнение, сколько порядок их следования. Браузеры всегда отдают свой отпечаток с одним и тем же алгоритмом ранжирования. А парсеры, написанные программистами, почти всегда нарушают этот порядок.

Это только базовый минимум. Конкретный сайт или веб-сервер, может анализировать гораздо больше заголовков, отдаваемых клиентом. Основная цель парсера – сделать так, чтобы сервер не мог отличить его HTTP-заголовки от заголовков реального браузера.

Позаботьтесь о прокси заранее

Чистые IP для доступа к ценным данным со всего мира.

Попробовать триал $1.99, 100Mb

Заголовки браузера: когда их нужно имитировать, а когда нет

Всё будет зависеть от совокупности факторов: тип сайта (многие крупные платформы представляют собой сложные web-приложения, которые не работают без JavaScript, соответственно, для доступа к ним вам обязательно потребуется headless-браузер или антидетект) и уровень его защиты (насколько глубоко сайт изучает ваши цифровые отпечатки).

Выяснить необходимость имитирования заголовков в Axios при скрапинге можно только опытным путём. Открывайте сайт, изучайте его архитектуру, пробуйте отправлять запросы без заголовков, с минимальным набором, с использованием дополнительных. И так до тех пор, пока парсер не заработает.

Без правильного набора заголовков бан будет практически гарантирован, если на сайте применяются продвинутые системы защиты: Cloudflare, Akamai, PerimeterX, DataDome, Kasada и т.п. Их можно выявить по набору подключённых скриптов и специальных атрибутов в коде.

Обратите внимание, в некоторых случаях может не помочь даже полная замена Axios на headless-браузеры, так как последние в дефолтной настройке тоже имеют особые отпечатки и требуют тонкой работы для их скрытия.

Файлы cookie и сессии

Cookie — это особые текстовые данные, которые веб-сервер отправляет браузеру вместе с заголовком Set-Cookie. Браузер их запоминает и автоматически возвращает обратно при запросах к одному и тому же сайту, но уже в заголовке Cookie. Именно такой подход позволяет удерживать и управлять сессиями и авторизацией пользователей.

Сессионные куки хранят специальный идентификатор сессии (session ID), сервер в свою очередь связывает этот идентификатор с отдельным набором данных: логин, статус авторизации, корзина и т.п. Без правильных кук парсер выглядит как неавторизованный гость, соответственно, либо получает ошибку доступа, либо пустые/обезличенные данные.

Многие веб-файрволлы (WAF-системы) используют механизм кук для отсева ботов. Например, они могут даже записывать свои токены и куки, которые работают по аналогии с уникальным электронным пропуском: __cf_bm, cf_clearance у Cloudflare; _px, _px3 у PerimeterX и т.д.

Про этичный обход защиты WAF-систем.

В парсинге через Axios без браузера куки по умолчанию не сохраняются и не отправляются. Поэтому ими нужно управлять вручную:

  • Сохранять все Set-Cookie из ответов.
  • Формировать строку Cookie с полученными значениями для новых запросов: name1=value1; name2=value2…
  • Использовать готовые библиотеки для автоматического управления, такие как axios-cookiejar-support и tough-cookie.

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

Токены CSRF и двухэтапные запросы

CSRF-токен (Cross-Site Request Forgery token) — это уникальный идентификатор, генерируемый сервером для каждой сессии, формы или запроса. Цель такого токена — убедиться, что входящий запрос (POST/PUT/DELETE) пришёл от реального пользователя, а не от вредоносного сайта через браузер жертвы. Ведь технически автоматизированный скрипт или злоумышленник может скопировать куки пользователя и отправить запрос от его имени. Перехват легко можно осуществить при посещении пользователем подконтрольного сайта.

Если речь идёт о парсере на Axios, то CSRF-токен будет блокировать механизмы отправки данных через методы POST, PUT и DELETE, так как они зачастую связаны с авторизацией. Чтобы пройти такую защиту, нужно позаботиться не только о куках, но и о чтении токенов в HTML-коде (обычно на уровне специальных атрибутов), а также о работе с отдельными заголовками для CSRF. Значения токенов должны актуализироваться при каждом обращении к серверу.

Обратите внимание! Боты на axios/requests часто не могут считать токены, если они генерируются динамически – через JS, уже после отдачи основного HTML-кода страницы.

Двухэтапные (multi-step) запросы — это классический паттерн для обхода:

  1. С помощью GET-запроса парсер получает CSRF-токен (в заголовке или в HTML). При необходимости устанавливает/обновляет куки.
  2. Токен извлекается и используется уже в запросе с POST, PUT или DELETE.

Практические примеры для скриптов парсинга с Axios

Ниже типовые ситуации по работе с общими и кастомными заголовками в Axios при парсинге.

1. Базовое использование с глобальными заголовками

Глобальная установка заголовков предполагает то, что параметры достаточно установить один раз. Они в свою очередь заменят дефолтные значения и будут использоваться при всех последующих запросах в скрипте.

import axios from 'axios';

axios.defaults.headers.common = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept-Language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
    'Accept-Encoding': 'gzip, deflate, br, zstd',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1'
};

axios.get('https://example.com').then(r => console.log(res.data));

Такой подход удобно применять при массовом парсинге страниц одного сайта – там, где требуется единообразный цифровой отпечаток.

Обратите внимание! Дефолтные значения могут перезаписываться заголовками, заданными в конкретном запросе.

2. Заголовки под конкретный запрос

Это самый частый и гибкий способ точечной донастройки Axios при скрапинге.

axios.get('https://shop.com/search?q=iphone', {
    headers: {
        'Referer': 'https://www.google.com/search?q=купить+iphone', // имитация перехода из поиска
        'Sec-Fetch-Site': 'cross-site', // пришёл с другого домена
        'Sec-Fetch-Mode': 'navigate', // полноценная навигация
        'Sec-Fetch-Dest': 'document', // цель — HTML-документ
        'Sec-Fetch-User': '?1', // инициировано пользователем (клик)
        'Priority': 'u=0, i' // новый приоритетный заголовок Chrome
    }
});

3. Перехват запросов

Рассмотрим перехват на примере автоматического добавления CSRF-токена.

axios.interceptors.request.use(config => {
    // перед каждым запросом проверяем, есть ли свежий CSRF-токен
    const token = localStorage.getItem('csrf_token') ||
        // или можно брать из глобальной переменной / Map по домену
        globalCsrfTokens?.[new URL(config.url).origin];

    if (token && ['post', 'put', 'delete', 'patch'].includes(config.method)) {
        config.headers['X-CSRF-Token'] = token; // самый популярный заголовок, но он может быть видоизменён на конкретном сайте
        // Альтернативы: 'X-XSRF-TOKEN', 'X-CSRFTOKEN', '_csrf' в теле и т.п.
    }

    return config;
}, err => Promise.reject(err));

Наиболее востребованным будет применение при работе с формами, добавлении товара в корзину, настройке фильтров с POST и пр.

4. Авторизация + полноценное управление куками

Для автоматизации обработки кук подключаем дополнительные библиотеки.

import { wrapper } from 'axios-cookiejar-support';
import { CookieJar } from 'tough-cookie';

const jar = new CookieJar();
const client = wrapper(axios.create({
    jar,
    withCredentials: true, // обязательно для кросс-доменных кук
    headers: { 'User-Agent': '...' } // заголовки можно задать здесь – глобально
}));

// Логин, куки сохраняются автоматически
await client.post('https://site.com/auth/login', {
    email: 'user@example.com',
    password: 'strongpass123'
}, {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});

// Теперь все последующие запросы идут с куками
const profile = await client.get('https://site.com/account/profile');

Важно: если не задать истину для «withCredentials», то куки от поддоменов/другого пути не сохранятся.

5. Обработка ошибок + адаптивная смена заголовков при бане

axios.interceptors.response.use(
    response => response,
    async error => {
        const { response, config } = error;

        if (response?.status === 403 || response?.status === 429) {
            console.warn(`Блокировка (${response.status})! Меняем заголовки`);

            // Пример: ротация User-Agent + Client Hints
            config.headers['User-Agent'] = getNextUserAgent();
            config.headers['Sec-CH-UA'] = getRandomCHUA();

            // Ретрай с теми же параметрами (но новыми заголовками)
            return axios(config);
        }

        if (response?.status === 401) {
            // Для этого типа ошибки можно, например, задать логику авторизации под новым пользователем
        }

        return Promise.reject(error);
    }
);

6. Ротация заголовков для снижения риска блокировки отпечатков

const browsers = [
    { ua: 'Chrome 133 Win', chua: '"Google Chrome";v="133", ...' },
    { ua: 'Edge 133 Win', chua: '"Microsoft Edge";v="133", ...' },
    { ua: 'Firefox 124 Win', chua: '"Firefox";v="124", ...' }
];

function randomBrowser() {
    return browsers[Math.floor(Math.random() * browsers.length)];
}

axios.get('https://target.com', {
    headers: {
        'User-Agent': randomBrowser().ua,
        'Sec-CH-UA': randomBrowser().chua,
        'Sec-CH-UA-Platform': '"Windows"',
        'Sec-CH-UA-Mobile': '?0'
    }
});

7. Парсинг с Axios через прокси

axios.get('https://api.ipify.org?format=json', {
    proxy: {
        protocol: 'http',
        host: 'proxy.example.com',
        port: 3128,
        auth: {
            username: 'myuser123',
            password: 'strongpass456'
        }
    }
})
.then(res => console.log(res.data));

Когда Axios + заголовки не сработают

Axios (как и requests, httpx, curl, node-fetch или любой другой HTTP-клиент) — это не браузер. Даже если вы подмените все заголовки в точном соответствии с тем, как работает реальный браузер, библиотеку всё равно легко будет раскусить при выполнении JS-кода. Axios работает только с запросами и ответами по HTTP-протоколу. Всё, что подлежит выполнению внутри браузера, библиотека обрабатывать не умеет.

А многие продвинутые WAF-системы анализируют не только заголовки, но и то, как ведёт себя браузер при отрисовке страниц: какой набор шрифтов имеет, шевелит ли пользователь мышкой, нажимает ли на кнопки, попадают ли пиксели в те места, которые должны быть после реального рендеринга, и т.п.

Достаточно внедрения простого JS-токена, который сверяется с соответствующим заголовком, и Axios уже провалит проверку.

Заключение

Библиотека Axios весьма неплохо показывает себя при парсинге, но она имеет ограниченную сферу применения. Её использование будет оправдано в основном только при скрапинге сайтов без продвинутой защиты на основе веб-файрволлов (WAF).

Управление заголовками в Axios обеспечит максимальный уровень доверия. Основная цель здесь – по максимуму подражать работе реального браузера: отдавать естественные значения для юзер-агента, локали, типов содержимого и прочего, сохранять и использовать куки, а также CSRF-токены.

Ещё один немаловажный рубеж обороны любого парсера – качественные прокси. Axios умеет выполнять и получать запросы только через HTTP(S)-прокси. Для всех остальных протоколов потребуются сторонние библиотеки, такие как socks-proxy-agent.

Арендовать надёжные резидентные и мобильные прокси можно у нас. Froxy предлагает более 10 млн. IP с таргетингом до города и оператора связи. 200+ стран, ротация по времени или при каждом запросе.