Initial project version

This commit is contained in:
qananasikq
2026-04-08 23:36:19 +03:00
commit 50d107cfba
54 changed files with 4592 additions and 0 deletions

135
README.md Normal file
View File

@@ -0,0 +1,135 @@
# IAAI Scraper
Небольшой сервис для сбора автомобилей с [iaai.com](https://www.iaai.com).
Собирает ссылки из листинга, открывает карточки машин, достаёт данные из HTML и XHR, сохраняет всё в PostgreSQL.
## Что важно по сайту
У IAAI стоит **Imperva Incapsula** — внешний anti-bot и WAF.
- headless Chromium без прокси часто режется
- часть данных грузится через XHR, часть есть сразу в HTML
- есть cookie banner
Поэтому в проекте используется Playwright, паузы между действиями и прокси.
## Запуск
```bash
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` — история запусков
Пример:
```bash
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:
```bash
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 — основной код скрапера
cli.py — CLI-команды
proxy_bridge.py — HTTP→SOCKS5 мост
browser/
factory.py — запуск браузера и контекста
listing.py — сбор ссылок из листинга
network.py — перехват XHR/fetch
pace.py — паузы между действиями
parsing/
parser.py — разбор карточки машины
mapper.py — нормализация данных
storage/
models.py — SQLAlchemy модели
schemas.py — Pydantic схемы
enums.py — справочники значений
db.py — работа с БД
api/
app.py — FastAPI приложение
deps.py — зависимости
routes/
health.py — GET /health
cars.py — машины и статистика
tasks.py — задачи и история запусков
worker/
celery_app.py — конфиг Celery
tasks.py — фоновые задачи
core/
config.py — настройки
logs.py — логирование
retry.py — retry-логика
utils.py — утилиты
alembic/ — миграции БД
```
## Конфигурация
Основные переменные лежат в `.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-контейнера.
Вручную:
```bash
alembic upgrade head
alembic revision --autogenerate -m "add_column_x"
```
## Тесты
```bash
pytest -q
```
Тесты идут на SQLite in-memory, без внешних сервисов.