Полнофункциональный скрапер, просмотрщик и архиватор коллекций с сайта collectionerus.ru.
- Описание
- Возможности
- Структура проекта
- Установка
- Быстрый старт
- Компоненты
- Формат данных
- Использование
- Сборка EXE
- Безопасность EXE
- FAQ
- Лицензия
Collectionerus Scraper — инструмент для автоматического скачивания публичных коллекций предметов (открытки, значки, марки, монеты и т.д.) с сайта collectionerus. Проект состоит из четырёх основных компонентов:
- Scraper — многопоточный скрапер с интерактивным меню, умным fallback'ом URL, кешем паттернов, возобновлением после прерывания и упаковкой в ZIP.
- Viewer — локальный веб-просмотрщик на Flask с фильтрацией, поиском, lightbox-галереей и поддержкой cross-item ссылок.
- Builder — скрипт сборки в автономные EXE-файлы через PyInstaller.
- Tests — простое тестирование функций.
- 🔄 Автоматическое скачивание всех коллекций или выбранных по номерам
- 🧵 Многопоточность — параллельная загрузка изображений (до 10 потоков) и деталей предметов (до 5 потоков)
- 💾 Возобновление — прогресс сохраняется в
_progress.json, прерванное скачивание продолжается с того же места - 🔍 Умный fallback URL — автоматический перебор качества изображений (
preloaded-items→items-large→items-thumbs) с обучаемым кешем паттернов - 📦 ZIP-архивация — упаковка скачанных коллекций с удалением исходных папок
- ✅ Проверка целостности — поиск битых, пропущенных и дублирующихся файлов
- 🔎 Сканирование — анализ коллекций на наличие дополнительных фото и связанных предметов
- 📊 Детализированная статистика — подсчёт 404, таймаутов, HTML-ответов, fallback'ов
- 🛡️ Антибот-защита — автоматическое определение Cloudflare и rate-limit'ов
- 🌐 Полный оффлайн — работает без интернета, все данные локальные
- 🔎 Поиск и фильтрация по всем свойствам предметов
- 🖼️ Lightbox-галерея с навигацией клавиатурой
- 🔗 Cross-item ссылки — связанные предметы отображаются с локальными изображениями через media-индекс
- 📱 Адаптивный дизайн — работает на мобильных устройствах
- 🔒 XSS-защита — санитизация HTML-описаний (bleach или fallback regex)
- 🚀 Автооткрытие браузера при запуске
- 🏗️ Сборка в EXE — два автономных исполняемых файла
- 🎨 Генерация иконок — автоматическое создание
.icoчерез Pillow или минимальный BMP
📂 Нажмите, чтобы развернуть дерево файлов
collectionerus-scraper/
├── config.py # Единая конфигурация
├── utils.py # Общие утилиты
├── requirements.txt # Зависимости Python
├── .gitignore
├── README.md
├── LICENSE
├── scripts/
│ ├── scraper.py # Основной скрапер (v10)
│ ├── viewer.py # Веб-просмотрщик (v4)
│ ├── builder.py # Сборка EXE
│ └── tests.py # Тесты проекта
├── assets/
│ ├── scraper.ico # Иконка скрапера
│ └── viewer.ico # Иконка вьюера
├── data/
│ ├── metadata/ # Метаданные и изображения коллекций
│ │ ├── _collections_list.json
│ │ ├── _check_report.json
│ │ └── <slug>/ # Папка коллекции
│ │ ├── collection_info.json
│ │ ├── metadata.json
│ │ ├── metadata.csv
│ │ ├── fields_info.json
│ │ ├── _progress.json
│ │ └── images/
│ │ ├── 00001_Название.jpg
│ │ └── 00002_Название/
│ │ ├── main.jpg
│ │ ├── 02.jpg
│ │ ├── related_01_Связанный.jpg
│ │ └── _info.json
│ ├── archives/ # ZIP-архивы (repack)
│ └── scraper.log # Лог работы
├── dist/ # Собранные EXE
│ ├── collectionerus-scraper.exe
│ └── collectionerus-viewer.exe
├── templates/ # Jinja2-шаблоны (создаются автоматически)
│ ├── base.html
│ ├── index.html
│ ├── collection.html
│ └── item.html
└── static/
└── style.css
- Python 3.8+
- pip
pip install -r requirements.txt📄 Содержимое requirements.txt
requests>=2.28
beautifulsoup4>=4.11
flask>=2.3
markupsafe>=2.1
bleach>=6.0 # опционально, для XSS-защиты
pillow>=9.0 # опционально, для генерации иконок
pyinstaller>=5.0 # опционально, для сборки EXE
python scripts/scraper.pyОткроется интерактивное меню:
══════════════════════════════════════════════════════════════════════
📦 COLLECTIONERUS SCRAPER v10
══════════════════════════════════════════════════════════════════════
📋 Коллекций: 141 (кэш: 5 мин назад)
✅ Готово: 120 🔄 В процессе: 3 ⬚ Не начато: 18
──────────────────────────────────────────────────────────────────────
1. 📥 Скачать коллекции
2. 🔍 Проверить скачанное
3. 🔎 Сканировать (доп. фото)
4. 📦 Упаковать в ZIP
5. 🔄 Перекачать с нуля
6. 🔃 Обновить список коллекций
7. 📋 Показать список коллекций
──────────────────────────────────────────────────────────────────────
q. Выход
──────────────────────────────────────────────────────────────────────
python scripts/viewer.pyОткроется браузер на http://localhost:5000 с каталогом всех скачанных коллекций.
python scripts/builder.pyОсновной скрапер коллекций. Версия 10 с полным набором исправлений.
| Класс | Описание |
|---|---|
CollectionScraper |
Главный скрапер: HTTP-сессия, парсинг HTML, скачивание изображений, умный fallback URL |
MenuManager |
Интерактивное меню с навигацией, кешем коллекций |
ZipManager |
Упаковка в ZIP, проверка актуальности, удаление папок |
DownloadChecker |
Проверка целостности: битые файлы, пропущенные изображения, дубликаты |
AntiBotChecker |
Определение Cloudflare, rate-limit, адаптация задержек |
all — все коллекции
5 — коллекция #5
1-10 — диапазон 1..10
1,3,5 — перечисление
1-10,!5 — диапазон с исключением
odd — нечётные
even — чётные
Скрапер автоматически пробует URL в порядке убывания качества:
/preloaded-items/— оригинал/items-large/— большой размер/items-thumbs/— миниатюра (всегда доступна)
Кеш запоминает, какие паттерны работают для каждой коллекции. После 3 ответов 404 паттерн отключается.
- Каждый поток использует уникальный
tmp-файл (filepath.tmp.<thread_id>) - Статистика защищена
threading.Lock - Кеш URL-паттернов защищён отдельным
_cache_lock
Локальный веб-просмотрщик на Flask (v4).
- Главная страница — сетка коллекций с миниатюрами, поиском, бейджами
- Страница коллекции — фильтрация по всем свойствам, пагинация, сортировка, боковая панель
- Страница предмета — галерея изображений, lightbox, связанные предметы, похожие, навигация ← →
- Media-индекс (v3) — маппинг URL с сайта → локальные файлы для отображения cross-item ссылок
| Роут | Описание |
|---|---|
/ |
Список коллекций |
/collection/<slug>/ |
Предметы коллекции |
/collection/<slug>/item/<index>/ |
Карточка предмета |
/data/<path> |
Статические файлы из metadata |
/media/<path> |
Проксирование media URL через индекс |
/collections/<slug>/items/<id>/ |
Редирект внешних ссылок → локальные |
При запуске viewer строит индекс всех скачанных изображений:
URL с сайта (thumb_url, images[]) → путь к локальному файлу
Это позволяет корректно отображать <img> в описаниях предметов, даже если URL указывает на другой предмет (cross-item-link).
Сборка в автономные EXE через PyInstaller.
python scripts/builder.pyИнтерактивное меню:
| # | Действие |
|---|---|
| 1 | Собрать collectionerus-scraper.exe (консольное) |
| 2 | Собрать collectionerus-viewer.exe (консольное + Flask) |
| 3 | Собрать оба |
| 4 | Перегенерировать иконки |
| 5 | Очистить build/ |
| 6 | Очистить dist/ |
EXE ищет папку data/ в следующем порядке:
- Рядом с
.exe - На уровень выше (если exe в
dist/) - В текущей рабочей директории
- Создаёт
data/рядом с exe
Базовые тесты проекта.
# Все тесты
python scripts/tests.py
# Выборочно
python scripts/tests.py imports
python scripts/tests.py config
python scripts/tests.py utils
python scripts/tests.py structure
python scripts/tests.py viewer
python scripts/tests.py data
python scripts/tests.py scraper| Группа | Тесты |
|---|---|
| imports | Импорт config, utils, requests, bs4, flask, markupsafe |
| config | PROJECT_ROOT, BASE_URL, задержки, потоки, расширения, ensure_dirs, PyInstaller |
| utils | safe_filename, parse_selection, get_extension |
| structure | Наличие обязательных файлов |
| viewer | Ключевые функции: _make_image_url, _build_media_index, sanitize_html, serve_media и др. |
| data | Структура metadata.json, images/, ZIP-архивы |
| scraper | Классы, методы, отсутствие safe_dirname |
Единая конфигурация проекта.
# Пути
PROJECT_ROOT # Корень проекта (с поддержкой PyInstaller)
DATA_DIR # data/
METADATA_DIR # data/metadata/
ARCHIVES_DIR # data/archives/
# Сеть
BASE_URL = "https://collectionerus.ru"
DELAY_PAGE = 0.1 # задержка между страницами (сек)
DELAY_ITEM = 0.05 # задержка между предметами
IMAGE_THREADS = 10 # потоки для скачивания изображений
ITEM_THREADS = 5 # потоки для загрузки деталей
# Файлы
MAX_FILENAME_LEN = 120
MIN_FILE_SIZE = 500 # минимальный размер файла (байт)
BATCH_SIZE = 50 # размер пакета для сохранения прогресса
# Viewer
VIEWER_HOST = '0.0.0.0'
VIEWER_PORT = 5000
VIEWER_DEBUG = True
# ZIP
ZIP_COMPRESSION_LEVEL = 6Общие утилиты, используемые всеми компонентами.
| Функция | Описание |
|---|---|
safe_filename(text, max_len) |
Безопасное имя файла (убирает спецсимволы, обрезает) |
get_extension(url, default) |
Извлекает расширение из URL |
parse_selection(input, max) |
Парсит строку выбора (all, 1-10, !5, odd) |
load_metadata(dir) |
Загружает метаданные из metadata.json или _progress.json |
is_valid_image(filepath) |
Проверяет файл по magic bytes (JPEG, PNG, GIF, WebP, BMP, TIFF) |
is_image_file(filename) |
Проверяет расширение файла |
atomic_write_json(path, data) |
Атомарная запись JSON (tmp + os.replace + fallback) |
dir_size(path) |
Размер директории рекурсивно |
file_hash(filepath) |
MD5-хеш файла |
load_collections_cache() |
Загрузка кеша списка коллекций |
save_collections_cache(list) |
Сохранение кеша |
format_cache_age(path) |
Человекочитаемый возраст кеша |
get_col_dir(slug) |
Путь к папке коллекции |
📄 Пример JSON (развернуть)
{
"collection": {
"name": "Советские открытки",
"slug": "ussr-postcards",
"url": "https://collectionerus.ru/collections/ussr-postcards/",
"count": 500
},
"scraped_at": "2026-02-28T12:00:00",
"items": [
{
"index": 1,
"filename": "00001_Открытка_1960.jpg",
"title": "Открытка «С Новым годом!»",
"url": "https://collectionerus.ru/collections/ussr-postcards/items/12345/",
"properties": {
"Год": "1960",
"Художник": "Зарубин",
"Тираж": "500000"
},
"images": [
"https://collectionerus.ru/media/preloaded-items/abc.jpg"
],
"downloaded_files": ["00001_Открытка_1960.jpg"],
"related_items": [
{
"file": "00001_Открытка_1960/related_01_Обратная_сторона.jpg",
"title": "Обратная сторона"
}
]
}
]
}📄 data (развернуть)
data/metadata/<slug>/
├── collection_info.json # Информация о коллекции
├── metadata.json # Все предметы с метаданными
├── metadata.csv # CSV-экспорт
├── fields_info.json # Покрытие полей
├── _progress.json # Прогресс скачивания (удаляется при ZIP)
└── images/
├── 00001_Простой.jpg # Предмет с 1 фото
├── 00002_С_галереей/ # Предмет с несколькими фото
│ ├── main.jpg
│ ├── 02.jpg
│ ├── related_01_Связанный.jpg
│ └── _info.json
└── ...
# Запуск с интерактивным меню
python scripts/scraper.py
# В меню выбрать:
# 1 → скачать коллекции
# Ввести: all (все), 1-10 (диапазон), 5 (одну)# В меню скрапера:
# 2 → проверить скачанное
# Отчёт сохраняется в data/metadata/_check_report.jsonpython scripts/viewer.py
# Откроется http://localhost:5000# В меню скрапера:
# 4 → упаковать в ZIP
# Выбрать коллекции, опционально удалить папки послеpython scripts/tests.py# Установить PyInstaller
pip install pyinstaller pillow
# Запустить сборку
python scripts/builder.py
# Выбрать 3 — собрать оба EXE
# Результат:
# dist/collectionerus-scraper.exe (~15 MB)
# dist/collectionerus-viewer.exe (~17 MB)# Положить data/ рядом с EXE или на уровень выше
# Запустить:
collectionerus-scraper.exe # скрапер с меню
collectionerus-viewer.exe # откроется браузерEXE-файлы собраны через PyInstaller из открытого исходного кода данного репозитория. PyInstaller упаковывает интерпретатор Python и зависимости в один файл, что часто вызывает ложные срабатывания антивирусов (false positive).
Каждый релиз проверен на VirusTotal (70+ антивирусных движков):
| Файл | Результат | Отчёт |
|---|---|---|
collectionerus-scraper.exe |
✅ 6/70 — AI срабатывания | 🔗 Открыть отчёт |
collectionerus-viewer.exe |
✅ 5/70 — AI срабатывания | 🔗 Открыть отчёт |
💡 Как проверить самостоятельно: загрузите EXE на virustotal.com → увидите результат за 1-2 минуты.
e7729f405f9e993a529855f2b10e7cdbc0774b2649b50a89608f82f1b45b02fb collectionerus-scraper.exe
0d5c254baf649ea1f9b9ab7b37e0c4b733a9255e7d1bccb1c63d581f99ac2d72 collectionerus-viewer.exe
ee79ab3db1915b01e640222c5d35c96b66407a9ba36aa7323fa4c20725a055b5 collectionerus-scraper.zip
604c0e975e9a29200c230da1f61d427f76f6bdc93e21df660a00c9aace16ebe5 collectionerus-viewer.zip
PyInstaller-сборки иногда детектируются эвристикой как «подозрительные», потому что:
- EXE распаковывает Python-рантайм во временную папку при запуске
- Такой же механизм используют некоторые вредоносные программы
- Это не означает, что файл заражён
Решения:
- Проверьте отчёт VirusTotal по ссылкам выше
- Сравните SHA-256 хеш скачанного файла с указанным
- Соберите EXE самостоятельно из исходников:
python scripts/builder.py - Добавьте файл в исключения антивируса
При первом запуске Windows может показать предупреждение:
"Windows защитила ваш компьютер"
→ Подробнее → Выполнить в любом случае
Это происходит потому, что EXE не подписан цифровой подписью (code signing certificate стоит $200+/год). Предупреждение исчезнет после нескольких запусков.
В папке data/metadata/ — метаданные и изображения, data/archives/ — ZIP-архивы.
Да, Ctrl+C. Прогресс сохраняется в _progress.json. При следующем запуске скачивание продолжится с того же места.
В меню скрапера: 5 → Перекачать с нуля, выбрать номера коллекций.
Убедитесь, что data/metadata/ содержит папки коллекций с metadata.json и images/.
При запуске viewer сканирует все metadata.json и строит маппинг:
thumb_urlпредмета → путь к его первому скачанному файлуimages[i]→downloaded_files[i]related_items[].thumb_url→related_items[].file
Это позволяет отображать <img src="/media/items-thumbs/..."> в описаниях предметов из локальных файлов.
~125 ГБ для всех 141 коллекций (в ZIP-архивах).
Да. Смотрите раздел Безопасность EXE — там ссылки на отчёты VirusTotal и инструкции по самостоятельной проверке.
Проект распространяется под лицензией MIT — используйте как угодно, но на свой страх и риск.
Программное обеспечение предоставляется «КАК ЕСТЬ» (AS IS), без каких-либо явных или подразумеваемых гарантий, включая, но не ограничиваясь, гарантиями товарной пригодности и пригодности для конкретной цели.
Автор ни при каких обстоятельствах не несёт ответственности за:
- прямые, косвенные, случайные, штрафные или побочные убытки
- потерю данных, прибыли или деловой репутации
- блокировку аккаунтов, IP-адресов, доменов
- нарушение условий использования сторонних сервисов
- любые претензии третьих лиц
- Все скачиваемые материалы являются собственностью их правообладателей
- Сайт collectionerus.ru — владелец контента
- Пользователь обязан самостоятельно убедиться в законности скачивания и использования материалов в своей юрисдикции
Проект создан исключительно в образовательных и исследовательских целях для демонстрации методов веб-скрапинга на Python. Автор не поощряет нарушение авторских прав или условий использования сайтов.