Compare commits
1 Commits
main
...
032608261e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
032608261e |
114
README.md
Normal file
114
README.md
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
# 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/<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
|
||||||
|
```
|
||||||
|
|
||||||
Reference in New Issue
Block a user