commit
f0fec9bbc1
|
@ -34,7 +34,7 @@ class BaseAnime:
|
|||
|
||||
if not _skip_online_data:
|
||||
logging.info('Extracting episode info from page')
|
||||
self.getEpisodes()
|
||||
self.get_data()
|
||||
|
||||
@classmethod
|
||||
def verify_url(self, url):
|
||||
|
@ -42,17 +42,17 @@ class BaseAnime:
|
|||
return True
|
||||
return False
|
||||
|
||||
def getEpisodes(self):
|
||||
def get_data(self):
|
||||
self._episodeIds = []
|
||||
r = requests.get(self.url, headers=desktop_headers)
|
||||
soup = BeautifulSoup(r.text, 'html.parser')
|
||||
|
||||
try:
|
||||
self._getMetadata(soup)
|
||||
self._scrape_metadata(soup)
|
||||
except Exception as e:
|
||||
logging.debug(e)
|
||||
|
||||
self._episodeIds = self._getEpisodeUrls(soup)
|
||||
self._episodeIds = self._scarpe_episodes(soup)
|
||||
self._len = len(self._episodeIds)
|
||||
|
||||
logging.debug('EPISODE IDS: length: {}, ids: {}'.format(
|
||||
|
@ -86,10 +86,10 @@ Episode count: {length}
|
|||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
def _getEpisodeUrls(self, soup):
|
||||
def _scarpe_episodes(self, soup):
|
||||
return
|
||||
|
||||
def _getMetadata(self, soup):
|
||||
def _scrape_metadata(self, soup):
|
||||
return
|
||||
|
||||
|
||||
|
@ -112,20 +112,20 @@ class BaseEpisode:
|
|||
logging.debug("Extracting stream info of id: {}".format(self.episode_id))
|
||||
|
||||
try:
|
||||
self.getData()
|
||||
self.get_data()
|
||||
except NotFoundError:
|
||||
parent.QUALITIES.remove(self.quality)
|
||||
for quality in parent.QUALITIES:
|
||||
logging.warning('Quality {} not found. Trying {}.'.format(self.quality, quality))
|
||||
self.quality = quality
|
||||
try:
|
||||
self.getData()
|
||||
self.get_data()
|
||||
parent.quality = self.quality
|
||||
break
|
||||
except NotFoundError:
|
||||
parent.QUALITIES.remove(self.quality)
|
||||
|
||||
def getData(self):
|
||||
def get_data(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def download(self, force=False, path=None,
|
||||
|
|
|
@ -20,14 +20,14 @@ scraper = cfscrape.create_scraper()
|
|||
|
||||
|
||||
class BaseAnimeCF(BaseAnime):
|
||||
def getEpisodes(self):
|
||||
def get_data(self):
|
||||
self._episodeIds = []
|
||||
r = scraper.get(self.url, headers=desktop_headers)
|
||||
soup = BeautifulSoup(r.text, 'html.parser')
|
||||
|
||||
self._getMetadata(soup)
|
||||
self._scrape_metadata(soup)
|
||||
|
||||
self._episodeIds = self._getEpisodeUrls(soup)
|
||||
self._episodeIds = self._scarpe_episodes(soup)
|
||||
self._len = len(self._episodeIds)
|
||||
|
||||
logging.debug('EPISODE IDS: length: {}, ids: {}'.format(
|
||||
|
|
|
@ -8,7 +8,7 @@ class GogoanimeEpisode(BaseEpisode):
|
|||
QUALITIES = ['360p', '480p', '720p']
|
||||
_base_url = 'https://www2.gogoanime.se'
|
||||
|
||||
def getData(self):
|
||||
def get_data(self):
|
||||
url = self._base_url + self.episode_id
|
||||
soup = BeautifulSoup(requests.get(url).text, 'html.parser')
|
||||
url = 'https:'+soup.select_one('li.anime a').get('data-video')
|
||||
|
@ -23,20 +23,19 @@ class GogoanimeEpisode(BaseEpisode):
|
|||
class GogoAnime(BaseAnime):
|
||||
sitename = 'gogoanime'
|
||||
QUALITIES = ['360p', '480p', '720p']
|
||||
_api_url = 'https://www2.gogoanime.se//load-list-episode?ep_start=1&'\
|
||||
'ep_end={ep_end}&id={id}&default_ep=0'
|
||||
_episode_list_url = 'https://www2.gogoanime.se//load-list-episode'
|
||||
_episodeClass = GogoanimeEpisode
|
||||
|
||||
def _getEpisodeUrls(self, soup):
|
||||
ep_end = max([int(a.attrs['ep_end'])
|
||||
for a in soup.find(
|
||||
'ul', {'id': 'episode_page'}
|
||||
).find_all('a')])
|
||||
def _scarpe_episodes(self, soup):
|
||||
anime_id = soup.select_one('input#movie_id').attrs['value']
|
||||
params = {
|
||||
'default_ep': 0,
|
||||
'ep_start': 0,
|
||||
'ep_end': 999999, # Using a very big number works :)
|
||||
'id': anime_id,
|
||||
}
|
||||
|
||||
id = soup.find('input', {'id': 'movie_id'}).attrs['value']
|
||||
|
||||
url = self._api_url.format(id=id, ep_end=ep_end)
|
||||
res = requests.get(url)
|
||||
res = requests.get(self._episode_list_url, params=params)
|
||||
soup = BeautifulSoup(res.text, 'html.parser')
|
||||
|
||||
epurls = list(reversed([a.get('href').strip()
|
||||
|
@ -44,8 +43,8 @@ class GogoAnime(BaseAnime):
|
|||
|
||||
return epurls
|
||||
|
||||
def _getMetadata(self, soup):
|
||||
meta = soup.find('div', {'class': 'anime_info_body_bg'})
|
||||
def _scrape_metadata(self, soup):
|
||||
meta = soup.select_one('.anime_info_body_bg')
|
||||
self.title = meta.find('h1').text
|
||||
self.poster = meta.find('img').get('src')
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class KissanimeEpisode(BaseEpisode):
|
|||
_base_url = 'http://kissanime.ru'
|
||||
VERIFY_HUMAN = True
|
||||
|
||||
def getData(self):
|
||||
def get_data(self):
|
||||
episode_url = self._base_url+self.episode_id+'&s=rapidvideo'
|
||||
logging.debug('Calling url: {}'.format(episode_url))
|
||||
|
||||
|
@ -59,6 +59,8 @@ class KissAnime(BaseAnimeCF):
|
|||
|
||||
soup = BeautifulSoup(res.text, 'html.parser')
|
||||
|
||||
# If only one anime found, kissanime redirects to anime page.
|
||||
# We don't want that
|
||||
if soup.title.text.strip().lower() != "find anime":
|
||||
return [SearchResult(
|
||||
title=soup.find('a', 'bigChar').text,
|
||||
|
@ -80,7 +82,7 @@ class KissAnime(BaseAnimeCF):
|
|||
|
||||
return ret
|
||||
|
||||
def _getEpisodeUrls(self, soup):
|
||||
def _scarpe_episodes(self, soup):
|
||||
ret = soup.find('table', {'class': 'listing'}).find_all('a')
|
||||
ret = [str(a['href']) for a in ret]
|
||||
logging.debug('Unfiltered episodes : {}'.format(ret))
|
||||
|
@ -98,6 +100,6 @@ class KissAnime(BaseAnimeCF):
|
|||
ret = ret[::-1]
|
||||
return ret
|
||||
|
||||
def _getMetadata(self, soup):
|
||||
def _scrape_metadata(self, soup):
|
||||
info_div = soup.find('div', {'class': 'barContent'})
|
||||
self.title = info_div.find('a', {'class': 'bigChar'}).text
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from anime_downloader.sites.kissanime import Kissanime
|
||||
from anime_downloader.sites.anime import BaseEpisode
|
||||
from anime_downloader.sites.exceptions import NotFoundError
|
||||
from anime_downloader.const import desktop_headers
|
||||
|
||||
import requests
|
||||
|
||||
|
@ -8,17 +9,23 @@ import requests
|
|||
class KisscartoonEpisode(BaseEpisode):
|
||||
_base_url = ''
|
||||
VERIFY_HUMAN = False
|
||||
_api_url = 'https://kisscartoon.ac/ajax/anime/load_episodes?v=1.1&episode_id={}'
|
||||
_episode_list_url = 'https://kisscartoon.ac/ajax/anime/load_episodes'
|
||||
QUALITIES = ['720p']
|
||||
|
||||
def getData(self):
|
||||
ep_id = self.episode_id.split('id=')[-1]
|
||||
url = self._api_url.format(ep_id)
|
||||
res = requests.get(url)
|
||||
def get_data(self):
|
||||
params = {
|
||||
'v': '1.1',
|
||||
'epiosde_id': self.episode_id.split('id=')[-1],
|
||||
}
|
||||
headers = desktop_headers
|
||||
headers['referer'] = self.episode_id
|
||||
res = requests.get(self._episode_list_url,
|
||||
params=params, headers=headers)
|
||||
url = res.json()['value']
|
||||
|
||||
headers = {'referer': self.episode_id}
|
||||
res = requests.get('https:' + url, headers=headers)
|
||||
headers = desktop_headers
|
||||
headers['referer'] = self.episode_id
|
||||
res = requests.get('https://' + url, headers=headers)
|
||||
|
||||
self.stream_url = res.json()['playlist'][0]['file']
|
||||
self.title = self.episode_id.split(
|
||||
|
@ -30,7 +37,7 @@ class KissCarton(Kissanime):
|
|||
sitename = 'kisscartoon'
|
||||
_episodeClass = KisscartoonEpisode
|
||||
|
||||
def _getEpisodeUrls(self, soup):
|
||||
def _scarpe_episodes(self, soup):
|
||||
ret = soup.find('div', {'class': 'listing'}).find_all('a')
|
||||
ret = [str(a['href']) for a in ret]
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class Masterani(BaseAnime):
|
|||
QUALITIES = ['360p', '480p', '720p']
|
||||
_api_url = 'https://www.masterani.me/api/anime/{}/detailed'
|
||||
|
||||
def getEpisodes(self):
|
||||
def get_data(self):
|
||||
anime_id = self.url.split('info/')[-1].split('-')[0]
|
||||
url = self._api_url.format(anime_id)
|
||||
res = requests.get(url)
|
||||
|
|
|
@ -13,10 +13,10 @@ __all__ = ['NineAnimeEpisode', 'NineAnime']
|
|||
|
||||
class NineAnimeEpisode(BaseEpisode):
|
||||
QUALITIES = ['360p', '480p', '720p', '1080p']
|
||||
_base_url = r'https://9anime.is/ajax/episode/info?id={id}&server={server}&_={param_}&ts={ts}'
|
||||
_base_url = r'https://9anime.is/ajax/episode/info'
|
||||
ts = 0
|
||||
|
||||
def getData(self):
|
||||
def get_data(self):
|
||||
params = {
|
||||
'id': self.episode_id,
|
||||
'server': '33',
|
||||
|
@ -24,10 +24,9 @@ class NineAnimeEpisode(BaseEpisode):
|
|||
}
|
||||
|
||||
def get_stream_url(base_url, params, DD=None):
|
||||
params['param_'] = int(generate_(params, DD=DD))
|
||||
params['_'] = int(generate_(params, DD=DD))
|
||||
logging.debug('API call params: {}'.format(params))
|
||||
url = base_url.format(**params)
|
||||
data = util.get_json(url)
|
||||
data = util.get_json(base_url, params=params)
|
||||
|
||||
return data['target']
|
||||
|
||||
|
@ -35,7 +34,7 @@ class NineAnimeEpisode(BaseEpisode):
|
|||
url = get_stream_url(self._base_url, params)
|
||||
except KeyError:
|
||||
try:
|
||||
del params['param_']
|
||||
del params['_']
|
||||
# I don't know if this is reliable or not.
|
||||
# For now it works.
|
||||
url = get_stream_url(
|
||||
|
@ -116,7 +115,7 @@ class NineAnime(BaseAnime):
|
|||
|
||||
return ret
|
||||
|
||||
def _getEpisodeUrls(self, soup):
|
||||
def _scarpe_episodes(self, soup):
|
||||
ts = soup.find('html')['data-ts']
|
||||
self._episodeClass.ts = ts
|
||||
logging.debug('data-ts: {}'.format(ts))
|
||||
|
@ -141,7 +140,7 @@ class NineAnime(BaseAnime):
|
|||
|
||||
return episode_ids
|
||||
|
||||
def _getMetadata(self, soup):
|
||||
def _scrape_metadata(self, soup):
|
||||
self.title = str(soup.find('div', {'class': 'widget info'}).find(
|
||||
'h2', {'class': 'title'}).text)
|
||||
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
import logging
|
||||
import json
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
import re
|
||||
import os
|
||||
import errno
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from anime_downloader.sites.exceptions import NotFoundError
|
||||
from anime_downloader.const import desktop_headers
|
||||
|
||||
|
||||
def get_json(url):
|
||||
def get_json(url, params=None):
|
||||
logging.debug('API call URL: {}'.format(url))
|
||||
data = json.loads(requests.get(url, headers=desktop_headers).text)
|
||||
data = requests.get(url, headers=desktop_headers).json()
|
||||
logging.debug('Returned data: {}'.format(data))
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def get_stream_url_rapidvideo(url, quality, headers):
|
||||
# TODO: Refractor this into a EmbedUrlProcessor
|
||||
url = url+'&q='+quality
|
||||
logging.debug('Calling Rapid url: {}'.format(url))
|
||||
r = requests.get(url, headers=headers)
|
||||
|
|
Loading…
Reference in New Issue