Skip to content

vypivshiy/anicli-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

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_ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ асинхронный ΠΌΠ΅Ρ‚ΠΎΠ΄, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹

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]"]

Loading

quickstart

from anicli_api.source.animego import Extractor
from anicli_api.tools import cli

if __name__ == '__main__':
    cli(Extractor())

Π­Ρ‚ΠΎΡ‚ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ для простого Ρ€ΡƒΡ‡Π½ΠΎΠ³ΠΎ тСстирования парсСров ΠΈ "ΠΈΠΌΠΈΡ‚ΠΈΡ€ΡƒΠ΅Ρ‚" ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ настоящСС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ своСй Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ

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_:

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

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 ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΡ‚ БНГ ΠΈ стран ΠΏΡ€ΠΈΠ±Π°Π»Ρ‚ΠΈΠΊΠΈ. Часто ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ ΠΏΠΎΠ΄ РКН Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ
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
yummy-anime.org https://yummy-anime.org NO many
yummy-anime.ru https://yummy-anime.ru YES many

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 ссылку Π½Π° Π²ΠΈΠ΄Π΅ΠΎ
askor 1080
sibnet 480
csst 1080
dzen 1080
mailru
okru
sovetromantica 1080 Π½Π΅ Π½Π° всС Ρ‚Π°ΠΉΡ‚Π»Ρ‹ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Π²ΠΈΠ΄Π΅ΠΎ
vkcom 1080 (ΠΊΠ°ΠΊΠΎΠ³ΠΎ качСства Π°Π²Ρ‚ΠΎΡ€ Π·Π°Π»ΡŒΠ΅Ρ‚ Π²ΠΈΠ΄Π΅ΠΎ) CDN сСрвСра Π² Π Π€, Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… странах загруТаСтся ΠΌΠ΅Π΄Π»Π΅Π½Π½Π΅Π΅
anilibria 1080
jutsu 1080
sameband 1080

logging

Настройка Π»ΠΎΠ³Π³Π΅Ρ€Π° ΠΈΠ΄Π΅Ρ‚ Ρ‡Π΅Ρ€Π΅Π· ΠΊΠ»ΡŽΡ‡ anicli-api

import logging
logger = logging.getLogger('anicli-api')

Tools

Наборы Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ

cookies.py

ΠžΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Π°Ρ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ для извлСчСния cookie Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° для ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ использования Π² httpx. Π Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ rookiepy

pip install anicli-api[browser-cookies]
import httpx
from anicli_api.tools.cookies import get_raw_cookies_from_browser, raw_cookies_to_httpx_cookiejar

# ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ всС cookies
raw_cookies = get_raw_cookies_from_browser("firefox")
cookies = raw_cookies_to_httpx_cookiejar(raw_cookies)
# ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ ΠΏΠΎ host:
# raw_cookies = get_raw_cookies_from_browser("firefox", ["example.com"])
httpx.get("https://example.com", cookies=cookies)

# update cookies in extractors:
from anicli_api.source.yummy_anime_org import Extractor
ex = Extractor()
ex.http.cookies.update(cookies)
ex.http_async.cookies.update(cookies)

dummy_cli.py

ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ cli-ΠΊΠ»ΠΈΠ΅Π½Ρ‚ для Ρ€ΡƒΡ‡Π½Ρ‹Ρ… тСстов ΠΈ ΠΈΠΌΠΈΡ‚Π°Ρ†ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

from anicli_api.tools.dummy_cli import cli
from anicli_api.source.yummy_anime_org import Extractor

cli(Extractor())

helpers.py

Наборы Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для взаимодСйствия с экстракторами

from anicli_api.source.yummy_anime_org import Extractor
from anicli_api.tools.helpers import get_video_by_quality, video_picker_iterator, async_video_picker_iterator

ex = Extractor()
result = ex.search('lain')[0]
anime = result.get_anime()
episodes = anime.get_episodes()
sources = episodes[0].get_sources()
videos = sources[0].get_videos()

# ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ блиТайшСС доступноС ΠΏΠΎ качСству Π²ΠΈΠ΄Π΅ΠΎ
# 1080 or linear quality: 720 -> 480 -> 360 -> 240...
video = get_video_by_quality(videos, 1080)

# ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π²ΠΈΠ΄Π΅ΠΎ ΠΈ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°
# ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ΅ Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡŽ ΠΈ ΠΎΠ·Π²ΡƒΡ‡ΠΊΠ΅
for video_and_title in video_picker_iterator(
        start_source=sources[0],
        start_video=videos[0],
        anime=anime,
        episodes=episodes[3:]):  # limit episodes to 3
    v, title = video_and_title
    print(title, v)

# async рСализация ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°
async def main():
    async for vid_and_title in async_video_picker_iterator(
      start_source=sources[0],
        start_video=videos[0],
        anime=anime,
        episodes=episodes[3:]  # limit episodes to 3
    ):
        v, title = vid_and_title
        print(title, v)

import asyncio
asyncio.run(main())

m3u.py

РСализация создания m3u плСйлиста ΠΈΠ· ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² экстрактора

from anicli_api.source.yummy_anime_org import Extractor

from anicli_api.tools.m3u import generate_playlist, generate_asyncio_playlist
from anicli_api.tools.helpers import video_picker_iterator, async_video_picker_iterator

ex = Extractor()
result = ex.search('lain')[0]
anime = result.get_anime()
episodes = anime.get_episodes()
# get first source for first 3 episodes
sources =  [e.get_sources()[0] for e in episodes[:3]]
videos = sources[0].get_videos()

# generate playlist from sources
playlist_sources = generate_playlist(sources)

# generate playlist from video_picker
video_objs, titles_objs = [],[]
for video_and_title in video_picker_iterator(
        start_source=sources[0],
        start_video=videos[0],
        anime=anime,
        episodes=episodes[3:]):  # limit episodes to 3
    v, title = video_and_title
    video_objs.append(v)
    titles_objs.append(title)
playlist = generate_playlist(video_objs, titles_objs)


# asyncio
# if target not Source object - you can use sync variant
import asyncio
playlist_async = asyncio.run(generate_asyncio_playlist(sources))

http path

source

Если ΠΏΠΎ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ Π»ΠΈΠ±ΠΎ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ вас Π½Π΅ ΡƒΡΡ‚Ρ€Π°ΠΈΠ²Π°ΡŽΡ‚ настройки ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ - Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ http ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² для экстракторов. Или Ссли Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ proxy

from anicli_api.source.animego import Extractor
import httpx
# Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ всС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹, зависит ΠΎΡ‚ Ρ€Π΅ΠΆΠΈΠΌΠ° использования
# Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ссли Π²Ρ‹ Π±ΡƒΠ΄Π΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ asyncio - настраивайтС Ρ‚ΠΎΠ»ΡŒΠΊΠΎ http_async_client 
my_client = httpx.Client(headers={"user-agent": "007"}, proxy="http://127.0.0.1:8080")
my_async_client = httpx.AsyncClient(headers={"user-agent": "007"}, proxy="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 Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹:

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 автоматичСски Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ssc_gen, настройки хранятся Π² libanime_schema

  • Для ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΉ парсСров ΠΈΠ· Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ anicli_api/source/parsers ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ наслСдованиС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΠΏΠΎΡ‚Π΅Ρ€ΡΡ‚ΡŒ измСнСния ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ ssc_gen.

  • ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½ прСимущСствСнно Π½Π° Π»ΠΈΡ‡Π½ΠΎΠ΅, нСкоммСрчСскоС использованиС с client-side стороны. ΠŸΡ€ΠΎΠ΅ΠΊΡ‚Π° Π½Π΅ нСсСт отвСтствСнности Π·Π° ΠΏΠΎΠ»ΠΎΠΌΠΊΠΈ, ΡƒΠ±Ρ‹Ρ‚ΠΊΠΈ ΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ прСдоставляСтся "Как Π΅ΡΡ‚ΡŒ" Π² соотвСтствии с MIT Π»ΠΈΡ†Π΅Π½Π·ΠΈΠ΅ΠΉ.

  • Основная Ρ†Π΅Π»ΡŒ этого ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° β€” ΡΠ²ΡΠ·Π°Ρ‚ΡŒ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΈ ΡΡ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ извлСчСния Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ прСдоставляСтся ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π² Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚Π΅. Π’Π΅ΡΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚, доступный Π² Ρ€Π°ΠΌΠΊΠ°Ρ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, размСщаСтся Π½Π° Π²Π½Π΅ΡˆΠ½ΠΈΡ… Π½Π΅Π°Ρ„Ρ„ΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… источниках.

  • Π­Ρ‚ΠΎΡ‚ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π½Π΅ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ инструмСнты ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ ΠΈ сохранСния всСх ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ парсСров ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹Π΅ интСрфСйсы