Загрузчик изображений и видео с платформы Boosty. Есть графический интерфейс на PySide6 и консольный режим, параллельная загрузка, возобновление и постраничная пагинация постов.
Версия 2.0 переписана как пакет с разделением на слои, обработкой ошибок и
сборкой в один .exe.
- Графический интерфейс на PySide6: тёмная тема, прогресс-бар, панель логов.
- Консольный режим
--cliдля запуска без графического окружения. - Параллельная загрузка с настраиваемым числом потоков, от 1 до 32.
- Возобновление: уже скачанные файлы пропускаются.
- Постраничная пагинация, которая обходит все страницы блога, а не только первую, как делала исходная версия.
- Повторные попытки при временных сбоях сети и сервера (5xx, таймауты).
- Пауза при достижении rate limit (HTTP 429).
- Токен хранится в локальном
config.json, а не в исходниках. - Логи пишутся в файл с ротацией (
downloads/.logs/). - Ошибка при скачивании одного файла не прерывает весь процесс.
Требуется Python 3.11 или новее (проверено на 3.12).
# Клонировать репозиторий
git clone https://github.com/MoLineTy19/Boosty-Dumper
cd Boosty-Dumper
# Виртуальное окружение
python -m venv .venv
# Windows: .venv\Scripts\activate
# Linux: source .venv/bin/activate
# Зависимости
pip install -r requirements.txt
# Запуск (GUI)
python run.pypip install -r requirements.txt
pip install -r requirements-build.txt
# Скрипт сборки (очищает build/dist и собирает):
build.bat
# Или вручную:
pyinstaller boosty_dumper.spec --noconfirmГотовый файл появится в dist/BoostyDumper.exe. Это один самодостаточный
исполняемый файл с графическим интерфейсом, размер около 31 МБ.
Размер удалось сильно уменьшить, потому что из PySide6 вырезаются неиспользуемые
модули (WebEngine, то есть встроенный Chromium, а также QML, Quick3D,
Multimedia, SQL, 3D и подобные). Приложение использует только QtCore,
QtGui и QtWidgets. Всё это настроено в boosty_dumper.spec.
Чтобы уменьшить ещё примерно в полтора раза, положите переносимый upx.exe в
папку tools/ (например, со страницы релизов UPX) и пересоберите. Spec
автоматически включит сжатие бинарников.
Если хотите иконку, положите icon.ico рядом с boosty_dumper.spec и замените
icon=None на icon='icon.ico'.
Токен нужен, чтобы API отдавал контент, доступный вашей подписке.
- Зайдите на boosty.to и войдите в аккаунт.
- Откройте страницу любого автора, нажмите F12 и перейдите на вкладку Network.
- Поставьте фильтр Fetch/XHR и перезагрузите страницу.
- В поиске запросов введите
media_album/?type. - В заголовках этого запроса найдите
Authorization: Bearer <ТОКЕН>и скопируйте сам токен, без префиксаBearer. - Вставьте его в поле «Bearer-токен» в окне BoostyDumper или в
config.json.
Токен сохраняется локально в config.json рядом с .exe. Не публикуйте его.
- Вставьте Bearer-токен.
- Укажите имя блога (например
maria_help). - Выберите папку и типы медиа, задайте число потоков.
- Нажмите «Старт». Прогресс и лог видны в окне.
- Чтобы прервать, нажмите «Стоп»: текущие файлы доделаются, новые не начнутся.
python run.py --cli -b maria_help --token ВАШ_ТОКЕН --workers 8Поддерживаемые флаги:
| Флаг | Описание |
|---|---|
--cli |
консольный режим (без GUI) |
-b, --blog |
имя блога (обязательно для --cli) |
--token |
Bearer-токен (перекрывает config.json) |
--workers N |
число потоков загрузки |
--no-images |
не скачивать изображения |
--no-videos |
не скачивать видео |
--no-resume |
перекачивать даже уже существующие файлы |
-c, --config |
путь к config.json |
--version |
показать версию |
Настройки хранятся в config.json рядом с приложением. Файл создаётся
автоматически при первом сохранении из GUI. Пример в config.json.example:
{
"token": "ВАШ_BEARER_ТОКЕН",
"output_dir": "downloads",
"max_workers": 4,
"download_images": true,
"download_videos": true,
"skip_existing": true,
"request_timeout": 30.0
}config.json и папка downloads/ добавлены в .gitignore и не попадают в
репозиторий.
BoostyDumper/
├── boosty_dumper/ основной пакет
│ ├── __init__.py
│ ├── __main__.py точка входа (GUI/CLI)
│ ├── config.py AppConfig: настройки и (де)сериализация
│ ├── exceptions.py иерархия исключений
│ ├── models.py dataclasses: MediaCounters, MediaItem, Post
│ ├── api.py BoostyClient: сессия, retry, пагинация
│ ├── downloader.py DownloadService: потоки, resume, прогресс
│ ├── logging_setup.py ротация логов и GUI-обработчик
│ └── gui/
│ ├── main_window.py QMainWindow: форма, прогресс, лог
│ ├── workers.py QThread-воркер (сигналы progress/log/error)
│ └── style.qss тёмная тема
├── downloads/ куда качаются медиа (.gitignore'd)
│ └── <блог>/{images,videos}/
├── run.py тонкая точка входа для запуска из исходников
├── config.json.example
├── requirements.txt runtime
├── requirements-build.txt pyinstaller
├── boosty_dumper.spec спецификация сборки
├── build.bat скрипт сборки .exe
├── .gitignore
└── README.md
Зависимости идут в одну сторону: gui → downloader → api → models/exceptions.
Слой api.py занимается только сетью и типизацией ответов и ничего не знает про
файлы и UI. Слой downloader.py координирует загрузку и общается с GUI или CLI
через callbacks, а не через Qt-сигналы, поэтому не привязан к конкретному
интерфейсу. Слой gui/ отвечает за представление: QThread-воркер переводит
колбэки в Qt-сигналы, а главное окно только подписывается на них.
| Было (v1) | Стало (v2) |
|---|---|
main.py не запускался (оборванный print() |
запускается |
| Картинка писалась дважды в файл | единая потоковая запись через stream=True |
url['low'] == 'low': баг выбора качества |
корректный выбор по type: high/medium/low |
Bearer-токен зашит в cookies.py |
вводится в UI, хранится в config.json |
| Одна страница постов | постраничная пагинация всех постов |
exit() при 401 |
типизированное исключение и сообщение в UI |
| Последовательная загрузка | ThreadPoolExecutor, до 32 потоков |
| Нет resume | пропуск существующих файлов |
Только input() |
GUI и CLI |
- Python 3.11 или новее (проверено на 3.12).
- PySide6 для GUI.
- Любой современный браузер для получения токена.
Проект предназначен для личного сохранения контента, на который у вас есть доступ (оплаченная подписка). Уважайте условия пользования Boosty и авторские права: не перераспространяйте скачанные материалы. Использование инструмента вопреки правилам платформы остается на вашей ответственности.
MIT © MoLineTy19
