Anime extractors api implementation
Project description
# 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_` обозначает асинхронный метод, возвращаемые объекты идентичны
```mermaid
flowchart TD
E[Extractor] -->|"search('QUERY') | a_search('QUERY')"| S("List[Search]")
E -->|"ongoing() | a_ongoing()"| O("List[Ongoing]")
O -->|"get_anime() | a_get_anime()"| A[Anime]
S -->|"get_anime() | a_get_anime()"| A
A -->|"get_episodes() | a_get_episodes()"|Ep["List[Episode]"]
Ep -->|"get_sources() | a_get_sources()"|So["List[Source]"]
So -->|"get_videos() | a_get_videos()"|V["List[Video]"]
```
# quickstart
```python
from anicli_api.source.animego import Extractor
from anicli_api.tools import cli
if __name__ == '__main__':
cli(Extractor())
```
> Этот модуль реализован для простого ручного тестирования парсеров и "имитирует" потенциальное настоящее приложение
Пример своей реализации
```python
from anicli_api.source.animego import Extractor # can usage any source
def _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)
```
С asyncio аналогично, но **все** методы получения объектов имеют префикс `a_`:
```python
import asyncio
from 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 objects
results = await ex.a_search(prompt)
print(*[f"{i}) {r}" for i, r in enumerate(results)], sep="\n")
if __name__ == '__main__':
asyncio.run(main())
```
# Player
Эти модули можно использовать как экстрактор прямых ссылок на видео
> Эти модули минимально реализуют получение ссылок на видео с минимальными метаданными и заголовками для скачивания и
> не стремятся стать заменой yt-dlp
```python
import asyncio
from anicli_api.player.sibnet import SibNet
async 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 support!
asyncio.run(main())
```
# source description
- name - имя модуля
- type - тип источника получения данных.
- **NO** - неофициальный (парсинг html документов и запросы недокументированным API методам)
- **YES** - официальный (rest-api)
- note - примечания
- dubbers - тип озвучек.
- many - от различных авторов.
- subtitles - только субтитры.
- once - один вид (случайный)
- author - своя
| name | url | official api | dubbers | note |
|--------------------------------|----------------------------|--------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| animego | https://animego.org | NO | many | источники kodik, animego, не работает на IP отличных от СНГ и стран прибалтики |
| animania DROP (dead) | https://animania.online | NO | many | источник kodik, не работает на IP отличных от СНГ и стран прибалтики |
| sovetromantica | https://sovetromantica.com | NO | subtitles, author | не на все тайтлы есть видео, у себя хостят |
| anilibria | https://anilibria.tv | YES | author | |
| animevost | https://animevost.org | YES | author | |
| jutsu | https://jut.su | NO | once | Запуск видео в сторонних плеерах зависим от используемого user-agent заголовка в API интерфейсе. Некоторые тайтлы заблокированы на территории РФ |
| sameband | https://sameband.studio | NO | author | |
| animego.pro | https://animego.pro | NO | many | Нестабильный uptime сайта (могут быть проблемы с доступом) |
# 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 |
| anilibria | 1080 | |
| jutsu | 1080 | |
| sameband | 1080 | |
## logging
Настройка логгера идет через ключ `anicli-api`
```python
import logging
logger = logging.getLogger('anicli-api')
```
## http path
### source
Если по какой-то либо причине вас не устраивают настройки по умолчанию - то вы можете задать
конфигурацию http клиентов для экстракторов. Или если необходимо подключить proxy
```python
from anicli_api.source.animego import Extractor
import httpx
# не обязательно настраивать все клиенты, зависит от режима использования
# например, если вы будете использовать только asyncio - настраивайте только http_async_client
my_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_client
result.http_async = my_async_client
...
```
### player
В player для модификации httpx клиентов (Client, AsyncioClient) необходимо передать kwargs аргументы:
```python
from anicli_api.source.animego import Extractor
sources = (
Extractor()
.search("lain")[0]
.get_anime()
.get_episodes()[0]
.get_sources()
)
videos = sources[0].get_videos(transport=None, # reset to default httpx.HTTPTransport
headers={"User-Agent": "i'm crushing :("})
```
## Структуры объектов
Приведены поля, которые **гарантированно** возвращаются в API интерфейсе библиотеки.
В некоторых источниках могут присутствовать дополнительные поля или атрибуты для
использования во внутренних методах.
- Например, в `anilibria` и `animevost` поля почти идентичны ответам API.
В `animego.Anime` есть сырой несериализованный `raw_json` для извлечения дополнительных метаданных.
- В некоторых источниках на полях могут присутствовать "заглушки" для поддержания консистентности API интерфейса. Например,
в модуле `anicli_api.source.jutsu.Episode` уже можно получить прямые ссылки на видео (Video объект),
но для поддержания полиморфизма, необходимо возвращать объект `Source` и только потом `Video`
- Если по какой-либо причине объекты не получены (ddos защита, региональные ограничения) - то возвращает пустой список.
(#TODO возможно, необходимо выбрасывать исключение?)
### Search
- url: str - URL на тайтл
- title: str - имя найденного тайтла
- thumbnail: str - изображение
### Ongoing
- url: str - URL на тайтл
- title: str - имя найденного тайтла
- thumbnail: str - изображение
### Anime
- title: str - имя тайтла (на русском)
- thumbnail: str - изображение
- description: Optional[str] - описание тайтла. может вернуть пустую строку или None
### Episode
- title: str - имя эпизода (Если источник его не хранит, то будет Серия или Serie)
- 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`.
- Проект разработан преимущественно на личное, некоммерческое использование с client-side
стороны. Проекта не несет ответственности за поломки, убытки и решение
предоставляется "Как есть" в соответствии с [MIT](LIENSE) лицензией.
- Основная цель этого проекта — связать автоматизацию и эффективность извлечения того,
что предоставляется пользователю в Интернете.
Весь контент, доступный в рамках проекта, размещается на внешних неаффилированных источниках.
- **Этот проект не включает инструменты кеширования и сохранения всех полученных данных,
только готовые реализации парсеров и программные интерфейсы**
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
anicli_api-0.6.11.tar.gz
(42.4 kB
view details)
Built Distribution
File details
Details for the file anicli_api-0.6.11.tar.gz
.
File metadata
- Download URL: anicli_api-0.6.11.tar.gz
- Upload date:
- Size: 42.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.10.12 Linux/5.15.0-113-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d637cf97e561edce335a3409fea76f14e85706f5535f88aa4a1c6832d6cdea3e |
|
MD5 | 1f2063fd63c1b627005ffd19cfb30f58 |
|
BLAKE2b-256 | 6d290a8f14c30194ee5fa713babcd7b4f731dfd9845fe498328dd4f964b3b901 |
File details
Details for the file anicli_api-0.6.11-py3-none-any.whl
.
File metadata
- Download URL: anicli_api-0.6.11-py3-none-any.whl
- Upload date:
- Size: 53.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.10.12 Linux/5.15.0-113-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 62aa9fea957218d4aa9676edf077a6fea8529c28ef35b1aee5d45347cb2c3445 |
|
MD5 | 50ea74af7b172b5a34497eec982cf26e |
|
BLAKE2b-256 | 5bd6dffdfdec496f0bf1bc1cf851eabc06676d828556aab3c538d50789a11a63 |