# Encar Scraper Парсер автомобилей с [encar.com](https://www.encar.com) — крупнейшей корейской площадки продажи авто. ## Как это работает Скрапер работает через публичный JSON API Encar (без браузера, без Selenium): 1. **Листинг** — `api.encar.com/search/car/list/general` отдаёт список авто с пагинацией (до 1000 на страницу) 2. **Шардирование** — API лимитирует выдачу ~10k результатов, поэтому весь каталог (~230k авто) разбивается на 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 - **~100 авто/сек** — полный sync ~230k авто за ~35 мин - **PostgreSQL** для хранения данных (авто + фото) - **Celery + Redis** для фоновых задач и периодической синхронизации - **FastAPI** REST API для управления задачами и просмотра данных ## Быстрый старт (Docker) ```bash docker compose up -d --build ``` Поднимутся сервисы: - `encar-postgres` — PostgreSQL - `encar-redis` — Redis - `encar-api` — FastAPI на порту 8000 - `encar-worker` — Celery worker - `encar-beat` — периодическая синхронизация (каждые 60 мин) ## CLI ```bash # Инициализация БД 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" ``` ### Фильтры ```bash 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` — история синхронизаций ### Примеры ```bash # Запуск синхронизации 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/ # Список авто 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 ```