Есть у каждого такая железка. Купил вроде бы «для дела», а потом годами используешь как угодно, только не «для дела». У меня это мини ПК CHUWI CoreBox с Ubuntu под капотом. Он был и прокси, и NAS, и VPN, и сервером Lineage 2 (три человека играли, один из них я, второй — жена), и даже чем‑то вроде цифровой кладовки для вещей, которые жалко удалять, но которыми невозможно пользоваться (все было убито, потому что хранить хлам и ждать, когда он пригодится — плохо).

Когда то я купил себе 3D принтер просто поиграться. И в какой‑то момент неожиданно понял, что это одно из самых крутых хобби, которые у меня вообще были. В 3D печати есть что‑то удивительно честное и созидательное: ты делаешь модель, нажимаешь кнопку, и через пару часов держишь в руках вещь, которой раньше не существовало. Даже если это маленькая бесполезная мелочь вроде берущегося за голову дракончика или держателя для зубочисток, ощущение «я это создал» работает и присутствует. И вот тогда мне и пришло в голову, что хочется собрать свою библиотеку моделей, чтобы печатать что угодно в любую секунду.

Ах да, к сути...


Однажды я проснулся утром и подумал: «А не сделать ли из этого ветерана экспериментов автономного сборщика 3D моделей со всех инторнетов, чтобы тот тихо, без жалоб, подсобирал мне библиотеку на будущее?»

Звучало немного безумно и очень весело. Значит надо делать.


Зачем вообще в 2025 году собирать 3D модели

Для тех, кто счастлив и не шарится по сайтам с моделями: мир STL, OBJ и 3MF выглядит как лист в тетрадке у восьмиклассника. Все в одном месте, но не разберешь, что к чему, зачем и почему оно вообще тут.

Добавим к этому:

  • десятки сайтов

  • реклама

  • платные логины

  • платные скачивания (ничего не имею против и спокойно плачу за качественные модельки по 3 - 10 долларов, но все же!)

  • куча моделей упакована в ZIP

  • половина ZIP пустые, исчезли или побиты

  • у половины моделей "model_1.stl" как название, и угадай что внутри

Все это не хочется отслеживать руками.
Лучше, чтобы делала машина.
Машине не жалко. Машина не устанет.

...In the name of the God-Emperor.
...In the name of the God-Emperor.

Цель: личный автономный мини-Thingiverse

Требования сформировались сами собой:

  1. Краулер обходит сайты (только те, что открыты и разрешены).

  2. Находит потенциальные ZIP и STL.

  3. Скачивает.

  4. Распаковывает.

  5. Валидирует модели (не повреждены ли).

  6. Классифицирует по категориям.

  7. Складывает аккуратно по папкам.

  8. Работает на 100% автономно.

Архитектура

[Crawler] -> pages.db -> [Downloader] -> files -> [Validator] -> [Classifier] -> models/

Ключевые компоненты:

  1. Crawler
    - Обходит seed страницы, вытаскивает ссылки, фильтрует потенциальные загрузки. Seed можно положить или в базу, или прямо в код. На тестах я пошел по второму пути, а на бою выбрал первый.

  2. Downloader
    - Скачивает ZIP и STL.
    - Распаковывает.
    - Проверяет, что внутри (на плечах Downloader только валидация по размеру файла. Задаем любой рэндж и не качаем "нули").
    - Удаляет мусор, кидает полезное в хранилище.

  3. Classifier
    GPT (API token) смотрит файл и генерирует красивое название, категорию, набор тегов. Дополнительная информация склалдывается в meta.json рядом с моделью.

  4. Validator
    Использует trimesh для проверки STL.
    Если файл битый, пустой или представляет собой модель под названием "ничего", он летит в топку.

База на SQLite, потому что:

  • простая

  • надежная

  • не требует сервера

  • переживет что угодно (не всегда, да, но все равно)

  • поддерживает десятки миллионов записей, если ее не кормить мусором

Анти-DDoS меры и этичность

Я решил, что в моем сценарии я хочу вообще не мешать сайтам жить спокойно.

Поэтому в систему встроены элементарные, но важные правила приличия:

  • Ползать медленно.
    Crawler делает паузу между запросами. Не «миллисекунду, потому что мне надо быстрее», а нормальные человеческие 3–5 секунд. Я же не Googlebot.

  • Никаких сотен параллельных потоков.
    Все работает в одном процессе. Это не промышленный скачивальщик. Это домашнее хобби, а не атака.

  • Ограничение глубины обхода.
    Я не пытаюсь залезть на страницы, куда сам сайт не хочет, чтобы я лез. Если ссылка слишком глубокая или не относится к моделям, я туда не хожу.

  • Только открытый контент.
    Никаких обходов логина, paywall или «хитрых запросов». Все ссылки, которые поднимает краулер, доступны анонимно. Если сайт не дает скачивать анонимно — я иду мимо и никаких о��ид и попыток пробить/обойти стену.

  • Никаких попыток выгребать сайт целиком.
    Цель — не стать зеркалом, а собрать личную коллекцию интересных моделей.

  • Корректные User‑Agent и заголовки.
    Ничего маскирующего. Я даже честно отправляю свой User‑Agent, чтобы было понятно, что это бот‑собиратель.

С этим подходом краулер живет тихо, мирно и никому не мешает. За неделю ползания я не получил ни одного бана и ни один сайт не стал отвечать капчей или криками «ты кто вообще такой». Такой результат меня полностью устраивает.

Проблемы с реальными STL файлами или почему 3D модели иногда ведут себя как коты

STL файлы бывают трех типов:

  1. Нормальные.
    Они открываются, печатаются и вообще радуют.

  2. Странные.
    В них 0 полигонов, 0 граней и иногда текст "Created by SomethingFreeEditionUnregistered".
    Я не шучу, такое встречалось много раз

  3. Проклятые (мы все еще сравниваем сущности с котами, не забываем).
    Эти выглядят как нормальные, весят мегабайт, но при попытке загрузить их через trimesh превращаются в ошибку уровня «я не знаю, что это, но это точно не 3D модель».

Стоит понимать: STL бывает в ASCII и binary форматах, и сайты иногда пихают в ZIP такое, что сложно назвать «геометрией».

Именно поэтому у меня обязательный пайплайн:

  • файл скачан

  • если ZIP - распакован

  • каждая STL проходит через trimesh.load()

"Модель" летит в мусор если она:

  • пустая

  • битая

  • вызывает исключение

  • имеет 0 faces

  • состоит из одного треугольника размером с вселенную

  • или просто выглядит подозрительно

Validator стал моим главным героем. Он тихо убирает весь мусор и оставляет только то, что действительно имеет смысл печатать.

Как GPT помогает классифицировать модели и почему это невероятно удобно

Я пробовал вручную разбирать модели по категориям.
Хватило примерно 7 минут, чтобы понять, что это пытка.
Названия вроде model_1_final_fixed_v3.stl не помогают вообще.

Поэтому я сделал классификатор на GPT API, который делает сразу несколько вещей:

  1. Нормализует название модели
    Если страница называлась "MyDragonNew2023VFinalFixed", GPT выдаст человеческое: Articulated Cute Dragon.

  2. Определяет категорию
    У меня набор основных категорий (на момент написания статьи): animals, toys, gadgets, household, cosplay, decor, mechanical, figures, parts.
    GPT безошибочно (ладно, попадание где-то 98%) кладет модель туда, куда надо.

  3. Генерирует теги
    Это важно для поиска. Модель «кубик» может иметь теги: ["cube", "parametric", "math", "geometry", "calibration"]

  4. Пишет краткое описание
    Иногда страница с моделью выглядит так: "Here is a model. Enjoy."
    GPT превращает это в нормальный текст, который можно прочитать через 5 лет и вспомнить, зачем и что это.

Философская часть

Мини ПК служил много лет.

Он пережил прокси сервер, VoIP эксперименты, Lineage 2 сервер, архив фильмов, домашний торрентовый ад, и дошел до момента, когда он стал полностью автономной системой, которая сама ползает по интернету, сама ищет STL, сама сортирует, сама валидирует, сама классифицирует.

Мне нравится думать, что я подарил ему вторую жизнь.

Он заслужил.

Комментарии (0)