36 lines
1.6 KiB
Python
36 lines
1.6 KiB
Python
"""Avito-specific exceptions для anti-bot detection."""
|
||
|
||
|
||
class AvitoError(Exception):
|
||
"""Base для всех Avito scraper exceptions."""
|
||
|
||
|
||
class AvitoBlockedError(AvitoError):
|
||
"""HTTP 403 от Avito — IP-level block detected."""
|
||
|
||
|
||
class AvitoRateLimitedError(AvitoError):
|
||
"""HTTP 429 от Avito — rate limit triggered."""
|
||
|
||
|
||
class AvitoListingGoneError(AvitoError):
|
||
"""Объявление удалено / вернуло 404 (страница «Ошибка 404» вместо item-view).
|
||
|
||
Отдельный сигнал от AvitoBlockedError/AvitoRateLimitedError: 404 — НЕ анти-бот
|
||
deflect, а мёртвый листинг (его незачем ротировать/ретраить). Наследует общий
|
||
AvitoError, но НЕ AvitoBlockedError — чтобы backfill-ловушка
|
||
`except (AvitoBlockedError, AvitoRateLimitedError)` его НЕ перехватывала и не крутила
|
||
consecutive-block breaker на мёртвых координатных дырах (run 458: 5 dead → abort).
|
||
"""
|
||
|
||
|
||
class AvitoContentBlockedError(AvitoBlockedError):
|
||
"""HTTP 200 от Avito, но 0 карточек на первой странице — content-block / captcha.
|
||
|
||
Наследует AvitoBlockedError, чтобы существующие except-блоки на AvitoBlockedError
|
||
продолжали ловить этот сигнал (mark_banned, pipeline abort и т.д.).
|
||
"""
|
||
|
||
|
||
class AvitoParseError(AvitoError):
|
||
"""Cannot parse Avito HTML structure (selector changes)."""
|