Как обойти ошибку 403 при парсинге Avito и ВКонтакте

Поиск услуг гадалок на популярных площадках Авито и ВКонтакте часто сопровождается автоматическим сбором объявлений. Однако обе платформы активно защищаются от скрейпинга: при слишком частых или подозрительных запросах возвращают HTTP 403 Forbidden или вовсе блокируют IP‑адрес. Ниже – подробное руководство, как минимизировать риски и получить нужные данные без блокировок.

Почему возникает ошибка 403?

  • Сервер определил запрос как автоматизированный (отсутствие типичных заголовков браузера, подозрительный User‑Agent).
  • IP‑адрес превысил лимит запросов за короткий период (rate‑limiting).
  • Отсутствуют или некорректны куки, необходимые для поддержки сессии.
  • Сработала защита от ботов (CAPTCHA, JS‑челлендж) и сервер вернул 403 вместо перенаправления на страницу проверки.
  • IP‑адрес уже находится в чёрном списке из‑за предыдущих нарушений.

Подготовка окружения

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

  1. Создать отдельный виртуальный окружение Python (venv или conda).
  2. Подготовить список прокси (резидентные или датацентровые) с поддержкой HTTP/HTTPS и возможностью ротации.

Настройка HTTP‑запросов

User‑Agent и заголовки браузера

Серверы проверяют, насколько запрос похож на обычный браузер. Минимальный набор заголовков:

  • User‑Agent – актуальная строка одного из популярных браузеров (Chrome, Firefox, Safari). Лучше менять её каждые N запросов.
  • Accept-Language – ru-RU,ru;q=0.9,en-US;q=0.8
  • Referer – указывать страницу, с которой якобы пришёл пользователь (например, главную страницу Авито или VK).
  • Connection – keep-alive
  • Upgrade-Insecure-Requests – 1

Пример формирования заголовков в Python:

Пример 1 – статический набор

import requests
from fake_useragent import UserAgent

ua = UserAgent
headers = {
 "User-Agent": ua.random, "Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8",
 "Referer": "https://www.avito.ru/",
 "Connection": "keep-alive",
 "Upgrade-Insecure-Requests": "1"
}
response = requests.get("https://www.avito.ru/", headers=headers, timeout=10)

Пример 2 – ротация User‑Agent каждые 5 запросов

import itertools
from fake_useragent import UserAgent

ua = UserAgent
agents = [ua.random for _ in range(20)]
agent_cycle = itertools.cycle(agents)

def get_headers:
 return {
 "User-Agent": next(agent_cycle), "Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8",
 "Referer": "https://www.avito.ru/",
 "Connection": "keep-alive",
 "Upgrade-Insecure-Requests": "1"
 }

Куки и сессия

Многие площадки используют куки для отслеживания сессии. Чтобы не выглядеть как новый пользователь каждый запрос, следует:

  • Создавать объект requests.Session и повторно использовать его для серии запросов.
  • Сохранять полученные куки после первого успешного запроса и передавать их дальше.
  • При необходимости обновлять куки (например, после получения CAPTCHA‑страницы).

Пример:

session = requests.Session
session.headers.update(get_headers)

r = session.get("https://www.avito.ru/", timeout=10)


r2 = session.get("https://www.avito.ru/rossiya?query=%D0%B3%D0%B0%D0%B4%D0%B0%D0%BB%D0%BA%D0%B0", timeout=10)

Ротация прокси

Даже с правильными заголовками частые запросы с одного IP быстро приводят к блокировке. Решение – использовать пул прокси и менять их после каждого N запросов или при получении 403/429.

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

  • Резидентные IP – менее вероятно попасть в чёрный список, но дороже.
  • Датацентровые – дешевле, но чаще блокируются; подходят для тестов.
  • Поддержка SOCKS5/HTTP – выбирайте в зависимости от библиотеки.
  • Геолокация – лучше выбирать IP из той же страны, что и целевая аудитория (Россия).

Простейший ротатор на Python

import random
import requests

PROXY_LIST = [
 "http://user:pass@proxy1.example.com:3128",
 "http://user:pass@proxy2.example.com:3128",
 "http://user:pass@proxy3.example.com:3128"
]

def get_random_proxy:
 return {"http": random.choice(PROXY_LIST), "https": random.choice(PROXY_LIST)}

def fetch(url):
 proxies = get_random_proxy
 try:
 r = requests.get(url, headers=get_headers, proxies=proxies, timeout=10)
 r.raise_for_status
 return r.text
 except requests.exceptions.RequestException as e:
 print(f"Ошибка через {proxies}: {e}")
 return None

При получении 403 или 429 можно сразу пометить текущий прокси как «плохой» и исключить его из дальнейшего использования на определённое время.

Ограничение скорости (rate limiting)

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

  • Добавлять случайную задержку между запросами: time.sleep(random.uniform(1, 3)).
  • Использовать экспоненциальное back‑off при получении ошибок.
  • Ограничивать количество одновременных потоков (например, не более 5‑10 параллельных запросов).

Работа с JavaScript‑защитой

Если после всех мер вы всё ещё получаете 403, вероятно, сайт проверяет выполнение JS (например, через Cloudflare или собственную капчу). В таких случаях:

  1. Перейти на headless‑браузер: Selenium с Chrome/Firefox в headless‑режиме или Playwright.
  2. Настроить браузер так, чтобы он отправлял те же заголовки, что и обычный пользователь (User‑Agent, viewport, язык).
  3. Включить обработку куки и локального хранилища.
  4. При необходимости решать капчу manually или через сервисы вроде 2captcha, Anti-Captcha.

Пример с Playwright (асинхронный):

from playwright.async_api import async_playwright
import asyncio

async def avito_search:
 async with async_playwright as p:
 browser = await p.chromium.launch(headless=True)
 context = await browser.new_context( locale="ru-RU"
 )
 page = await context.new_page
 await page.goto("https://www.avito.ru/", wait_until="networkidle")
 # Ввод поискового запроса
 await page.fill('input[name="query"]', "гадалка")
 await page.click('button[type="submit"]')
 await page.wait_for_timeout(2000) # дать время загрузиться # Здесь можно парсить html через BeautifulSoup
 await browser.close
asyncio.run(avito_search)

Особенности работы с ВКонтакте

ВКонтакте предоставляет официальное API, которое значительно снижает риск блокировки. Однако если вам нужен сбор публичных постов или объявлений без использования API, применяйте те же принципы, что и для Авито:

  • Используйте официальные методы wall.get, groups.getMembers с параметром access_token (полученным через OAuth).
  • Следите за лимитами API: обычно 3 запроса в секунду на один токен.
  • При превышении лимита получите ошибку 6 (Too many requests) – делайте паузу и повторяйте запрос.
  • Лучшие практики и чек‑лист

    • ✅ Всегда используйте сессию (requests.Session) для сохранения куки.
    • ✅ Rotate User‑Agent каждые 5‑10 запросов.
    • ✅ Используйте пул прокси и меняйте их при получении 403/429.
    • ✅ Добавляйте случайную задержку 1‑3 секунды между запросами.
    • ✅ При появлении CAPTCHA или JS‑челленджа переключайтесь на headless‑браузер.
    • ✅ Логируйте статус коды и задержки – это поможет быстро обнаружить проблемные IP.
    • ✅ Уважайте robots.txt и условия использования площадки; если сбор запрещён, ищите официальные API.
    • ✅ Храните токены и учётные данные в безопасном месте (переменные окружения, vault).

    Избежать блокировок и ошибки 403 при поиске гадалок на Авито и ВК – задача полностью решаемая при соблюдении комплекса мер: правильные заголовки, ротация прокси и User‑Agent, ограничение скорости, работа с сессией и куки, а при необходимости – переход на headless‑браузеры. Следуя предложенному чек‑листу и используя приведённые примеры кода, вы сможете собирать нужные объявления стабильно и без лишних простоев.

    Удачного парсинга и помните: уважительное отношение к ресурсам площадки не только снижает риск блокировки, но и способствует долгосрочной работе вашего проекта.