Files
Openlane/README.md
2026-04-08 14:30:27 +03:00

174 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IAAI Scraper
Скрапер листинга автомобилей с сайта IAAI.
Собирает данные карточек через Playwright, парсит HTML и перехваченные JSON ответы,
нормализует и сохраняет в PostgreSQL или SQLite через SQLAlchemy.
По умолчанию работает последовательно одна машина за раз, с паузами между запросами.
## Что делает
1. Открывает страницу листинга `Vehiclelisting/Cars`, собирает ссылки на карточки.
2. Переходит на каждую карточку, перехватывает XHR/fetch JSON-ответы.
3. Парсит DOM-текст, `<title>`, встроенные `<script>` с JSON, сетевые payload'ы.
4. Маппит всё в единую структуру `CarRecord` (pydantic) с нормализацией полей.
5. Делает upsert в БД по `origin_id`, сравнивая `content_hash`, чтобы пропускать неизменившиеся записи.
6. Защищён от дублей: `origin_id` уникален, одинаковые записи пропускаются, а повторные картинки заменяются безопасно.
## Структура проекта
```
iaai_scraper/
├── browser/
│ ├── factory.py # запуск Chrome/Chromium с desktop-фингерпринтом
│ ├── network.py # перехват XHR/fetch, фильтрация и категоризация JSON
│ └── pace.py # паузы между действиями
├── core/
│ ├── config.py # настройки из .env
│ ├── logs.py # setup logging
│ ├── retry.py # retry-декоратор
│ └── utils.py # regex, deep_find_key, save_to_json
├── parsing/
│ ├── parser.py # DOM + JSON парсинг
│ └── mapper.py # нормализация в CarRecord
├── storage/
│ ├── models.py # ORM: cars, images, sync_runs
│ ├── schemas.py # pydantic-схемы
│ ├── db.py # upsert с content_hash
│ ├── listing.py # сбор ссылок из листинга
│ └── enums.py # enum-значения для БД
├── scraper.py # главный модуль
└── cli.py # CLI (argparse)
```
## Установка
```bash
pip install -r requirements.txt
python -m playwright install chromium
```
## Настройка
Создайте `.env` на основе `.env.example`:
```env
IAAI_HEADLESS=true
IAAI_DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5432/iaai_scraper
```
Все настройки (pacing, лимиты, gentle mode, retry/backoff, scheduler) задаются через переменные окружения в `.env.example`.
### БД для рабочего сайта
Для рабочего запуска нужно **PostgreSQL**.
Пример:
```env
IAAI_DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5432/iaai_scraper
```
SQLite подходит для локальной отладки, но не для production-сценария сайта.
### Scheduler по умолчанию
Режим :
- запуск раз в **1 час**
- лимит **30 машин за цикл**
Это уже отражено в актуальных env-настройках.
### Прокси и anti-bot
IAAI использует anti-bot / fraud protection.
Что важно:
- предпочтительно использовать **USA residential** или **USA mobile** прокси
- для Playwright лучше использовать **HTTP/HTTPS proxy**
- Chromium **не поддерживает SOCKS5 с аутентификацией напрямую**
- поэтому для production желательно покупать прокси, который отдаёт именно HTTP/HTTPS доступ
Пример:
```env
IAAI_PROXY_SERVER=http://proxy.example.com:8080
IAAI_PROXY_USERNAME=username
IAAI_PROXY_PASSWORD=password
```
### Captcha / anti-bot detection
В парсере добавлены признаки для определения возможной captcha / anti-bot страницы:
- `possible_captcha`
- `possible_antibot`
- `dom_hints.has_captcha_text`
- `dom_hints.has_antibot_text`
Если сайт начнёт отдавать защитную страницу, это можно увидеть в результате scrape.
## Команды
```bash
# создать таблицы
python main.py init-db
# собрать ссылки из листинга
python main.py collect-listing --make Toyota --model Camry --output listing.json
# scrape одной карточки
python main.py scrape-vehicle "https://www.iaai.com/VehicleDetail/41180634~US" --output result.json
# scrape + запись в БД
python main.py sync-vehicle "https://www.iaai.com/VehicleDetail/41180634~US" --lane iaai
# массовая синхронизация листинга
python main.py sync-listing --make Toyota --model Camry --lane iaai_cars --limit 30
# daemon-режим (цикл каждые N минут)
python main.py run-daemon --interval 60
```
## Тесты
```bash
pytest tests -q
```
## Docker
```bash
# собрать образ
docker compose build
# запустить daemon (по умолчанию run-daemon)
docker compose up -d
# посмотреть логи
docker compose logs -f
# одноразовая команда
docker compose run --rm iaai-scraper python main.py sync-listing --limit 5
# остановить (graceful shutdown)
docker compose down
```
Контейнер автоматически перезапускается при крашах (`restart: unless-stopped`).
Для Docker прокси также задаются через `.env`.
## Защита от дублей
Система защищена от дублей на нескольких уровнях:
- `origin_id` уникален в БД
- при совпадении `content_hash` запись **пропускается** (`skipped`)
- при обновлении запись не дублируется, а обновляется
- изображения пересобираются без накопления дублей