View Single Post
  #37  
Old 05-30-2014, 10:14 AM
Nopt Nopt is offline
Member
 
Join Date: May 2014
Posts: 37
Nopt is on a distinguished road
Default

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

Last edited by Nopt : 05-30-2014 at 11:38 AM.
Reply With Quote