From 3eee68aee4e07b5660b75e2ff730cabbe723696e Mon Sep 17 00:00:00 2001 From: qananasikq Date: Thu, 16 Apr 2026 18:11:22 +0300 Subject: [PATCH] update readme --- README.md | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..9250639 --- /dev/null +++ b/README.md @@ -0,0 +1,113 @@ +# Encar Scraper + +Парсер автомобилей с [encar.com](https://www.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) + +```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 +``` +