Files
encar/README.md
2026-04-16 18:13:45 +03:00

4.9 KiB
Raw Permalink Blame History

Encar Scraper

Парсер автомобилей с encar.com

Как работает

Скрапер работает через публичный JSON API Encar (без браузера, без Selenium):

  1. Листингapi.encar.com/search/car/list/general отдаёт список авто с пагинацией (до 1000 на страницу)
  2. Шардирование — API лимитирует выдачу от 10k результатов, поэтому весь каталог 200к+ разбивается на 36 шардов по типу (domestic/import) и диапазонам годов
  3. Фото — batch endpoint api.encar.com/v1/readside/vehicles (до 20 ID за запрос) возвращает все фото с CDN ci.encar.com
  4. Переводы — корейские названия брендов, моделей и цветов автоматически переводятся в русские/английские
  5. Sold-трекинг — авто, пропавшие из листинга, помечаются как проданные

Celery Beat запускает полную синхронизацию каждые 60 минут. Worker обходит все шарды, парсит данные и пишет батчами в PostgreSQL.

Особенности

  • Чистые HTTP запросы — без браузера, через публичный API Encar
  • PostgreSQL для хранения данных (авто + фото)
  • Celery + Redis для фоновых задач и периодической синхронизации
  • FastAPI REST API для управления задачами и просмотра данных

Быстрый старт (Docker)

docker compose up -d --build

Поднимутся сервисы:

  • encar-postgres — PostgreSQL
  • encar-redis — Redis
  • encar-api — FastAPI на порту 8000
  • encar-worker — Celery worker
  • encar-beat — периодическая синхронизация (каждые 60 мин)

CLI

# Инициализация БД
encar init-db

# Собрать листинг
encar collect-listing --limit 100

# Синхронизировать листинг в БД
encar sync-listing --limit 100 --car-type all --only-new true

# Синхронизировать одно авто
encar sync-vehicle "https://www.encar.com/dc/dc_cardetailview.do?carid=41421262"

Фильтры

encar sync-listing --car-type import --manufacturer BMW --year-from 2020 --limit 50

API endpoints

  • GET /health — проверка доступности
  • GET /api/v1/cars — список авто с пагинацией и фильтрами
  • GET /api/v1/cars/{car_id} — детали авто
  • GET /api/v1/cars/by-origin/{origin_id} — поиск по origin_id
  • POST /api/v1/tasks/sync-vehicle — синхронизация одного авто
  • POST /api/v1/tasks/sync-listing — синхронизация листинга
  • GET /api/v1/tasks/{task_id} — статус задачи
  • GET /api/v1/sync-runs — история синхронизаций

Примеры

# Запуск синхронизации
curl -X POST http://localhost:8000/api/v1/tasks/sync-listing \
  -H "Content-Type: application/json" \
  -d '{"car_type": "all", "limit": 100, "only_new": true}'

# Статус задачи
curl http://localhost:8000/api/v1/tasks/<task_id>

# Список авто
curl "http://localhost:8000/api/v1/cars?page=1&per_page=20"

Переменные окружения

  • БД: ENCAR_DATABASE_URL
  • Redis: ENCAR_REDIS_URL
  • Celery: CELERY_BROKER_URL, CELERY_RESULT_BACKEND, CELERY_TASK_TIME_LIMIT
  • Beat: ENCAR_BEAT_INTERVAL_MINUTES (по умолчанию 60), ENCAR_BEAT_LIMIT (0 = без лимита)

Структура проекта

encar_scraper/
├── encar.py          — скрапер Encar (HTTP API), маппер, переводы
├── cli.py            — CLI интерфейс
├── api/
│   ├── app.py        — FastAPI приложение
│   └── routes/       — health, cars, tasks
├── core/
│   ├── config.py     — настройки из env vars
│   ├── utils.py      — утилиты (save_to_json, deep_find_key)
│   └── logs.py       — логирование с trace_id
├── storage/
│   ├── db.py         — PersistenceService (upsert, session_scope)
│   ├── models.py     — SQLAlchemy модели (Car, Image, SyncRun)
│   └── schemas.py    — Pydantic схемы (CarRecord, ImageRecord)
└── worker/
    ├── celery_app.py — Celery app + beat schedule
    └── tasks.py      — encar_sync_listing_task, encar_sync_vehicle_task