_parse_html=[] при HTTP 200 на page==1 (анкер EKB всегда имеет объявления) ⇒ content-block (captcha/challenge) → logger.error + raise AvitoContentBlockedError (subtype AvitoBlockedError — existing except ловит). page>1 с 0 карточек → легитимный end-of-pagination (graceful break, сохранено). 403/429-обработка не тронута. pytest -k avito 101 passed, ruff clean.
25 lines
843 B
Python
25 lines
843 B
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 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)."""
|