Re: Télécharger les vidéos du site Wakanim.tv
Au vu de la nouvelle politique de "multiplication des clés", je propose les modifications suivantes du fichier .py
Code:
# -*- coding: utf8 -*-
from Crypto.Cipher import Blowfish
from Crypto.Cipher import AES
import base64, os, urlparse, urllib2, re, sys, zlib, struct
import m3u8, cookielib, optparse, subprocess
import xml.etree.ElementTree as ElementTree
fn_regexp = re.compile('.*(?:=|/)(.*?).mp4_.*?.m3u8',re.DOTALL)
md_regexp = re.compile("var MovieData = {(.*?)};",re.DOTALL)
st_regexp = re.compile("var STMode = (.*?);",re.DOTALL)
token_regexp = re.compile('"(/video-streaming/.*?)"',re.DOTALL)
m3u8_regexp = re.compile("file: '(?P<url>.*?)',",re.DOTALL)
provider_regexp = re.compile("provider: '(.*?)',",re.DOTALL)
cj = cookielib.CookieJar()
ulo = urllib2.build_opener(
urllib2.HTTPRedirectHandler(),
urllib2.HTTPHandler(debuglevel=0),
urllib2.HTTPSHandler(debuglevel=0),
urllib2.HTTPCookieProcessor(cj)
)
ulo.addheaders = [
('User-agent', ('Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'))
]
def main_is_frozen():
return (hasattr(sys, "frozen") or hasattr(sys, "importers"))
if main_is_frozen() :
exit = sys.exit
def decrypt_key(aeskey):
bfkeys = [k.strip() for k in open('bfkeys.txt').readlines()]+[None]
for bfkey in bfkeys :
try:
bf = Blowfish.new(bfkey, Blowfish.MODE_ECB)
t = aeskey.decode("hex")
t = bf.decrypt(t)
t = base64.b64decode(t)
if len(t) != 16 : raise
except: continue
aeskey = t
break
print "bfkey = %s" % bfkey
return aeskey
def unzipSWF(d):
if d[0] == 'C':
d = zlib.decompress(d[8:])
elif d[0] == 'F':
d = d[8:]
else:
raise
return d
def quick_parse(d):
d = re.sub('\s*:\s*','=',d)
d = re.sub('\s*,\s*','&',d)
d = re.sub("='(.*?)'",'=\g<1>',d)
d = re.sub('="(.*?)"','=\g<1>',d)
d = re.sub('=false','=False',d)
d = re.sub('=true','=True',d)
d = re.sub('^\s','',d)
d = re.sub('\s\Z','',d)
return d
def download_m3u8(uri):
playlist = ulo.open(uri).read()
playlist = m3u8.loads(playlist)
if playlist.is_variant:
playlist = max(((int(x.stream_info.bandwidth),x) for x in playlist.playlists))[1]
if playlist.uri.startswith('http'): uri = playlist.uri
else: uri = uri.replace(os.path.basename(uri),playlist.uri)
playlist = ulo.open(uri).read()
playlist = m3u8.loads(playlist)
fn = '%s.ts' % fn_regexp.findall(uri)[0]
while os.access(fn, os.F_OK):
fn = '_'+fn
print uri,'->',fn
f = open(fn,'wb')
if not playlist.key.uri.startswith('http'): playlist.key.uri = uri.replace(os.path.basename(uri),playlist.key.uri)
key = decrypt_key(ulo.open(playlist.key.uri).read())
iv = ("%032x" % int(playlist.key.iv,16)).decode("hex")
aes = AES.new(key, AES.MODE_CBC, iv)
for x in playlist.segments :
if not x.uri.startswith('http'): x.uri = uri.replace(os.path.basename(uri),x.uri)
r = ulo.open(x.uri)
d = r.read()
d = aes.decrypt(d)
f.write(d)
print 'Done'
f.close()
subprocess.call(r"ffmpeg.exe -i %s -vcodec copy %s" % (fn,fn+'.mp4'),stdout=sys.stdout,shell=True)
def download_video(video_url):
page = ulo.open(video_url).read()
md = md_regexp.search(page).group(1)
st = st_regexp.search(page).group(1)
post_data = quick_parse(md+'&STMode='+st)
post_data = post_data.replace('SupportAds=0','SupportAds=1')
Id = dict(urlparse.parse_qsl(post_data, strict_parsing=True))['Id']
req = urllib2.Request('http://www.wakanim.tv/video/Advertisement?IdItem='+Id)
req.add_header('Referer', video_url)
r = ulo.open(req)
req = urllib2.Request('http://www.wakanim.tv/Library/GetMoviesByAdsNew')
req.add_header('Referer', video_url)
r = ulo.open(req, post_data)
video_url = ('http://www.wakanim.tv'+token_regexp.findall(r.read())[0]).decode('unicode_escape')
d = ulo.open(video_url).read()
provider_url = provider_regexp.findall(d)
provider_url = provider_url[0] if len(provider_url)>0 else None
video_url = m3u8_regexp.findall(d)[0]
if provider_url :
req = urllib2.Request(provider_url)
req.add_header('Referer', video_url)
r = ulo.open(req)
d = unzipSWF(r.read())
print "Provider = %s" % provider_url
open(os.path.basename(provider_url),'wb').write(d)
download_m3u8(video_url)
def GetSeries():
d = ulo.open(r'http://www.wakanim.tv/catalogws/CatalogXml/').read()
root = ElementTree.fromstring(d)
series = []
for child in root :
if child.tag == 'serie' :
s = {}
s['id'] = child.findall('Id')[0].text.replace(' ','')
s['name'] = child.findall('Nom')[0].text.encode('cp850',errors='replace')
series.append(s)
return series
def GetEpisodes(id):
d = ulo.open(r'http://www.wakanim.tv/catalogws/SerieXml/%s' % id).read()
episodes = []
catalogue = ElementTree.fromstring(d)
for episode in catalogue :
e = {}
e['AvailableFree'] = episode.findall('AvailableFree')[0].text
e['NumEp'] = int(episode.findall('NumEp')[0].text)
e['Titre'] = episode.findall('Titre')[0].text.encode('cp850',errors='replace')
e['UrlEpisodeFree'] = episode.findall('UrlEpisodeFree')[0].text
episodes.append(e)
return episodes
if __name__ == '__main__' :
VERSION = 1
usage = sys.executable+" [<SerieID> <EpisodeNum> | <VideoURL> | <m3u8URL>]"
description = "Sluuurp (v2)."
parser = optparse.OptionParser(description=description,usage=usage,formatter=optparse.IndentedHelpFormatter(max_help_position=1000,width=1000))
parser.add_option("-S", "--slist", action="store_true", help="Montre la liste des series et quitte.", default=False)
parser.add_option("-E", "--elist", action="store", help="Montre la liste des episodes d'une serie et quitte.", default=False)
(options, args) = parser.parse_args()
if not sys.argv[1::] :
parser.print_help()
exit()
if options.slist is True :
s = GetSeries()
for x in s :
print '%s\t:%s' % (x['id'],x['name'])
exit()
if options.elist is not False :
e = GetEpisodes(options.elist)
for x in e :
print '%s(%s)\t:%s' % (x['NumEp'],x['AvailableFree'],x['Titre'])
exit()
if len(args) == 1 :
if re.search(r'http://www.wakanim.tv/video/.*/',args[0],re.DOTALL) == None :
download_m3u8(args[0])
else:
download_video(args[0])
elif len(args) == 2 :
url = r'http://www.wakanim.tv'+[ x for x in GetEpisodes(args[0]) if x['NumEp'] == int(args[1])][0]['UrlEpisodeFree']
download_video(url)
else:
print "Saisie invalide"
exit()
Les clées seront donc maintenant lues du fichier bfkeys.txt (inserez une clé par ligne et vice versa), et le script les testera toutes jusqu'a trouver la bonne.
Un fichier bfkeys.txt contenant les 2 clés sus-citées (attention un espace s'est glissé dans la derni?re) devrait permettre de telecharger toutes les videos .m3u8 ? ce jour.
La nouvelle fonction decrypt_key devrait ?tre plus comprehensible CereFR :)
|