Разработка модуля парсера для Melon максимально унифицирована и абстрагирована. Из коробки поставляется множество инструментов, которые почти наверняка вам пригодятся.
Конечно, одним из важнейших методов обучения является так называемое обучение «по примеру». Вы можете ознакомиться с эталонными реализациями парсеров в наших репозиториях.
Для лучшего понимания терминологии Melon рекомендуется ознакомиться с основными определениями, введёнными в процесс разработки.
| Термин | Определение |
|---|---|
| Временный каталог парсера | Директория с относительным путём Temp/{PARSER}. Используется для хранения временных файлов, необходимых парсеру, или загрузки изображений без спецификации пути. |
| Домашний каталог парсера | Директория с относительным путём Parsers/{PARSER}. Также под этим может пониматься корень подмодуля Git. |
| Дополнение контента | Процесс получения и записи в структуры описания глав контента (слайдов или абзацев). |
| Формат описательного файла | Набор правил о ключах и типах их значений в описательном файле JSON. Подробнее здесь. |
| Коллекция | Текстовый файл Collection.txt во временном каталоге парсера, содержащий список алиасов тайтлов, разделённых символом новой строки. |
| Описательный файл | Файл с расширением JSON, содержащий в себе все данные о конкретном тайтле в соответствии с одним из поддерживаемых форматов. |
| Кастомные параметры | Дополнительные настройки парсера, не поддающиеся унификации, и определяемые под ключём custom в settings.json. |
| Ветви контента | Наборы глав, часто имеющие пересечения между собой, прошедшие отличающуюся обработку (например, ветви перевода или редактуры разных издательств). |
| Заголовок главы | Полная подпись главы, включающая нумерацию, типизацию и названия, предоставляемая источником (например, Том 1. Эпилог: Название). |
Melon поддерживает два типа контента: манга и ранобэ.
Воспользуйтесь командой melon init -p {PARSER} --content {TYPE} для автоматической генерации всех необходимых файлов парсера выбранного типа контента, где PARSER – название парсера, а TYPE – тип контента (manga, ranobe).
Important
Название парсера должно содержать только символы латинского алфавита в нижнем регистре и цифры!
Будет создан каталог Parsers/{parser_name}, в котором инициализируется Git-репозиторий и появятся следующие файлы:
По умолчанию игнорируется кэш Python.
Внутри находится класс Parser, унаследованный от соответствующего типа, внутри которого необходимо выполнить реализацию парсера, не нарушая API.
Заполненные автоматически поля не рекомендуется редактировать вручную.
Следует применять семантическое версионирование, но вместо конретного значения можно указать директивы:
$last_git_tag– берёт версию из последнего тега репозитория парсера;$from_parser:{PARSER}– берёт версию определённого парсера (например для клонов сайтов с разным контентом).
Здесь следует указать ссылку на источник, парсер которого вы добавляете, а также то, как ваш парсер обрабатывает параметры коллекционирования и какие требует кастомные параметры.
Определите кастомные параметры в секции custom. Не забывайте описывать их в README.md.
При изменении значений в остальных секциях будут переопределены параметры по умолчанию конкретно для вашего парсера.
Механизм реализации функционала в модулях Melon основан на переопределении публичных и защищённых методов. Вы можете наполнять их по своему желанию, но принимаемые аргументы и возаращаемые значения являются обязательным условием корректного взаимодествия с парсером. Это также создаёт гибкость, поскольку не ограничивает разработчика каким-то определённым спектром библиотек.
Для удобства ознакомления в сгенерированном main.py будут находиться все доступные для переопределения методы, но те из них, которые не требуют изменения для функционирования парсера, следует удалить.
| Метод | Описание |
|---|---|
| _PostInitMethod | Вызывается в конце __init__() класса. Используйте его как замену, чтобы не переопределять конструктор. |
| _InitializeRequestor | Инициализирует оператор запросов. Переопределите для использования собственных конфигураций. Изменения также будут подхвачены во всех зависимых модулях (например, при сборке контента). |
| Метод | Описание |
|---|---|
| amend | Обязательный метод. Дополняет главы данными о слайдах или абзацах. |
| amend_postprocessor | Обрабатывает главу после завершения операции её дополнения (например, для очистки временных данных, прикрепляемых к структуре главы на уровне словаря). |
| collect | Просит парсер собрать список алиасов по трём заданным опциям: period – период сбора обновлений в часах; filters – строка для дополнительных способов фильтрации (обычно параметры запроса); pages – количество страниц каталога, с которых нужно получить данные. Парсер может не поддерживать все опции сразу. |
| get_slug | Извлекает из переданной строки алиас тайтла. Например, служит для парсинга тайтлов по полным ссылкам. |
| image | Скачивает изображение во временный каталог парсера. |
| parse | Обязательный метод. Выполняет множество действий, обычно выносимых в приватные методы, целью которых является подробнейшее заполнение полей структуры self._Title, а также получение сведений о ветвях контента. Подробнее о структуре здесь. |
Для работы с CLI, логами, временными файлами и настройками предоставляются так называемые порталы и объектные имплементации, позволяющие выводить и использовать данные в унифицированном формате. Каждый парсер на разных этапах своей работы может использовать самодокументируемые порталы, определённые в объекте self._Portals.
Порталы совмещают вывод в консоль и доступ к логам, что позволяет обрабатывать их при помощи файлов конфигурации (см. Настройка логов).
В некоторых случаях парсер также обязан выбрасывать исключения, которые используются Melon для корректной обработки процесса получения контента. Порталы ошибок по умолчанию выбрасывают соответствующие исключения, но такое поведение можно отключить, передав соответствующий аргумент.
Парсеру может понадобиться хранить какие-либо сторонние файлы, тебующиеся обработчику контента (например Collection.txt), и, чтобы не засорять домашний каталог, доступен портал для лёгкого получения доступа к директории Temp. Для каждого парсера внутри данной директории создаётся свой подраздел.
# Получение пути к каталогу временных файлов парсера.
Path = self._Temper.parser_temp
# Скачивание изображения во временный каталог парсера.
Filename = self._ImagesDownloader.temp_image("https://link_to_image.png")Доступ к настройкам парсера осуществляется через абстракцию self._Settings, проверяющую валидность данных.
self._Settings.common.delay
self._Settings.proxies[0].to_string()
self._Settings.filters.text.clear("Some text.")
self._Settings.custom["key"]Во время разработки парсеров часто приходится использовать похожие или вовсе одинаковые алгоритмы, но при этом требующие тонкой настройки и точечного расширения функционала. Melon предоставляет набор инструментов, который может стать полезным в некоторых ситуациях.
При работе с некоторыми тайтлами может возникнуть необходимость обрабатывать ключевые слова, например при парсинге нумерации из строки типа «Том 1. Глава 1. Название» слова Том и Глава являются ключевыми и используются внутренними системами Melon для автоматического извлечения данных при обработке ранобэ. Вы можете переопределить их для корректной работы.
# Если словарь доступен, он загрузится при установке языка.
WordsDictionary = self._Title.set_content_language("rus")
# Позднее словарь также доступен через свойство тайтла.
WordsDictionary = self._Title.words_dictionary
# Все ключевые слова приводятся к нижнему регистру.
WordsDictionary["art"] = "Иллюстрации"
# Возможно хранение собственных ключевых слов.
WordsDictionary.additional_data["custom"] = "Ключевое слово"Источники контента не всегда предоставляют удобные способы получения данных наподобие номера тома и главы, в связи с чем периодически возникает необходимость парсить заголовки глав. Для этого вы можете использовать парсер заголовков, поддерживающий расширение через наследование.
from Source.Core.Base.Formats.Ranobe import ChapterHeaderParser
# Парсинг заголовка с использованием словаря ключевых слов.
ParsedHeader = ChapterHeaderParser("Том 1. Эпилог: Название", self._Title.words_dictionary).parse()
# Доступ к данным.
ParsedHeader.volume
ParsedHeader.number
ParsedHeader.type
ParsedHeader.nameАлгоритм базовой сортировки глав основан на их нумерации, но не всегда это наилучшее решение. Если необходимо реализовать собственный сценарий, вы можете унаследовать объект от Branch и переопределить метод sort(). Для создания ветвей в дальнейшем используйте собственный класс.
Сортировка отключается флагом -no-sort.
Как и любой хороший Open Source проект, Melon имеет ряд рекомендаций по чистоте кода парсеров, а также взаимодействию модулей и их структуре. Следуя им, вы однозначно повысите качество интеграции своего парсера с системой.
| Номер | Описание |
|---|---|
| 1 | Парсер должен выполнять все файловые операции внутри своих рабочих директорий, определённых настройками, а также во временном каталоге. Это семантически изолирует файловую систему и поддерживает чистоту. |
| 2 | Все запросы парсера к источникам должны поддерживать проброс через прокси-сервер, что важно для регионов, подпадающих под сетевые ограничения. |
| 3 | Следует по возможности использовать только порталы CLI/логов для общения с пользователем и унификации интерфейса (к расширениям это относится в меньшей степени). |
| 4 | Ограничивайте частоту запросов к серверу: это позволяет не только избежать блокировок, но и не создаёт избыточную нагрузку на источник контента, что является хорошим тоном. |
| 5 | Всегда указывайте в описательных файлах авторов и переводчиков, если таковые известны. Уважайте чужой труд. |
| 6 | Парсер должен опираться на предоставляемые Melon методы, порталы, имплементации и абстракции. Это избавляет вас от изобретения велосипеда и позволяет длительное время поддерживать парсер в актуальном состоянии, а также автоматически получать исправления и улучшения. |
| 7 | Домашний каталог парсера должен являться неизменяемым. Все настройки определяются в Configs/{PARSER}/settings.json, а временные файлы в Temp/{PARSER}. |
| 8 | Весь сторонний функционал, не использующийся для реализации стандартных функций Melon, должен быть вынесен в расширения (см. Поставка расширений). |
Такие вещи, как CLI, логи, протоколы общения модулей, а также работа с данными ложатся на плечи Melon. Он следит за валидностью, стилистикой и иногда корректностью рабочего процесса и выходных данных. Предоставив парсер и правильно его настроив, вы можете использовать его так же непринуждённо, как и встроенные модули.