Files
iaai-parser/README.md
qananasikq 9f703696d8 fix readme
2026-04-08 23:43:21 +03:00

5.8 KiB
Raw Blame History

IAAI Scraper

Парсер аукционных автомобилей с iaai.com. Ходит по листингу, собирает карточки машин, вытаскивает данные из DOM и перехваченных XHR-ответов, складывает всё в PostgreSQL. Работает через Playwright (headless Chromium), крутится в Docker.

Как устроен сайт и его защита

У IAAI стоит Imperva Incapsula — внешний WAF и anti-bot.

  • Anti-bot — headless Chromium без прокси часто режется.
  • Динамическая подгрузка — часть данных приходит через XHR (/Search, /VehicleDetail), часть есть в HTML.
  • Cookie consent — при первом заходе показывают баннер.

Поэтому в проекте используется Playwright, паузы между действиями и прокси.

Запуск

cp .env.example .env   # подправить под себя
docker compose up -d

Поднимутся 5 контейнеров: postgres, redis, api, worker, beat. API на http://localhost:8000.

Swagger-документация: http://localhost:8000/docs

API

Здоровье и статистика:

  • GET /health — статус сервиса и подключения к БД
  • GET /api/v1/stats — сколько машин/картинок в базе, топ брендов

Машины:

  • GET /api/v1/cars — список с пагинацией
  • GET /api/v1/cars/{id} — карточка с картинками
  • GET /api/v1/cars/by-origin/{origin_id} — поиск по IAAI stock number

Задачи:

  • POST /api/v1/tasks/sync-vehicle — скрапнуть одну машину по URL
  • POST /api/v1/tasks/sync-listing — запустить полный обход листинга
  • GET /api/v1/tasks/{task_id} — статус задачи
  • GET /api/v1/tasks — все задачи
  • GET /api/v1/sync-runs — история запусков

Пример — скрапнуть конкретную машину:

curl -X POST http://localhost:8000/api/v1/tasks/sync-vehicle 
  -H "Content-Type: application/json" \
  -d '{"vehicle_url": "https://www.iaai.com/VehicleDetail/45089484~US"}'

CLI

Для отладки без API/Celery:

python main.py init-db
python main.py collect-listing --make Toyota
python main.py sync-vehicle "https://www.iaai.com/VehicleDetail/45089484~US"
python main.py sync-listing --limit 10

Структура

iaai_scraper/
  scraper.py              — оркестратор: связывает browser → parser → storage
  cli.py                  — CLI-команды (init-db, sync-vehicle, sync-listing, ...)
  proxy_bridge.py         — HTTP→SOCKS5 мост (Chromium не умеет SOCKS5 с авторизацией)

  browser/
    factory.py            — создание браузера, stealth-инъекции, fingerprint
    listing.py            — сбор ссылок на машины с листинга, пагинация
    network.py            — перехват XHR/fetch ответов через Playwright events
    pace.py               — рандомные паузы и движение мыши

  parsing/
    parser.py             — VehicleParser: 3 канала (DOM + XHR JSON + embedded JSON)
    mapper.py             — CarMapper: нормализация → CarRecord, content hash

  storage/
    models.py             — SQLAlchemy: Car (30+ полей), Image, SyncRun, ScrapeTask
    schemas.py            — Pydantic: CarRecord, ImageRecord, CarRead
    enums.py              — допустимые значения (drive, gearbox, body_type, ...)
    db.py                 — PersistenceService: upsert (insert/update/skip), sync runs

  api/
    app.py                — FastAPI factory, lifespan, роутеры
    deps.py               — dependency injection (Settings, PersistenceService)
    routes/
      health.py           — GET /health
      cars.py             — CRUD по машинам + GET /stats
      tasks.py            — управление Celery-задачами + sync-runs

  worker/
    celery_app.py         — конфиг Celery, beat-расписание
    tasks.py              — sync_vehicle_task, sync_listing_task

  core/
    config.py             — Settings (dataclass), все env-переменные
    logs.py               — логирование с trace_id (ContextVar)
    retry.py              — декоратор @retryable с exponential backoff
    utils.py              — VIN_RE, deep_find_key, вспомогательные функции

alembic/                  — миграции БД
tests/                    — 30 тестов (SQLite in-memory)

Конфигурация

Всё через env-переменные (полный список в .env.example):

БД: IAAI_DATABASE_URL, IAAI_DATABASE_POOL_SIZE Redis: IAAI_REDIS_URL Celery: CELERY_BROKER_URL, CELERY_BEAT_SYNC_INTERVAL_MINUTES Скрапер: IAAI_HEADLESS, IAAI_SYNC_ONLY_NEW, IAAI_MAX_PAGES_PER_RUN Прокси: IAAI_PROXY_SERVER, IAAI_PROXY_USERNAME, IAAI_PROXY_PASSWORD Паузы: IAAI_BETWEEN_VEHICLES_MIN_S, IAAI_AFTER_PAGE_CHANGE_MAX_S и т.д.

Миграции

В Docker миграции накатываются автоматически при старте API-контейнера (alembic upgrade head в entrypoint).

Вручную:

alembic upgrade head
alembic revision --autogenerate -m "add_column_x"

Тесты

pytest -q

30 тестов, SQLite in-memory, без внешних зависимостей.