Skip to content

Instantly share code, notes, and snippets.

@koutoftimer
Last active October 24, 2018 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save koutoftimer/ae33afa5642682681805db14b2764396 to your computer and use it in GitHub Desktop.
Save koutoftimer/ae33afa5642682681805db14b2764396 to your computer and use it in GitHub Desktop.
Extract *.m3u8 playlist urls from link to anime page on online.anidub.com

Скрипт позволяет создать плейлист в формате \*.m3u для просмотра аниме с https://online.anidub.com/

Использование

Для создания плейлиста нужно выполнить скрипт с двумя параметрами: ссылку на страницу аниме (например это) и путь куда сохранять плейлист (например /tmp/pl.m3u). Команда будет иметь вид

$ python3 extract.py --output pl.m3u \
    --url "https://online.anidub.com/anime/10415-galakticheskie-zheleznye-dorogi-ginga-tetsudou-monogatari-01-iz-26.html"

Требования

  • python3
  • установленные зависимости из requirements.txt
  • любой плейер способный проигрывать плейлисты в форматах:
    • *.m3u - используется для создания плейлиста с сериями
    • *.m3u8 - используется для https://video.sibnet.ru
    • *.mp4 - используется для https://www.stormo.tv
#!/usr/bin/env python3
import re
import requests
import requests_cache
import click
from lxml import etree
from cssselect import GenericTranslator
requests_cache.install_cache(backend='memory')
class Video(object):
def __init__(self, number, provider_url):
self.number = number
self.provider_url = provider_url
self.title = None
self.duration = None
self.url = None
class Player(object):
def __init__(self, anidub_url):
self.anidub_url = anidub_url
self.playlist = []
def _extract_videos(self):
raise NotImplemented
def _extract_video_url(self, url):
raise NotImplemented
def _extract_video_title(self, url):
raise NotImplemented
def _extract_video_duration(self, url):
raise NotImplemented
@property
def name(self):
raise NotImplemented
@property
def REG(self):
raise NotImplemented
def count_series(self):
if not self.playlist:
self._extract_videos()
return len(self.playlist)
def process_playlist(self):
with click.progressbar(self.playlist, label='Loading: ') as playlist:
for video in playlist:
video.url = self._extract_video_url(video.provider_url)
video.title = self._extract_video_title(video.provider_url)
video.duration = self._extract_video_duration(video.provider_url)
class SibnetPlayer(Player):
name = 'Sibnet'
REG = re.compile('"/v/[a-z0-9]*/[0-9]*[.]m3u8"')
def _extract_videos(self):
html = requests.get(self.anidub_url).text
selector = GenericTranslator().css_to_xpath('#sel > option')
document = etree.HTML(html)
for el in document.xpath(selector):
url, number = el.get('value').split('|')
self.playlist.append(Video(number, url))
def _extract_video_url(self, url):
html = requests.get(url).text
try:
link = self.REG.search(html).group(0)[1:-1]
return 'https://video.sibnet.ru{}'.format(link)
except e:
return ''
def _extract_video_title(self, url):
html = requests.get(url).text
document = etree.HTML(html)
return document.find('.//meta[@property="og:title"]').get('content')
def _extract_video_duration(self, url):
html = requests.get(url).text
document = etree.HTML(html)
return document.find('.//meta[@property="og:duration"]').get('content')
class StormoPlayer(Player):
name = 'Stormo'
REG = re.compile('https://www\.stormo\.tv/get_file/[0-9]*/[a-z0-9]*/'
'[0-9]*/[0-9]*/[0-9]*[.]mp4/')
def _extract_videos(self):
html = requests.get(self.anidub_url).text
selector = GenericTranslator().css_to_xpath('#sel3 > option')
document = etree.HTML(html)
for el in document.xpath(selector):
url, number = el.get('value').split('|')
self.playlist.append(Video(number, url))
def _extract_video_url(self, url):
html = requests.get(url).text
try:
return self.REG.search(html).group(0)
except e:
return ''
def _extract_video_title(self, url):
html = requests.get(url).text
document = etree.HTML(html)
return document.find('.//title').text
def _extract_video_duration(self, url):
return -1
@click.command()
@click.option('-u', '--url', required=True, help='anidub url')
@click.option('-o', '--output', type=click.File('w'), required=True,
help='where to put VLC playlist (*.m3u)')
def extract(url=None, output=None):
players = [SibnetPlayer(url), StormoPlayer(url)]
series_count = max(player.count_series() for player in players)
players = [p for p in players if p.count_series() == series_count]
output.write('#EXTM3U\n\n')
for player in players[:1]:
click.secho('--= {} =--'.format(player.name), fg='green', bold=True)
output.write('# --= {} =--\n\n'.format(player.name))
player.process_playlist()
click.secho('#\tURL', fg='blue')
for video in player.playlist:
click.echo('{}\t{}'.format(video.number, video.url))
output.write('#EXTINF:{}, {}\n'.format(video.duration, video.title))
output.write('{}\n'.format(video.url))
if __name__ == "__main__":
extract()
Click==7.0
cssselect==1.0.3
lxml==4.2.5
requests==2.20.0
requests-cache==0.4.13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment