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)
