Package: anicli_api
# anicli-apiПрограммный интерфейс набора парсеров аниме с различных источников.Присутствует поддержка sync и async методов с помощью `httpx` библиотеки.Парсеры работают на REST-API (если у источника есть доступ) или если такой интерфейсотсутствует, то с помощью parsel, chompjs, jmespath, regex библиотек.# install`pip install anicli-api`# OverviewСтруктура проекта- source - наборы модулей для извлечения информации об аниме тайтлов из источников- player - наборы модулей для извлечения прямой ссылки на видеоПодробнее про `source` и `player` смотрите ниже.```anicli_api├── base.py - базовый класс модуля-парсера├── _http.py - предварительно сконфигурированные классы httpx.Client и httpx.AsyncClient├── _logger.py - логгер├── player - модули получения ссылок на видео│     ├── __template__.py - шаблон модуля PlayerExtractor│     ├── ...  ready-made модули│     ...├── source - модули парсеров с источников│     ├── parsers/... автоматически сгенерированные парсеры html страниц│     ├── __template__.py - шаблон для экстрактора│     ├─ ... ready-made парсеры│     ...└── tools - прочие модули```Схематичный принцип работы модуля из директории `source`префикс `a_` обозначает асинхронный метод```mermaidflowchart TDE[Extractor] -->|"search(<QUERY>) | a_search(<QUERY>)"| S(Search)E -->|"ongoing() | a_ongoing()"| O(Ongoing)O -->|"get_anime() | a_get_anime()"| A[Anime]S -->|"ongoing() | a_ongoing()"| AA -->|"get_episodes() | a_get_episodes()"|Ep[Episode]Ep -->|"get_sources() | get_sources()"|So[Source]So -->|"get_videos() | a_get_videos()"|V[Video]```# quickstart```pythonfrom anicli_api.source.animego import Extractorfrom anicli_api.tools import cliif __name__ == '__main__':cli(Extractor())```> Этот модуль реализован для простого ручного тестирования модулей и "имитирует" потенциальное настоящее приложениеПример своей реализации```pythonfrom anicli_api.source.animego import Extractor  # can usage any sourcedef _print_to_rows(items):print(*[f"{i}) {r}" for i, r in enumerate(items)], sep="\n")if __name__ == "__main__":ex = Extractor()print("PRESS CTRL + C for exit app")while True:results = ex.search(input("search query > "))if not results:print("Not founded, try again")continue_print_to_rows(results)anime = results[int(input("anime > "))].get_anime()print(anime)episodes = anime.get_episodes()_print_to_rows(episodes)episode = episodes[int(input("episode > "))]sources = episode.get_sources()_print_to_rows(sources)source = sources[int(input("source > "))]videos = source.get_videos()_print_to_rows(videos)video = videos[int(input("video > "))]print(video.type, video.quality, video.url, video.headers)```Также, можно использовать отдельно экстракторы видео> Эти модули минимально реализуют получение ссылок на видео с минимальными метаданными не стремиться> стать заменой yt-dlp```pythonimport asynciofrom anicli_api.player.sibnet import SibNetasync def main():videos = await SibNet().a_parse(URL)print(*videos)if __name__ == '__main__':URL = 'https://video.sibnet.ru/shell.php?videoid=432356'print(*SibNet().parse(URL))# asyncio too!asyncio.run(main())```С asyncio аналогично, но **все** методы получения объектов имеют префикс `a_`:```pythonimport asynciofrom anicli_api.source.animego import Extractor # или любой другой источникasync def main():ex = Extractor()prompt = input("search query > ")# a_ - async prefix.# simular in Ongoing, Anime, Episode, Source, Video objectsresults = await ex.a_search(prompt)print(*[f"{i}) {r}" for i, r in enumerate(results)], sep="\n")if __name__ == '__main__':asyncio.run(main())```# source description- name - имя модуля- type - тип источника получения данных.- **NO** - неофициальный (парсинг html документов и запросы недокументированным API методам)- **YES** - официальный (rest-api)- note - примечания- dubbers - тип озвучек.- many - от различных авторов.- subtitles - только субтитры.- author - своя| name           | url                        | official api | dubbers           | note                                                                                                                   ||----------------|----------------------------|--------------|-------------------|------------------------------------------------------------------------------------------------------------------------|| animego        | https://animego.org        | NO           | many              | источники kodik, animego, не работает на IP отличных от СНГ                                                            || animania       | https://animania.online    | NO           | many              | источник kodik, не работает на IP отличных от СНГ                                                                      || animejoy       | https://animejoy.ru        | NO           | subtitles         | **имеет cloudflare**, требуется реализация обхода или предварительное получения cookies и headers, много источников    || sovetromantica | https://sovetromantica.com | NO           | subtitles, author | не на все тайтлы есть видео, у себя хостят                                                                             || anilibria      | https://anilibria.tv       | YES          | author            |                                                                                                                        || animevost      | https://animevost.org      | YES          | author            |                                                                                                                        || jutsu          | https://jut.su             | NO           | author            | Один вид озвучки. Сжатый 1080. (DEV NOTE): запуск видео зависим от используемого user-agent заголовка в API интерфейсе |# players description> Требует дополнения и дополнительные тесты- name - имя плеера- max quality - максимальное разрешение выдаваемое источником. Это может быть 0 (аудио, без видео), 144, 240, 360, 480, 720, 1080- note - примечания| name           | max quality                                                  | note                                                                    ||----------------|--------------------------------------------------------------|-------------------------------------------------------------------------|| kodik          | 720 (на старых тайтлах (ранние One Peace, Evangelion) - 480) | **работает только на IP СНГ**                                           || aniboom        | 1080                                                         | **работает только на IP СНГ**. Иногда не возвращает mpd ссылку на видео || sibnet         | 480                                                          |                                                                         || animejoy       | 1080                                                         | только актуальные ongoing, потом видео удаляются с серверов             || csst           | 1080                                                         |                                                                         || dzen           | 1080                                                         |                                                                         || mailru         |                                                              |                                                                         || okru           |                                                              |                                                                         || sovetromantica | 1080                                                         | не на все тайтлы присутствуют видео                                     || vkcom          | 1080 (какого качества автор зальет видео)                    | CDN сервера в РФ, в других странах загружается медленнее                || nuum           | 1080                                                         | проект от wasd.tv                                                       |## loggingНастройка логгера идет через ключ `anicli-api````pythonimport logginglogger = logging.getLogger('anicli-api')```## http path### sourceЕсли по какой-то либо причине вас не устраивают настройки по умолчанию - то вы можете задатьконфигурацию http клиентов для экстракторов```pythonfrom anicli_api.source.animego import Extractorimport httpx# не обязательно настраивать все клиенты, зависит от режима использования# например, если вы будете использовать только asyncio - настраивайте только http_async_clientmy_client = httpx.Client(headers={"user-agent": "007"}, proxies="http:127.0.0.1:8080")my_async_client = httpx.AsyncClient(headers={"user-agent": "007"}, proxies="http:127.0.0.1:8080")# настройки клиентов будут передаваться всем объектам кроме методов Source.get_videos()# и Source.a_get_videos()ex = Extractor(http_client=my_client, http_async_client=my_async_client)# изменение http клиента для объектаresults = ex.search("lain")result = results[0]result.http = my_clientresult.http_async = my_async_client...```### playerВ player для модификации httpx клиентов (Client, AsyncioClient) необходимо передать kwargs аргументы:```pythonfrom anicli_api.source.animego import Extractorsources = (Extractor().search("lain")[0].get_anime().get_episodes()[0].get_sources())videos = sources[0].get_videos(transport=None,  # reset to default httpx.HTTPTransportheaders={"User-Agent": "i'm crushing :("})```## Структуры объектовПриведены поля, которые **гарантированно** возвращаются в API интерфейсе библиотеки,в некоторых источниках могут присутствовать дополнительные поля или атрибуты дляиспользования во внутренних методах.Например, в `anilibria` и `animevost` поля почти идентичны ответам API.В `animego.Anime` есть сырой несериализованный `raw_json` для извлечения дополнительных метаданных.### Search- url: str - URL на тайтл- title: str - имя найденного тайтла- thumbnail: str - изображение### Ongoing- url: str - URL на тайтл- title: str - имя найденного тайтла- thumbnail: str - изображение### Anime- title: str - имя тайтла (на русском)- thumbnail: str - изображение- description: Optional[str] - описание тайтла### Episode- title: str - имя эпизода- num: str - номер эпизода### Source- url: str - ссылка на источник- title: str - даббер или имя источника### VideoОбъект `Video`, полученный из `Source.get_video` (или `Source.a_get_video`)имеет следующую структуру:* type - тип видео (m3u8, mp4, mpd, audio)* quality - разрешение видео (0, 144, 240, 360, 480, 720, 1080)* url - прямая ссылка на видео* headers - заголовки требуемые для получения видео.Если возвращает пустой словарь - заголовки не нужны# Примечания- Парсеры из директории[anicli_api/source/parsers](anicli_api/source/parsers) автоматически генерируются с помощью[ssc_gen](https://github.com/vypivshiy/selector_schema_codegen),настройки хранятся в [libanime_schema](https://github.com/libanime/libanime_schema)- Для модификаций парсеров из директории `anicli_api/source/parsers`используйте наследование, чтобы не потерять изменения при перегенерации библиотекой `ssc_gen`.Пример из модуля [animejoy](anicli_api/source/animejoy.py):```pythonfrom anicli_api.source.parsers.animejoy_parser import PlayerUrlsView as PlayerUrlsViewOldfrom parsel import Selectorclass PlayerUrlsView(PlayerUrlsViewOld):def _parse_url(self, part: Selector) -> str:val_0 = part.attrib["data-file"]# maybe exclude https: prefixreturn f"https:{val_0}" if val_0.startswith("//") else val_0```- Проект разработан преимущественно на личное, некоммерческое использование с client-sideстороны.Автор проекта не несет ответственности за поломки, убытки в высоко нагруженных проектах и решениепредоставляется "Как есть" в соответствии с [MIT](LIENSE) лицензией.- Основная цель этого проекта — связать автоматизацию и эффективность извлечения того,что предоставляется пользователю в Интернете.Весь контент, доступный в рамках проекта, размещается на внешних неаффилированных источниках.- **Этот проект не включает инструменты кеширования и сохранения всех полученных данных,только готовые реализации парсеров и программные интерфейсы**