Есть у каждого такая железка. Купил вроде бы «для дела», а потом годами используешь как угодно, только не «для дела». У меня это мини ПК CHUWI CoreBox с Ubuntu под капотом. Он был и прокси, и NAS, и VPN, и сервером Lineage 2 (три человека играли, один из них я, второй — жена), и даже чем‑то вроде цифровой кладовки для вещей, которые жалко удалять, но которыми невозможно пользоваться (все было убито, потому что хранить хлам и ждать, когда он пригодится — плохо).
Когда то я купил себе 3D принтер просто поиграться. И в какой‑то момент неожиданно понял, что это одно из самых крутых хобби, которые у меня вообще были. В 3D печати есть что‑то удивительно честное и созидательное: ты делаешь модель, нажимаешь кнопку, и через пару часов держишь в руках вещь, которой раньше не существовало. Даже если это маленькая бесполезная мелочь вроде берущегося за голову дракончика или держателя для зубочисток, ощущение «я это создал» работает и присутствует. И вот тогда мне и пришло в голову, что хочется собрать свою библиотеку моделей, чтобы печатать что угодно в любую секунду.
Ах да, к сути...
Однажды я проснулся утром и подумал: «А не сделать ли из этого ветерана экспериментов автономного сборщика 3D моделей со всех инторнетов, чтобы тот тихо, без жалоб, подсобирал мне библиотеку на будущее?»
Звучало немного безумно и очень весело. Значит надо делать.
Зачем вообще в 2025 году собирать 3D модели
Для тех, кто счастлив и не шарится по сайтам с моделями: мир STL, OBJ и 3MF выглядит как лист в тетрадке у восьмиклассника. Все в одном месте, но не разберешь, что к чему, зачем и почему оно вообще тут.
Добавим к этому:
десятки сайтов
реклама
платные логины
платные скачивания (ничего не имею против и спокойно плачу за качественные модельки по 3 - 10 долларов, но все же!)
куча моделей упакована в ZIP
половина ZIP пустые, исчезли или побиты
у половины моделей "model_1.stl" как название, и угадай что внутри
Все это не хочется отслеживать руками.
Лучше, чтобы делала машина.
Машине не жалко. Машина не устанет.

Цель: личный автономный мини-Thingiverse
Требования сформировались сами собой:
Краулер обходит сайты (только те, что открыты и разрешены).
Находит потенциальные ZIP и STL.
Скачивает.
Распаковывает.
Валидирует модели (не повреждены ли).
Классифицирует по категориям.
Складывает аккуратно по папкам.
Работает на 100% автономно.
Архитектура
[Crawler] -> pages.db -> [Downloader] -> files -> [Validator] -> [Classifier] -> models/
Ключевые компоненты:
Crawler
- Обходит seed страницы, вытаскивает ссылки, фильтрует потенциальные загрузки. Seed можно положить или в базу, или прямо в код. На тестах я пошел по второму пути, а на бою выбрал первый.Downloader
- Скачивает ZIP и STL.
- Распаковывает.
- Проверяет, что внутри (на плечах Downloader только валидация по размеру файла. Задаем любой рэндж и не качаем "нули").
- Удаляет мусор, кидает полезное в хранилище.Classifier
GPT (API token) смотрит файл и генерирует красивое название, категорию, набор тегов. Дополнительная информация склалдывается в meta.json рядом с моделью.Validator
Использует trimesh для проверки STL.
Если файл битый, пустой или представляет собой модель под названием "ничего", он летит в топку.

База на SQLite, потому что:
простая
надежная
не требует сервера
переживет что угодно (не всегда, да, но все равно)
поддерживает десятки миллионов записей, если ее не кормить мусором
Анти-DDoS меры и этичность
Я решил, что в моем сценарии я хочу вообще не мешать сайтам жить спокойно.
Поэтому в систему встроены элементарные, но важные правила приличия:
Ползать медленно.
Crawler делает паузу между запросами. Не «миллисекунду, потому что мне надо быстрее», а нормальные человеческие 3–5 секунд. Я же не Googlebot.Никаких сотен параллельных потоков.
Все работает в одном процессе. Это не промышленный скачивальщик. Это домашнее хобби, а не атака.Ограничение глубины обхода.
Я не пытаюсь залезть на страницы, куда сам сайт не хочет, чтобы я лез. Если ссылка слишком глубокая или не относится к моделям, я туда не хожу.Только открытый контент.
Никаких обходов логина, paywall или «хитрых запросов». Все ссылки, которые поднимает краулер, доступны анонимно. Если сайт не дает скачивать анонимно — я иду мимо и никаких о��ид и попыток пробить/обойти стену.Никаких попыток выгребать сайт целиком.
Цель — не стать зеркалом, а собрать личную коллекцию интересных моделей.Корректные User‑Agent и заголовки.
Ничего маскирующего. Я даже честно отправляю свой User‑Agent, чтобы было понятно, что это бот‑собиратель.
С этим подходом краулер живет тихо, мирно и никому не мешает. За неделю ползания я не получил ни одного бана и ни один сайт не стал отвечать капчей или криками «ты кто вообще такой». Такой результат меня полностью устраивает.
Проблемы с реальными STL файлами или почему 3D модели иногда ведут себя как коты
STL файлы бывают трех типов:
Нормальные.
Они открываются, печатаются и вообще радуют.Странные.
В них 0 полигонов, 0 граней и иногда текст "Created by SomethingFreeEditionUnregistered".
Я не шучу, такое встречалось много разПроклятые (мы все еще сравниваем сущности с котами, не забываем).
Эти выглядят как нормальные, весят мегабайт, но при попытке загрузить их через trimesh превращаются в ошибку уровня «я не знаю, что это, но это точно не 3D модель».
Стоит понимать: STL бывает в ASCII и binary форматах, и сайты иногда пихают в ZIP такое, что сложно назвать «геометрией».
Именно поэтому у меня обязательный пайплайн:
файл скачан
если ZIP - распакован
каждая STL проходит через trimesh.load()
"Модель" летит в мусор если она:
пустая
битая
вызывает исключение
имеет 0 faces
состоит из одного треугольника размером с вселенную
или просто выглядит подозрительно
Validator стал моим главным героем. Он тихо убирает весь мусор и оставляет только то, что действительно имеет смысл печатать.
Как GPT помогает классифицировать модели и почему это невероятно удобно
Я пробовал вручную разбирать модели по категориям.
Хватило примерно 7 минут, чтобы понять, что это пытка.
Названия вроде model_1_final_fixed_v3.stl не помогают вообще.
Поэтому я сделал классификатор на GPT API, который делает сразу несколько вещей:
Нормализует название модели
Если страница называлась "MyDragonNew2023VFinalFixed", GPT выдаст человеческое: Articulated Cute Dragon.Определяет категорию
У меня набор основных категорий (на момент написания статьи): animals, toys, gadgets, household, cosplay, decor, mechanical, figures, parts.
GPT безошибочно (ладно, попадание где-то 98%) кладет модель туда, куда надо.Генерирует теги
Это важно для поиска. Модель «кубик» может иметь теги: ["cube", "parametric", "math", "geometry", "calibration"]Пишет краткое описание
Иногда страница с моделью выглядит так: "Here is a model. Enjoy."
GPT превращает это в нормальный текст, который можно прочитать через 5 лет и вспомнить, зачем и что это.
Философская часть
Мини ПК служил много лет.
Он пережил прокси сервер, VoIP эксперименты, Lineage 2 сервер, архив фильмов, домашний торрентовый ад, и дошел до момента, когда он стал полностью автономной системой, которая сама ползает по интернету, сама ищет STL, сама сортирует, сама валидирует, сама классифицирует.
Мне нравится думать, что я подарил ему вторую жизнь.
Он заслужил.