1.前台代码
1 module.exports = { 2 dev: { 3 4 // Paths 5 assetsSubDirectory: 'static', 6 assetsPublicPath: '/', 7 proxyTable: { 8 '/dowloadvo': { 9 target: '', 10 changeOrigin:true, 11 pathRewrite: { 12 '^/dowloadvo': '' 13 } 14 } 15 }
1 <template> 2 <div class="hello"> 3 <h1>get param</h1> 4 输入要访问的网址 5 <input type="text" v-model="paramw"> 6 <button type="button" @click="time">go</button> 7 <button type="button" @click="doloadMethod2">图片下载</button> 8 <button type="button" @click="doloadMethodVO">视频下载</button> 9 <input type="text" v-model="min"> 10 <input type="text" v-model="max"> 11 <p v-for="(item,i) in websites" :key="i">{{item}}</p> 12 13 </div> 14 </template> 15 16 <script> 17 import http from '@/assets/tools/http.js' 18 import $ from 'jquery' 19 export default { 20 data () { 21 return { 22 msg: 'Welcome to Your Vue.js App', 23 paramw:"", 24 websites:[], 25 uploadss:{}, 26 indexs:22, 27 timer:{}, 28 min:0, 29 max:0 30 31 } 32 }, 33 methods:{ 34 time(){ 35 this.getMethod(); 36 this.timer = setInterval(()=>{ 37 this.getMethod(); 38 }, 30000); 39 }, 40 getMethod(){ 41 if(this.indexs >24){ 42 clearInterval(this.timer); 43 this.timer=null; 44 } 45 console.log("go start:") 46 let that = this; 47 that.websites=[]; 48 that.uploadss={}; 49 that.indexs++; 50 console.log(that.indexs); 51 let url = "news-show-id-16-p-"+that.indexs+".html" 52 http.fetchGet("/service/"+url,{}).then(function(req){ 53 var htmls = req.data; 54 var array = htmls.split("\n"); 55 let str = ""; 56 let with1 = '<td class="news-name">'; 57 let with2 = '<h5 class="text-overflow-2">'; 58 for(let i=0;i<array.length;i++){ 59 str = array[i]; 60 str = str.trim(); 61 if(str.startsWith(with1) || str.startsWith(with2)){ 62 str = str.startsWith(with1)?str.replace(with1,"") : str.replace(with2,""); 63 str = str.startsWith(with1)?str.replace('</td>',"") : str.replace('</h5>',""); 64 let href = $(str).attr('href'); 65 if(href != null){ 66 that.websites.push(href); 67 } 68 } 69 } 70 that.doloadMethod(); 71 console.log("go end:") 72 }) 73 74 }, 75 doloadMethod(){ 76 let that = this; 77 for(let i=0;i<that.websites.length;i++){ 78 79 let title = ""; 80 let flage = 0; 81 let url = that.websites[i]; 82 http.fetchGet("/service"+url,{}).then(function(req){ 83 var htmls = req.data; 84 var array = htmls.split("\n"); 85 let str = ""; 86 let arrayObj = []; 87 for(let i=0;i<array.length;i++){ 88 str = array[i]; 89 str = str.trim(); 90 if(flage === 0 && str.startsWith('<title>')){ 91 title = $(str).text(); 92 title = that.indexs + title; 93 if(title != null){ 94 that.uploadss[title]=[]; 95 flage=1; 96 } 97 } 98 99 if(str.startsWith('<img src="/Uploads/')){ 100 let href = $(str).attr('src'); 101 if(href != null){ 102 arrayObj.push(href); 103 } 104 } 105 } 106 if(title != undefined){ 107 that.uploadss[title]=arrayObj; 108 if(i==that.websites.length-1){ 109 that.doloadMethod2(); 110 } 111 } 112 }); 113 } 114 }, 115 doloadMethod2(){ 116 console.log("dowload start:"); 117 let that = this; 118 let keys = Object.keys(that.uploadss); 119 // console.log(that.uploadss); 120 for(let i=0;i<keys.length;i++){ 121 let er = that.uploadss[keys[i]]; 122 123 for(let j=0;j<er.length;j++){ 124 let url = er[j]; 125 that.downloadByBlob("/uploads/"+url,keys[i]+j); 126 } 127 } 128 129 }, 130 downloadByBlob(url,name) { 131 let image = new Image() 132 image.setAttribute('crossOrigin', 'anonymous') 133 image.src = url 134 image.onload = () => { 135 let canvas = document.createElement('canvas') 136 canvas.width = image.width 137 canvas.height = image.height 138 let ctx = canvas.getContext('2d') 139 ctx.drawImage(image, 0, 0, image.width, image.height) 140 canvas.toBlob((blob) => { 141 let url = URL.createObjectURL(blob) 142 this.download(url,name) 143 // 用完释放URL对象 144 URL.revokeObjectURL(url) 145 }) 146 } 147 }, 148 download(href, name) { 149 let eleLink = document.createElement('a') 150 eleLink.download = name 151 eleLink.href = href 152 eleLink.click() 153 eleLink.remove() 154 }, 155 doloadMethodVO(){ 156 let that = this; 157 let min = that.min;; 158 let max = that.max; 159 for(let i = min;i <= max;i++){ 160 let a = "0"; 161 let b = (i.toString()).length; 162 163 for(let j=0;j<3-b;j++){ 164 a+='0'; 165 } 166 let url = "//201904/"+that.paramw+"/"+a+i+".ts"; 167 window.open("/dowloadvo"+url);//e7c1e9de 168 } 169 } 170 } 171 } 172 </script>
2.python代码
1 # -*- coding:utf-8 -*- 2 import os 3 import sys 4 import requests 5 import datetime 6 from Crypto.Cipher import AES 7 8 if 1: 9 def debug(s): 10 print(s) 11 else: 12 def debug(s): 13 pass 14 15 import importlib 16 17 importlib.reload(sys) 18 19 20 def download(url, savefile_path): 21 # 创建download目录 22 download_path = os.getcwd() + "\download" 23 if not os.path.exists(download_path):#如果文件夹不存在,就创建一个 24 os.mkdir(download_path) 25 26 # 新建日期文件夹,如果没有指定文件存储位置,就用年月日创建文件夹,否则用指定的文件夹 27 if not savefile_path: 28 savefile_path = os.path.join(download_path, datetime.datetime.now().strftime('%Y%m%d')) 29 else: 30 savefile_path = os.path.join(download_path, savefile_path) 31 print("savefile_path = " + savefile_path) 32 if not os.path.exists(savefile_path): 33 os.mkdir(savefile_path) 34 35 # 如果不存在first.m3u8,就重新获取,并保存,否则证明之前已经获取过,直接读取就行了 36 if not os.path.exists(os.path.join(download_path, 'first.m3u8')): 37 all_content = requests.get(url).text # 获取第一层M3U8文件内容 38 with open(os.path.join(download_path, 'first.m3u8'), 'w') as f: 39 f.write(all_content) 40 print("save first.m3u8") 41 else: 42 print("first.m3u8 is exist,just read it") 43 all_content = open(os.path.join(download_path, 'first.m3u8'), 'r').read() 44 45 # 不是M3U8文件,直接报错退出 46 if "#EXTM3U" not in all_content: 47 raise BaseException("非M3U8的链接") 48 # 49 if "EXT-X-STREAM-INF" in all_content: # 第一层 50 # 从第一层中读取所有的文件组成行列表 file_line 51 print("we need to get the second line") 52 file_line = all_content.split("\n") 53 # 找到 .m3u8 ,拼出第二层的链接 54 for line in file_line: 55 if '.m3u8' in line: 56 url = url.rsplit("/", 1)[0] + "/" + line # 拼出第二层m3u8的URL 57 print("second line url = " + url) 58 # 没存,就存一下,同first.m3u8的逻辑 59 if not os.path.exists(os.path.join(download_path, 'second.m3u8')): 60 all_content = requests.get(url).text 61 with open(os.path.join(download_path, 'second.m3u8'), 'w') as f: 62 f.write(all_content) 63 print("second.m3u8 has been saved") 64 else: 65 all_content = open(os.path.join(download_path, 'second.m3u8'), 'r').read() 66 break 67 # 到此为止,all_content里面的内容已经更新成了包含所有文件名的最终文件 68 # url 更新成了下载最终m3u8的URL 69 70 # 把里面的元素分割出来 71 file_line = all_content.split("\n") 72 73 unknow = True 74 key = "" 75 76 for line in file_line: 77 # 先找到解密key 78 if "#EXT-X-KEY" in line: # 找解密Key 79 method_pos = line.find("METHOD") 80 comma_pos = line.find(",") 81 method = line[method_pos:comma_pos].split('=')[1] 82 print("Decode Method:", method) 83 uri_pos = line.find("URI") 84 quotation_mark_pos = line.rfind('"') 85 key_path = line[uri_pos:quotation_mark_pos].split('"')[1] 86 key = b'25p9ldk10excun4r' 87 cryptor = AES.new(key, AES.MODE_CBC, key) 88 print("key:", key) 89 break 90 print("you cann't see me") 91 # 再进行下载和解密 92 for index, line in enumerate(file_line): # 第二层 93 if "EXTINF" in line: # 找ts地址并下载 94 unknow = False 95 c_fule_name = file_line[index + 1].rsplit("/", 1)[-1] 96 # 如果文件已经存在,就下一个 97 if os.path.exists(os.path.join(savefile_path, c_fule_name)): 98 print("file %s exist, next" % c_fule_name) 99 continue 100 # 判断源文件是否存在 101 sourceFile = "E:\\pythonProject\\downloadTS\\decode" 102 if not os.path.exists(os.path.join(sourceFile, c_fule_name)): 103 print("file %s exist, next" % c_fule_name) 104 continue 105 # 网络不好的时候会失败,所以重复3次 106 for i in range(3): 107 # 获取视频内容 108 print("get video " + datetime.datetime.now().strftime('%H:%M:%S')) 109 # res = requests.get(pd_url) 110 111 fo = open(os.path.join(sourceFile, file_line[index + 1]), 'rb'); 112 try: 113 if len(key): # AES 解密,有key就是需要解密 114 with open(os.path.join(savefile_path, c_fule_name), 'ab') as f: 115 f.write(cryptor.decrypt(fo.read())) 116 print(c_fule_name + " success") 117 break 118 else: # 没有key就不需要解密了,直接保存文件就行了 119 with open(os.path.join(savefile_path, c_fule_name), 'ab') as f: 120 f.write(res.content) 121 f.flush() 122 print(c_fule_name + " success") 123 break 124 except: # 网络不好导致下载失败,清除文件 125 print(str(i + 1) + " download error, file: " + c_fule_name) 126 os.remove(os.path.join(savefile_path, c_fule_name)) 127 else: # 下载失败,先跳过这个文件,后面重新执行的时候在重新下载 128 print("download file has failed 3 times, jump it") 129 # exit() 130 131 if unknow: 132 raise BaseException("未找到对应的下载链接") 133 else: 134 print("下载完成") 135 # merge_file(savefile_path) 136 137 138 def merge_file(path): 139 os.chdir(path) 140 cmd = "copy /b * new.ts" 141 # os.system(cmd) 142 # os.system('del /Q *.ts') 143 # os.system('del /Q *.mp4') 144 # os.rename("new.tmp", "new.mp4") 145 146 147 if __name__ == '__main__': 148 # url = input("please input the url of index.m3u8 file:\n") 149 url = "index.m3u8" 150 savefile_path = "F:\\Download\\goole\\vo\\1" 151 # url = r'' 152 # savefile_path = r'' 153 download(url, savefile_path)