From 21bdf17f35fb1f376f0603b9a48b69e5be07bee9 Mon Sep 17 00:00:00 2001 From: qananasikq Date: Wed, 8 Apr 2026 13:30:17 +0300 Subject: [PATCH] update readme and env --- .env.example | 39 ++++++++++++++++++-------- Dockerfile | 2 ++ README.md | 76 +++++++++++++++++++++++++++++++++++++++++++++++---- entrypoint.sh | 4 +++ 4 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 entrypoint.sh diff --git a/.env.example b/.env.example index a63c2d6..5b0cd8a 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -IAAI_HEADLESS=false +IAAI_HEADLESS=true IAAI_RAW_OUTPUT_JSON=iaai_raw_network.json IAAI_LOG_LEVEL=INFO # IAAI_LOG_FILE=iaai_scraper.log @@ -13,11 +13,11 @@ IAAI_POST_OPEN_IDLE_MS=3500 # Sequential listing-first mode. IAAI_CARS_LISTING_URL=https://www.iaai.com/Vehiclelisting/Cars -IAAI_MAX_PAGES_PER_RUN=1 -IAAI_MAX_VEHICLES_PER_RUN=10 -IAAI_PAGE_LINK_LIMIT=20 -IAAI_INCLUDE_PAGINATION=false -IAAI_COLLECT_CURRENT_PAGE_ONLY=true +IAAI_MAX_PAGES_PER_RUN=10 +IAAI_MAX_VEHICLES_PER_RUN=30 +IAAI_PAGE_LINK_LIMIT=100 +IAAI_INCLUDE_PAGINATION=true +IAAI_COLLECT_CURRENT_PAGE_ONLY=false # Human-like pacing. IAAI_HUMAN_PACE_ENABLED=true @@ -25,15 +25,30 @@ IAAI_AFTER_LISTING_OPEN_MIN_S=2.5 IAAI_AFTER_LISTING_OPEN_MAX_S=4.5 IAAI_AFTER_FILTER_ACTION_MIN_S=2.0 IAAI_AFTER_FILTER_ACTION_MAX_S=4.0 -IAAI_BEFORE_VEHICLE_OPEN_MIN_S=2.5 -IAAI_BEFORE_VEHICLE_OPEN_MAX_S=5.5 -IAAI_AFTER_VEHICLE_OPEN_MIN_S=5.0 -IAAI_AFTER_VEHICLE_OPEN_MAX_S=9.0 -IAAI_BETWEEN_VEHICLES_MIN_S=8.0 -IAAI_BETWEEN_VEHICLES_MAX_S=18.0 +IAAI_BEFORE_VEHICLE_OPEN_MIN_S=1.5 +IAAI_BEFORE_VEHICLE_OPEN_MAX_S=3.0 +IAAI_AFTER_VEHICLE_OPEN_MIN_S=1.0 +IAAI_AFTER_VEHICLE_OPEN_MAX_S=2.5 +IAAI_BETWEEN_VEHICLES_MIN_S=2.0 +IAAI_BETWEEN_VEHICLES_MAX_S=4.0 IAAI_AFTER_PAGE_CHANGE_MIN_S=3.0 IAAI_AFTER_PAGE_CHANGE_MAX_S=6.0 +# Scheduler (default once per hour) +IAAI_SCHEDULER_INTERVAL_MINUTES=60 + +# Retry / backoff +IAAI_RETRY_DELAY_SECONDS=2.5 +IAAI_RETRY_BACKOFF_MULTIPLIER=2.0 +IAAI_RETRY_JITTER_SECONDS=0.25 + +# Proxy (HTTP/HTTPS preferred for Playwright) +# Chromium does not support SOCKS5 proxy authentication directly. +# Use residential or mobile USA proxy. +# IAAI_PROXY_SERVER=http://proxy.example.com:8080 +# IAAI_PROXY_USERNAME= +# IAAI_PROXY_PASSWORD= + # Database. IAAI_DATABASE_URL=sqlite:///iaai_scraper.db IAAI_DATABASE_ECHO=false diff --git a/Dockerfile b/Dockerfile index 44d0f92..e81a9ab 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,5 +9,7 @@ COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt COPY . . +RUN chmod +x entrypoint.sh +ENTRYPOINT ["./entrypoint.sh"] CMD ["python", "main.py", "--help"] diff --git a/README.md b/README.md index fc06fcc..36b5d12 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ Скрапер публичного листинга автомобилей с сайта IAAI. Собирает данные карточек через Playwright, парсит HTML и перехваченные JSON ответы, -нормализует и сохраняет в SQLite (или другую БД через SQLAlchemy). +нормализует и сохраняет в PostgreSQL или SQLite через SQLAlchemy. -Работает последовательно одна машина за раз, с паузами между запросами. +По умолчанию работает последовательно одна машина за раз, с паузами между запросами. ## Что делает @@ -12,7 +12,8 @@ 2. Переходит на каждую карточку, перехватывает XHR/fetch JSON-ответы. 3. Парсит DOM-текст, ``, встроенные `<script>` с JSON, сетевые payload'ы. 4. Маппит всё в единую структуру `CarRecord` (pydantic) с нормализацией полей. -5. Делает upsert в БД по `origin_id`, сравнивая `content_hash` чтобы не перезаписывать одинаковые данные. +5. Делает upsert в БД по `origin_id`, сравнивая `content_hash`, чтобы пропускать неизменившиеся записи. +6. Защищён от дублей: `origin_id` уникален, одинаковые записи пропускаются, а повторные картинки заменяются безопасно. ## Структура проекта @@ -53,10 +54,61 @@ python -m playwright install chromium ```env IAAI_HEADLESS=true -IAAI_DATABASE_URL=sqlite:///iaai_scraper.db +IAAI_DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5432/iaai_scraper ``` -Все настройки (pacing, лимиты, gentle mode) задаются через переменные окружения `.env.example`. +Все настройки (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. ## Команды @@ -74,7 +126,7 @@ python main.py scrape-vehicle "https://www.iaai.com/VehicleDetail/41180634~US" - 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 +python main.py sync-listing --make Toyota --model Camry --lane iaai_cars --limit 30 # daemon-режим (цикл каждые N минут) python main.py run-daemon --interval 60 @@ -93,4 +145,16 @@ docker compose build docker compose run --rm iaai-scraper python main.py --help ``` +Для Docker прокси также задаются через `.env`. + +## Защита от дублей + +Система защищена от дублей на нескольких уровнях: + +- `origin_id` уникален в БД +- при совпадении `content_hash` запись **пропускается** (`skipped`) +- при обновлении запись не дублируется, а обновляется +- изображения пересобираются без накопления дублей + + diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..a645310 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,4 @@ +#!/bin/bash +set -e + +exec "$@"