образовательный проект · не нарушает ToS при правильном использовании

Avito Guardian

Три инструмента в одном: разбор защиты Avito, умное сравнение товаров и поиск с фильтрами. Форма входа на Avito — прямо под этим текстом. AI-помощник — в шапке. Не дайте продавцам продать вам в 2× более слабый товар за в 2× большую цену.

Вход на Avito

Stealth-backend не запущен · демо-режим
Общая оценка защиты
100
из 100
Крепость
Avito — один из самых защищённых классифайдов в RU-сегменте.2 критических и 4 высоких уровней защиты.

Зоны защиты по категориям

Поведенческий43 баллов
Сетевой36 баллов
Структурный14 баллов
Юридический14 баллов
CAPTCHA11 баллов
Браузерный8 баллов

Что это значит на практике

Avito защищён от примитивного парсинга requests/BeautifulSoup почти на 100%. Любой новичок, запускающий скрипт со своего VPS, получит бан IP в течение нескольких минут. Однако полноценный парсинг возможен при комбинировании трёх факторов: (1) имперсонация TLS-фингерпринта браузера, (2) реалистичная эмуляция поведения мыши и таймингов, (3) резидентные российские прокси. Стоимость инфраструктуры для серьёзного парсинга — от 50$ в месяц за прокси + 5-15$ за CAPTCHA-сервис. Ниже — детальный разбор каждого слоя защиты.

Слои защиты — детальный разбор

Cloudflare Bot Management

Сетевой

Критическая

Avito стоит за Cloudflare и использует Bot Management с JA3/JA4-фингерпринтами TLS-клиентов.

Подробности и обход

Cloudflare анализирует не только IP и User-Agent, но и низкоуровневые параметры TLS-handshake (набор шифров, расширения, порядок hello). Классические httpx/aiohttp запросы из дата-центров помечаются как бот в течение 1-2 запросов. Дополнительно работает HTTP/2 fingerprinting и аномалии Accept-Language/Sec-CH-UA.

Признаки работы
  • Заголовок 'cf-ray' в ответах avito.ru
  • Срабатывание Cloudflare challenge 403 на девственных IP дата-центров
  • Появление cf_clearance cookie после прохождения JS-challenge
Сложность обхода4/5
  • curl_cffi / tls-client с имперсонацией Chrome/Firefox (точная копия JA3)
  • Playwright + playwright-stealth с реальным Chrome
  • Резидентные мобильные/домашние прокси (не дата-центр)

Avito Shield (собственный anti-bot)

Поведенческий

Критическая

Поверх Cloudflare работает собственная система, строящая поведенческий профиль сессии: мышь, скролл, паузы, клики.

Подробности и обход

Avito Shield собирает телеметрию со страницы через скрипт 'index-nodejs-avito-frontend' и отправляет её в /user/registration/events. Анализируется траектория мыши, скорость скролла, интервалы между кликами, наличие devtools, размер окна, плагины. Сессии с 'идеальным' поведением (без мыши, мгновенные клики) блокируются.

Признаки работы
  • POST /user/registration/events в network-вкладке при скролле
  • Блокировка аккаунтов, которые открывают >50 карточек без скролла
  • Поля 'device-id' и 'session-uuid' в cookie и localStorage
Сложность обхода5/5
  • Реалистичная эмуляция мыши через bezier-curves (ghost-cursor)
  • Случайные паузы 3-15 сек между действиями
  • Ре-использование профиля браузера с cookie/session
  • Бережный rate-limit: не более 1 карточки / 5-10 сек

CAPTCHA (Yandex SmartCaptcha + custom slider)

CAPTCHA

Высокая

После подозрительной активности показывается Yandex SmartCaptcha или кастомный slider-puzzle.

Подробности и обход

Avito использует два типа CAPTCHA. Первая — Yandex SmartCaptcha (для неавторизованных и для контактов продавца). Вторая — собственный slider-puzzle 'собери картинку' на этапе регистрации или частых запросах телефона. Оба типа устойчивы к простой OCR.

Признаки работы
  • Появление iframe smartcaptcha.yandexcloud.com на /sms/630311
  • Эндпоинт /captcha/verify для slider-puzzle
  • Блокировка просмотра телефона без решения капчи
Сложность обхода3/5
  • 2Captcha / Anti-Captcha / Capsolver — Yandex SmartCaptcha решается за 5-15 коп.
  • Для slider — компьютерное зрение + ML для позиционирования пазла
  • Поддержка cookie после прохождения 1 капчи (валиден ~30 мин)

Rate-limiting + progressive backoff

Сетевой

Высокая

Жёсткие лимиты на IP/session: >30 карточек/мин помечаются, >100 — временный бан на 1-24 часа.

Подробности и обход

Avito применяет многоуровневый rate-limit: на IP, на сессию (cookie device-id), на аккаунт. При превышении сначала замедляются ответы, потом возвращается 429, затем 403 с капчей. После нескольких нарушений — бан на 1-24 часа, при рецидиве — перманентный бан IP-сегмента.

Признаки работы
  • Заголовок 'X-RateLimit-Remaining' в ответах
  • 429 Too Many Requests после ~100 запросов за минуту
  • Бан IP на 1 час после 3 капч за 5 минут
Сложность обхода3/5
  • Парсинг с self-pace: 1 запрос / 5-10 сек (~360-720 карточек в час)
  • Ротация резидентных прокси (Smartproxy, Brightdata)
  • Приоритет парсинга списка по sitemap перед парсингом карточек

Dynamic rendering + обфускация классов

Структурный

Средняя

Часть контента рендерится через React на клиенте, CSS-классы обфусцированы и меняются при каждом деплое.

Подробности и обход

Avito рендерит начальный HTML на сервере (для SEO), но интерактивные блоки (контакты, отзыв-счётчик, параметры в фильтрах) догружаются через JSON-API. CSS-классы выглядят как 'iva-item-title-2yVW9' и переименовываются каждые 1-2 недели. Парсеры, привязанные к классам, ломаются постоянно.

Признаки работы
  • JSON в window.__INITIAL_STATE__ на карточке товара
  • Смена имён классов каждые 1-2 недели (видно по git-history парсеров)
  • XHR к /items/v1/items/{id} для подгрузки параметров
Сложность обхода2/5
  • Парсить JSON из script#__NEXT_DATA__ или window.__INITIAL_STATE__
  • Использовать data-атрибуты (data-marker='item-title') — они стабильны
  • Авто-регенерация селекторов при деплое через ML-классификатор

Login wall для контактов продавца

Браузерный

Средняя

Телефон продавца и чат доступны только после авторизации; для регистрации нужен телефон с SMS.

Подробности и обход

Телефон продавца скрыт за кнопкой 'Показать телефон'. При попытке открыть ссылку на телефон без сессии возвращается редирект на /login/. Для регистрации требуется российский или казахстанский номер с подтверждением SMS. Это блокирует массовый сбор контактов.

Признаки работы
  • Редирект /phone/... на /login/ для неавторизованных
  • SMS-верификация на +7 номерах
  • Лимит '5 звонков/показов телефона в час' даже для авторизованных
Сложность обхода3/5
  • Покупка пулов виртуальных номеров (sms-activate, 5sim)
  • Один аккаунт на 50-100 показов телефона, затем ротация
  • Допустимо для исследовательских задач: использовать 1 аккаунт для аналитики без массового сбора

Геоблокировка для зарубежных IP

Сетевой

Средняя

Часть эндпоинтов Avito доступна только с российских IP; с зарубежных IP — пониженный функционал или 403.

Подробности и обход

Avito географически ограничивает доступ к контактам, иногда — к поиску. Запросы с зарубежных IP к /api/1/items/... возвращают 403 или показывают урезанную страницу. Это сделано для соответствия GDPR и снижения нагрузки от зарубежных ботов.

Признаки работы
  • 403 на /items/v1/items/{id} при IP из EU/US
  • Cookie 'geoId' форсирует регион, но требует RU IP
  • Снижение количества результатов в выдаче с зарубежных IP
Сложность обхода2/5
  • Российские резидентные прокси (proxy6, proxy-seller)
  • SOCKS5 + цепочка из 2 прокси для стабильности
  • VPS в РФ (Selectel, Timeweb) — дешёвый вариант для личного парсинга

Валидация заголовков и Sec-CH-UA

Браузерный

Низкая

Проверяются User-Agent, Accept-Language, Sec-CH-UA, Referer. Несоответствия помечают как бот.

Подробности и обход

Avito валидирует связку User-Agent + Sec-CH-UA + Accept-Language + Referer. Например, UA Chrome на Windows, но пустой Sec-CH-UA — мгновенный флаг. Referer от Google — доверие выше, чем прямой заход. Пустой или лишний заголовок — флаг.

Признаки работы
  • Разный набор заголовков в Chrome devtools vs curl
  • Бан при 'Accept-Language: en-US' (несоответствие русскому контенту)
  • Referer с 3rd-party доменов помечается как подозрительный
Сложность обхода1/5
  • Копирование полного набора заголовков из devtools реального браузера
  • Парные Sec-CH-UA к конкретной версии Chrome
  • Referer = https://www.avito.ru/ для всех запросов карточек

Fingerprinting устройства (canvas, WebGL, fonts)

Поведенческий

Высокая

Скрипт FingerprintJS собирает 30+ параметров: canvas hash, WebGL renderer, шрифты, аудио-контекст.

Подробности и обход

Avito использует FingerprintJS Pro (или аналог) для построения уникального отпечатка устройства. Анализируются canvas rendering, WebGL vendor/renderer, список шрифтов, AudioContext, шрифты, плагины, размер экрана в CSS-пикселях. Одинаково во всех вкладках браузера. Это позволяет связать сессии даже после очистки cookie.

Признаки работы
  • Скрипт fpjs.js загружается на каждой странице
  • Заголовок 'X-Fingerprint' в запросах к API
  • Бан нового аккаунта при переиспользовании того же canvas-hash
Сложность обхода5/5
  • Canvas-спуфинг через расширения (CanvasBlocker, Trace)
  • Playwright с --disable-features=CanvasRendering и патчами canvas
  • Отдельный профиль браузера/профиль Chromium на каждую сессию
  • Multi-account containers Firefox для изоляции fingerprints

Юридическая защита (ToS + precedent)

Юридический

Высокая

Парсинг нарушает ToS Avito; есть прецеденты судебных исков против агрегаторов и скраперов.

Подробности и обход

П. 4.5 Пользовательского соглашения Avito прямо запрещает автоматизированный сбор данных. Avito подавал иски против нескольких агрегаторов (например, дело vs одного из авто-агрегаторов в 2020-2022). Для личного нефинансируемого парсинга риск минимален, но коммерческое использование собранных данных — высокий юридический риск.

Признаки работы
  • П. 4.5 Пользовательского соглашения: запрет на 'автоматизированные программы'
  • Дело А40-128521/2021 — иск Avito к агрегатору автомобилей
  • Бан аккаунтов с формулировкой 'нарушение п. 4.5'
Сложность обхода4/5
  • Только личное использование, без перепродажи данных
  • Соблюдение robots.txt и не превышать 'fair use'
  • Использование официального Avito API (если доступен для вашей задачи)
  • Юридическая консультация перед запуском коммерческого продукта

API gateway с подписью запросов

Структурный

Средняя

Часть данных доступна только через подписанные запросы к Avito API (HMAC + nonce + timestamp).

Подробности и обход

Avito API gateway требует подпись запроса HMAC-SHA256 с уникальным nonce и timestamp. Подпись генерируется в JS-бандле с обфусцированным ключом, который меняется при каждом деплое. Прямые запросы к API без подписи возвращают 403.

Признаки работы
  • Заголовки 'X-Signature', 'X-Nonce', 'X-Timestamp' в /api/1/... запросах
  • Динамический бандл avito-front.bundle.js с обфусцированной подписью
  • 403 на прямой вызов /api/1/items/search без подписи
Сложность обхода4/5
  • Извлечение ключа подписи из бандла через sourcemap или реверс JS
  • Перехват подписи через CDP в Playwright (подождать, что страница сделает запрос сама)
  • Использование публичных REST-эндпоинтов вместо подписанных GraphQL

Рекомендации для парсера

1

Не парсь в лоб

Прямой requests/httpx к avito.ru = 99% бан за 10-50 запросов. Минимум — curl_cffi с имперсонацией Chrome и резидентные RU прокси.

2

Один аккаунт = один профиль браузера

Не переиспользуй cookie/device-fingerprint между аккаунтами. Avito связывает сессии по canvas+WebGL fingerprint.

3

Скорость ≤ 1 карточка / 5 сек

Превышение = 429 → капча → бан. Лучше 360 карточек/час медленно, чем 5000 быстро и бан.

4

Сначала sitemap, потом карточки

Парс sitemap.xml и категорийных страниц дешевле, чем полный скан. Поиск по category + фильтр + пагинация = оптимум.

5

Для сравнения товаров — есть лицензионный путь

Avito выпускает партнерский API (Avito API). Если задача — сравнение цен, а не массовый сбор, попробуйте официальный доступ.

6

Кэшируй результат

Каждый парсинг — риск бана. Сохраняйте спаршенные карточки в БД, обновляйте раз в 1-7 дней, а не каждый раз при запросе пользователя.

Образец кода для безопасного парсинга

Только для образовательных целей. Перед использованием обязательно проверьте пользовательское соглашение Avito (п. 4.5 запрещает автоматизированный сбор) и действующее законодательство. Для коммерческих продуктов используйте официальный Avito API.

avito-stealth-parser.ts
// Пример безопасного парсинга Avito с Playwright + stealth
// ⚠️ Только для образовательных целей. Проверьте ToS перед использованием.

import { chromium } from 'playwright';
import { stealth } from 'playwright-extra';
import GhostCursor from 'ghost-cursor';

const browser = await chromium.launch({
  headless: false,
  args: ['--disable-blink-features=AutomationControlled'],
});

const context = await browser.newContext({
  userAgent:
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' +
    '(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
  viewport: { width: 1920, height: 1080 },
  locale: 'ru-RU',
  timezoneId: 'Europe/Moscow',
  geolocation: { latitude: 55.7558, longitude: 37.6173 },
});

await stealth(context);

const page = await context.newPage();
const cursor = GhostCursor.createCursor(page);

// Реалистичный заход через Google (повышает доверие)
await page.goto('https://www.google.com/search?q=site:avito.ru+ноутбук');
await page.waitForTimeout(2000 + Math.random() * 3000);

// Имитация мыши перед кликом
await cursor.move('a[href*="avito.ru"]', { waitForClick: 500 });
await cursor.click('a[href*="avito.ru"]');

// На карточке товара — пауза, скролл, сбор данных
await page.waitForSelector('[data-marker="item-title"]');
await page.waitForTimeout(3000 + Math.random() * 5000);
await page.mouse.wheel(0, 500);
await page.waitForTimeout(2000);

const data = await page.evaluate(() => {
  const title =
    document.querySelector('[data-marker="item-title"]')?.textContent?.trim() ?? '';
  const price =
    document.querySelector('[data-marker="item-price"]')
      ?.getAttribute('content') ?? '';
  const params = Array.from(
    document.querySelectorAll('[data-marker="item-params"] li'),
  ).map((li) => {
    const k = li.querySelector('.params-paramsList_1pekG')?.textContent?.trim() ?? '';
    const v = li.querySelector('.params-paramsValue_2vnyX')?.textContent?.trim() ?? '';
    return { key: k, value: v };
  });
  return { title, price, params };
});

console.log(data);

// ЗАКРЫТЬ сессию, не оставлять пустую
await context.close();
await browser.close();