IAAI Scraper
Скрапер листинга автомобилей с сайта IAAI. Собирает данные карточек через Playwright, парсит HTML и перехваченные JSON ответы, нормализует и сохраняет в PostgreSQL или SQLite через SQLAlchemy.
По умолчанию работает последовательно одна машина за раз, с паузами между запросами.
Что делает
- Открывает страницу листинга
Vehiclelisting/Cars, собирает ссылки на карточки. - Переходит на каждую карточку, перехватывает XHR/fetch JSON-ответы.
- Парсит DOM-текст,
<title>, встроенные<script>с JSON, сетевые payload'ы. - Маппит всё в единую структуру
CarRecord(pydantic) с нормализацией полей. - Делает upsert в БД по
origin_id, сравниваяcontent_hash, чтобы пропускать неизменившиеся записи. - Защищён от дублей:
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)
Установка
pip install -r requirements.txt
python -m playwright install chromium
Настройка
Создайте .env на основе .env.example:
IAAI_HEADLESS=true
IAAI_DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5432/iaai_scraper
Все настройки (pacing, лимиты, gentle mode, retry/backoff, scheduler) задаются через переменные окружения в .env.example.
БД для рабочего сайта
Для рабочего запуска нужно PostgreSQL.
Пример:
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 доступ
Пример:
IAAI_PROXY_SERVER=http://proxy.example.com:8080
IAAI_PROXY_USERNAME=username
IAAI_PROXY_PASSWORD=password
Captcha / anti-bot detection
В парсере добавлены признаки для определения возможной captcha / anti-bot страницы:
possible_captchapossible_antibotdom_hints.has_captcha_textdom_hints.has_antibot_text
Если сайт начнёт отдавать защитную страницу, это можно увидеть в результате scrape.
Команды
# создать таблицы
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
Тесты
pytest tests -q
Docker
docker compose build
docker compose run --rm iaai-scraper python main.py --help
Для Docker прокси также задаются через .env.
Защита от дублей
Система защищена от дублей на нескольких уровнях:
origin_idуникален в БД- при совпадении
content_hashзапись пропускается (skipped) - при обновлении запись не дублируется, а обновляется
- изображения пересобираются без накопления дублей