Skip to content
Владимир edited this page Mar 27, 2024 · 30 revisions

Тут все что может вам понадобится

https://drive.google.com/drive/folders/1hGODDb3OlHzAL7jqJbCW01ThdKKgbV9L

Как устроен парсер для MangaWatcherX

1) Поля заголовка парсера

  • id [long] - идентификатор сайта (пережиток далёкого прошлого но от него пока не отказаться),

  • version [string] - версия данного файла, приложение будет брать наибольшую версию или локальную,

  • title [string] - Название парсера [обязательно],

  • host [string] - основной хост сайта [обязательно],

  • public_link [string] - ссылка на каталог манг сайта (для пользователя)можно просто указать адрес сайта сайт,

  • folder [string] - название каталога для где будут храниться манги [обязательно],

  • name [string] - короткое название [не обязательно],

  • language [string] - код языка сайта ISO 639-1 https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes,

  • chapters_order [bool] - порядок сортировки глав на странице (true - 1,2,3 false: 501,500,499...), по умолчанию true

  • time_invalidate [long] - [не используется].

  • encoding string] - указывает какую кадировку использует сайт это чаше всего utf-8 или Windows-1251.

  • catalog_link [string] - ссылка на файл каталога манг в формате protobuf(с версии 3.1.6.0 убрано так как устаревшей формат), можно использовать и в формате sqlite ток для этого добавьте если хотяте использовать тип sqlite"file_type": "sqlite",.

  • self_link [string] - ссылка на парсера в формате .json.

  • self_link2 [string] - ссылка на парсера в формате .json отвечает за альтернативный источник загрузки парсера (проверяется версия парсера) добавлено начиная с версии 3.1.4.12;

  • icon_link [string] - ссылка на иконку парсера ,

  • "author": {"name": "Кто делает парсер","email": "Адрес для связи "},

  • old_ids": [string] - Перенести мангу с одного id на новый id доступно В версии 3.1.4.14 и выше !

  • old_sites": [string] - Исправить ссылки на мангу если сайт изменил адрес то тут пишем старый адрес сайта ! доступно В версии 3.1.4.14 и выше !

  • Добавлено - теперь Referer всегда задается для ссылок без него (если он есть в [manga_complete].[headers]);
  • Добавлено - [http_values] - добавлены параметры задержки скачивания данных по http в милисекундах (краткое описание: одиночный параметр [connect_sleep] - число больше 0 (по умолчанию 300, добавляется случайное число от -50 до 50), пара параметров [connect_sleep_min] (число больше 0) и [connect_sleep_max] (число больше [connect_sleep_min]) задают случайное число задержки, если указано, то перекрывает [connect_sleep]);

2) Онлайн поиск по сайту по ключевому слову

manga_search_complete

  • search_link [string] - ссылка на поисковый запрос на сайте ,

сформированных как search_link + $query$ + $page$

  • $query$ - Выдает текст который ишет пользователь 	
    
  • $page$ - ходит по страницам от 1-99
    
  • sufix [string] - текст вставляемый после результата.

  • query_type [string] - тип запроса GET или POST,

  • add_manga [add_href] - парсим каждую страницу и чтобы получить объекты с именами и ссылками на манги { title,summary, link, cover, uniq };

пример использования

"manga_search_complete": {		
  "search_link": "http://tl.rulate.ru/search/index/t/$query$/cat/0/s_lang/0/t_lang/0/sort/4/n_chapters//Book_page/$page$",
		"query_type": "GET",
		"add_manga": {
			"next": "<p><a href='/book/",
			"link": {
				"token1": "href='/book/",
				"token2": "'>",
				"replace": {
					"prefix": "http://tl.rulate.ru/book/"
				}
			},
			"title": {
				"skip": "href='",
				"token1": "'>",
				"token2": "</"
			},
			"uniq": {
				"skip": "href='",
				"token1": "book/",
				"token2": "'>"
			},
			"cover": {
				"skip": "href='",
				"token1": "src='",
				"token2": "'",
			"replace": {
					"prefix": "http://tl.rulate.ru/"
				}
			}
		}
	},

3) Функция авторизации

пока пусто я в этом плохо понимаю но пример оставлю рабочий пример Rulate

"authorization_complete": {
		"logo": "https://tl.rulate.ru/i/favicon.ico",
		"registration": "https://tl.rulate.ru/register",
		"expires": 31536000,
        "is_redirect": true,
		 
		"values": {
		    "login[login]": {
				"label": "Логин",
				"hint": "Введите свой логин с сайта Rulate!",
				"kind": "text"
			},
			"login[pass]": {
				"label": "Пароль",
				"hint": "Введите свой пароль с сайта Rulate!",
				"kind": "password"
			},
			"mature":{
			"forward":"cookie",
			"value":"c3a2ed4b199a1a15f5a5483504c7a75a7030dc4bi%3A1%3B"
			}
		},
"request": {"method": "post","url": "https://tl.rulate.ru/" },
"response_check": { "headers": {"Set-Cookie": "@%22login"}
  }
},


добавление своих печенек

"values": { "cookie_name": { "forward": "cookie", "value": "cookie_value"} } cookie_namе - имя самой печеньки cookie_value - значение остальное не трогать values - это блок, в который это все пихать;

  • authorization_complete - expires_check - cookies_value [массив строк] -если значение куки из списка изменилось, то выполняется повторная авторизация;

4) Методы формирования БД манги для создания каталога

manga_list_complete - функция получения списка манги ( title, link, uniq );

  • iterator [string|array|get_iterator] - формирование списка страниц каталога манг. Т.е. формируется список страниц из которые подлежат обходу;
  • add_manga [add_href] - парсим каждую страницу и чтобы получить объекты с именами и ссылками на манги { title, link, uniq };

Пример работы с сайта mangachan

"manga_list_complete": {
		"iterator": {
			"base_url": "https://manga-chan.me/mostfavorites?offset=",
			"append_nums": { "from": 0, "to": 16260, "step": 20, "last_page": {"before": ">>>", "token1": "<a href='?offset=", "token2": "'"} }
		},
		"add_manga": {
			"next": "<div class=\"content_row\"",
			"link":  { "token1": "href=\"", "token2": "\"" },
			"title": { "token1": "title=\"", "token2": "\"" },
			"cover": { "token1": "img src=\"", "token2": "\"" }
		},
		"rating_auto_inc": {
			"start": "20000",
			"inc": -1
		}
	},
    • rating_auto_inc - сортировать по рейтингу как на страницах поиска [не обязательно];

пример использования


"rating_auto_inc": {
            "start": 50000,
            "inc": -1
        }
    • link_corrector - Замена данных при добавлении по ссылке

Для самого приложения MangaWatcherX. начиная с версии "3.1.6.4"

Так же внимание, так как корректоры это массив то каждый корректор добавит одну ссылку после замены и затем ссылка проверяется и связывается с парсером и указывается как источник для манги

пример использования


"link_corrector": [
     {
           "match": "remanga.org/manga/",
           "text": "api.remanga.org/api/titles/"
            }
   ],

Рабочие примеры в парсерах
MangaDex, NewManga, Remanga

PS: поддерживаются регулярные выражения.

5) manga_complete - Функция формирования полной информации по манге;

  • Если вам вдруг надо 2 разных manga_complete не проблема, ниже приведен пример "condition": "тут пишем на что будет срабатывать к примеру на слово Том",
    "condition": "",обязательно так как он выступает по умолчанию

пример использования

"manga_complete":[
{"condition": "Альтернативное",
"title": {"skip": "Русское:","token1": ">","token2": "</"}
},
{"condition": "",
"title": {"skip": "Английское:","token1": ">","token2": "</"}
}
],
  • title [get_string] - название манги [обязательно];

  • uniq [get_string] - уникальное значение части пути для формирования папки [не обязательно но желательно].

  • author [get_string] - автор манги;

  • summary [get_string] - описание манги;

  • cover [get_string] - обложка манги;

  • rating [get_string] - рейтинг манги (как показала практика можно начхать на это);

  • need_auth [detect] - если для скачивания и для чтения нужна авторизация;

  • need_auth_genres [detect] - то же что и need_auth, но проверяет по жанрам;

  • need_auth_tags [detect] - то же что и need_auth, но проверяет по тегам;

  • is_mature [detect] - манга для взрослых; Пример

 "is_mature": {
            "values": [
                ">Для взрослых 18+<",
                ">Для взрослых 16+<",
                ">Сэйнэн<",
                ">Яой<"
            ]
        },
  • read_dir [enum_detect] - направление чтения покажет пользователю как читать
    • left_to_right - слева на право,
    • right_to_left - справа на лево;

Пример

"read_dir":  {
"right_to_left": "href=\"/type/Манга\"", 
"left_to_right": "href=\"/type/Манхва\"" 
},
  • status [enum_detect] - статус манги
    • unknown - неизвестен,
    • ongoing - продолжается,
    • complete - завершена,
    • single - сингл,
    • licensed - лицензирована/заблокирована,
    • empty - пустая.

Пример Нахождения статуса для манги:

"status": { 
	"complete": { 
		"start" : "<b>Перевод:</b>",
		"end" : "</p>",
		"values" : ["завершен", "Переведена", "Сингл"]
	},
	"ongoing": {
		"start" : "<b>Перевод:</b>",
		"end" : "</p>",
		"value" : "продолжается"
	},
	"single" : "<b>Сингл</b>",
	"default" : "ongoing"
}
  • chapters_from_page [get_string] - загружать главы с другой страницы, начиная с версии 3.1.4.12 к chapters_from_page добавлен "next": [get_string] это ссылка на следующую страницу, то есть он последовательно будет ходить по страницам и собирать главы, например на многих сайтах используется по страничный вывод списка глав, для них список глав можно получать со страницы главы, там всегда есть выпадающий список всех глав.

  • chapters_from_pages [get_array] - парсит страницы с одной страницы, а потом главы из того что достал из одной страницы.

  • add_genre [get_string] - добавляем все жанры по одному,

  • add_genres [get_array] - добавляем жанры списком,

  • add_tag [get_string] - добавляем все Тэги по одному,

  • add_tags [get_array] - добавляем Тэги списком,

  • "content_type": {"default": "light_novels"}, - указать если вы хотите чтоб читалка переключилась на чтения книг fb2,epub,txt

  • add_chapter [add_href] - создаём список глав манги.

Начиная с версии 3.1.5.17 в add_chapter добавлено
Добавлено - Парсеры -[manga_complete]-[add_chapter]-[lang]-тип [get_string],
позволяет определить язык главы (выполняется после [link] и до [title]), 
вернет две строки короткую форму и форму после replace;

-добавлены переменные
%%chapter_lang%% - короткая форма и 
%%chapter_lang_replace%% - после replace;

Пример как это работает 
https://github.com/veopot/mwx-json/blob/main/parsers/mangadex.json

Добавлено в само приложение Manga Watcher X - Манга - Список глав - фильтрация по языкам глав с сохранением состояния,
если язык не определен, то фильтрация недоступна;

6) chapter_complete - функция формирования списка страниц главы манги.

  • "add_numeration": true, - добавляем к сканам нумерацию при скачивание сканов ;

  • add_page [get_string] - добавляем страницы по одной;

  • add_pages [get_array] - добавляем страницы списком;

  • add_images [get_array] - добавляем страницы списком, ссылками сразу на файлы сканов если использовать это то можно не использовать "page_complete" так как вы уже указали ссылки на сканы пример ниже;

  • use_servers_only [bool] - использовать только зеркала [add_servers], исключает ссылку [add_chapter] - [link] при добавлении страниц;

  • add_servers [get_array] - если у зеркала есть путь, то путь остается, а файл добавляется дополнительное значение [next];

  • images_url [get_string] - ;

  • postfix [string] - ;

  • prefix [get_string] -добавляет вставляемый перед результатом, ;

  • sufix [get_string] - добавляет вставляемый после результата;

  • remove_first [bool] - удаляем первую страницу из списка;

  • remove_last [bool] - удаляем последнюю страницу из списка;

чаще всего remove_firstи remove_last используется чтоб удалить рекламные картинки
как любят некоторые сайты пихать их в читалку чаще иностранные !

примечание "start" и "end" обязательно использовать !

Совет можно использовать регулярные выражения чтоб собрать правильно разбитую ссылку на скан json "replace" : { "match" : "(.*?)','(.*?)',\"(.*?)\".*", "text" : "$2$1$3" }

Пример

"chapter_complete": {
	    "add_numeration": true,
	    "headers": {
			"Accept": "*/*",
			"Referer": "https://remanga.org/",
			"Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7"
		},
	"add_images": {
			"start": "content",
			"token1": "link\":\"",
			"token2": "\"",
			 "end": "]"
		}
	},

7) page_complete - функция извлечения ссылки на файл скана страницы манги;

  • image [get_string] - извлечение ссылки на файл скана страницы;

Пример

"page_complete": {
		"image": { "skip": "<div class=\"maincontent_mr\">", "token1": "<img src=\"", "token2": "\"" }
	},

8) test - функция тестирования данного файла;

  • proc [string] - функция которую будем тестировать;

  • link [string] - ссылка на мангу/главу/страницу для формирования тестируемого объекта;

  • assert - данные с которыми будем сравнивать специфичные для тестируемых функций;

    Сравнение значений

    • Проверка текстовых значений

      • равно "author" : "OKU Hiroya"
      • регулярными выражениями, первый символ @ "image" : "@^http://\\w*\\.manga24\\.ru/manga/gantz/\\d*/\\d*\\.(png|jpg|jpeg)$"
    • Проверка числовых значений

      • равно = "mangas_count" : "=460"
      • не равно != "pages_count" : "!=20"
      • больше > "mangas_count" : ">460"
      • меньше < "genres_count" : "<7"
      • больше или равно >= "mangas_count" : ">=460"
      • меньше или равно <= "genres_count" : "<=7"

Пример

"test": [
		{
			"proc" : "manga_list_complete",
			"assert" : {
				"mangas" : [
					{ "title" : "Gantz",  "link" : "http://manga.animea.net/gantz.html" },
					{ "title" : "Naruto", 
						"link" : "http://manga.animea.net/naruto.html",
						"uniq" : "naruto.html"
					}
				],
				"mangas_count" : ">12500"
			}
		},
		{
			"proc" : "manga_complete",
			"title" : "Bleach", 
			"link" : "http://manga.animea.net/bleach.html", 
			"assert" : {
				"author" : "KUBO TITE",
				"cover" : "http://s.animea.net/manga/thumbs200x275/42.jpg",
				"summary" : "@^(Ichigo Kurosaki has)",
				"genres" : "@action",
				"status" : "licensed",
				"rating" : ">=70",
				"genres_count" : ">=6"
			}
		},
		{
			"proc" : "chapter_complete",

			"link" : "http://manga.animea.net/gantz-chapter-383.html",
			"title" : "Gantz 383: Endpoint", 
			"assert" : {
				"pages" : [
					{ "link" : "http://manga.animea.net/gantz-chapter-383-page-4.html" },
					{ "link" : "http://manga.animea.net/gantz-chapter-383-page-31.html" }
				]
			}
		},
		{
			"proc" : "page_complete",
			"link" : "http://manga.animea.net/gantz-chapter-383-page-31.html",
			"assert" : {
				"image" : "http://162.210.197.229/b/395%2F383%2Fimg_31_59390.jpg"
			}
		}
	]

9) Типы полей

Простые типы

  • string - просто текстовое поле;
  • array - массив текстовых полей;
  • int - число в формате INT;
  • long - число в формате LONG;
  • bool - булевое поле;

Базовые методы парсера сайтов

replacer - замена подстроки

  • match [string] - заменяемый текст или регулярное выражение,
  • text [string] - вставляемый текст,
  • prefix [string] - текст вставляемый перед результатом,
  • sufix [string] - текст вставляемый после результата.

Пример

"replace" : { 
	"match" : "\\?.*", 
	"text" : "" 
}

"replace": [ 
{"match": "<.*>", "text": ""},
{"match": "Главы", "text": "Глава"}
] 
А вот так можно за раз использовать сразу 2  replacer  

link_corrector - Заменяет в URL на указанную часть (должно работать в manga_complete но возможно и в других местах будет работать но не уверен)

  • match [string] - заменяемый текст,
  • text [string] - вставляемый текст,

Пример

"link_corrector": [    
{ "match" : "https://remanga.org/manga/", 
"text" : "https://api.remanga.org/api/titles/" }   ], 

Mangawatcherx Поддерживает такие переменные в парсере

"path" -> "/related/17250-so-what-glava-0.html" "host" -> "https://hentai-chan.pro" "page" -> "17250-so-what-glava-0.html" "url" -> "https://hentai-chan.pro//related/17250-so-what-glava-0.html?offset=150" "pagename" -> "17250-so-what-glava-0"

Пример сслыка на мангу https://hentai-chan.pro//related/17250-so-what-glava-0.html?offset=150

Пример 1:

"replace" : {"prefix": "%%host%%%%path%%" } вот так без косой

Пример 2: "replace":[ {"prefix": "http://site.ru"}, {"sufix": "%%path%%/"}, { "match": "/pages", "text": "/" }, { "match": "/v3/chapters/", "text": "/" } ]

get_string - получение текстового значения (находящегося между token1 и token2) из документа

  • after [string] - курсор устанавливается перед найденным выражением,
  • skip [string] - курсор устанавливается после найденного выражения,
  • before [string] - выражение token1 ищется перед данным выражением,
  • tag [string] - ВНИМАНИЕ это не поиск по тегу! это позиционирование курсора по началу тега,
  • token1, token2 [string] - выражения между которыми находиться результат [обязательно],
  • replace [replacer] - конвертирование результата,
  • details [bool] - логгирование [debug].

Пример

author: { 
	"after": "<a href=\"/list/author/", 
	"token1":"\">", 
	"token2": "</a>" 
}

detect - проверка наличия выражения в документе

  • start [string] - выражение начала окна,
  • end [string] - выражение окончания окна,
  • pattern [string] - искомое выражение,
  • patterns [array] - массив искомых выражений.

enum_detect - специфический набор detect'ов с возможностью указать значение по умолчанию - default

Пример Нахождения статуса для манги:

"status": { 
	"complete": { 
		"start" : "<b>Перевод:</b>",
		"end" : "</p>",
		"values" : ["завершен", "Переведена", "Сингл"]
	},
	"ongoing": {
		"start" : "<b>Перевод:</b>",
		"end" : "</p>",
		"value" : "продолжается"
	},
	"single" : "<b>Сингл</b>",
	"default" : "ongoing"
}

get_array - получение списка строк. Если указан split то первое выражение найденное между token1 и token2 будет разделено по выражению split, Если split не указан то список строк будет формироваться вырезанием всех найденных строк между token1 и token2.

  • start [string] - выражение начала окна,
  • end [string] - выражение окончания окна,
  • after [string] - выражение смещение курсора,
  • split [string] - выражение по которому нужно нарезать найденное значение,
  • token1, token2 [string] - выражения между которыми находиться результат [обязательно],
  • replace [replacer] - конвертирование результата,
  • details [bool] - логгирование [debug];

Пример 1 Результатом будет список всех элементов перечисленных через запятую в элементе "span".

{ 
"split": ",",
"token1": "Жанр:</b>",
"token2": "</"
},

Пример 2 Результатом будет список всех элементов списка.

{
	"start": "<ul>", 
	"end": "</ul>", 
	"token1": "<li>", 
	"token2":"</li>"
}

add_href - Получение списка ссылок на манги/главы

title - название, 
link - ссылка, 
uniq - уникальное значение части пути для формирования папки **[не обязательно]**.
  • start [detect] - выражение начала окна,
  • end [detect] - выражение окончания окна,
  • next [detect] - выражение смещения курсора поиска,
  • link [get_string] - получение ссылки,
  • title [get_string] - получение названия,
  • uniq [get_string] - получение уникального идентификатора, если не указан то формируется из link последний сегмент пути,
  • details [bool] - логгирование [debug].

get_iterator - итератор значений, служит для формирования списка ссылок.

  • base_url [string] - базовый url,
  • append_nums - описание цикла для получения списка url, сформированных как base_url + %index% + sufix
    • from [int]
    • to [int]
    • step [int]
    • sufix [string]
  • append_array [array] - массив значений для формирования списка url, сформированных как base_url + %value%

Пример Формируем список ссылок вида: https://mintmanga.live/list?offset=0, https://mintmanga.live/list?offset=60, https://mintmanga.live/list?offset=120...

"iterator": {
	"base_url": "https://mintmanga.live/list?offset=",
	"append_nums": { "from": 0, "to": 6300, "step": 60 }
},

Начиная с Версии 3.1.6.1

  • Добавлено - теперь Referer всегда задается для ссылок без него

(если он есть в [manga_complete].[headers]);

Берутся все заголовки из [manga_complete].[add_chapter].[headers] Если нету [manga_complete].[add_chapter].[headers], то берется [manga_complete].[headers]


10) Отладка

  • nigma.jar - консольное java приложение для отладки парсера
  • test, test.bat - запускаемые скрипты (обертки над nigma.jar) для MacOs и Windows
  • site_parsers.sublime-project - заготовка проекта для SublimeText упрощающая процесс отладки

Приложение на выходе выдает отчет о прохождении тестов + логги работы если они включены (details : true) для всех методов. Чтобы вывести результаты работы методов нужно запускать приложение с одинм из ключей: [manga_list_complete], [manga_complete], [chapter_complete], [page_complete].

Запуск тестов для сайта manga24

$./test manga24.json

configuaration ok
1. success( 0,4s)
2. disabled( 0,0s)
3. manga_list_complete .............success(10,6s)
4. manga_complete success( 0,7s)
5. chapter_complete success( 0,1s)
Count: 5
Success: 5
Error: 0
Time: 11,8s
Result: 100,0%

Вывод результатов работы метода "chapter_complete" в консоль

$java -jar nigma.jar manga24 [chapter_complete] http://manga24.ru/goodending/003/

Chapter link: http://manga24.ru/goodending/003/
Chapter complete ok!
{
    "first_three_pages": [
        {"image": "http://img7.manga24.ru/manga/goodending/003/001.jpeg"},
        {"image": "http://img7.manga24.ru/manga/goodending/003/002.jpeg"},
        {"image": "http://img7.manga24.ru/manga/goodending/003/003.jpeg"}
    ],
    "link": "http://manga24.ru/goodending/003/"
}
time: 280ms