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

6.4 KiB
Raw Blame History

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)

Установка

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_captcha
  • possible_antibot
  • dom_hints.has_captcha_text
  • dom_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

# запустить 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)
  • при обновлении запись не дублируется, а обновляется
  • изображения пересобираются без накопления дублей