本文来源吾爱破解论坛
本帖最后由 a1789043588 于 2020-1-26 16:28 编辑
代码写的比较烂,请大佬指点我的代码需要改善和优化的地方!
0,本人菜鸟,在设计这个工具中遇到了好几个问题没有解决:
(1)合并文件用windows的copy /b,但是windows控制台对命令长度要求是8k以内,文件数太多就没法一次合并成一个文件,有没有别的好办法?
(2)在用协程下载时速度快了好多,但是会遇到连接错误的情况,不知道这个怎么解决?
感谢葫芦炒鸡蛋,copy /b问题已经解决。原来copy在合并时,当文件名是0,1,2,3,4...,合并顺序是0,1,10,100...。把文件名改成0001,0002,0003...就能依次序合并了。所以在合并前先修改一下文件名,然后直接copy /b * 电影名.mp4即可。合并和删除ts代码修改如下:
[Python] 纯文本查看 复制代码
def com_ts(movie_name,work_path): for a, b, files in os.walk(work_path): os.chdir(work_path) for i in files: if len(i)==1: new_name='000'+i os.rename(i, new_name) elif len(i)==2: new_name = '00' + i os.rename(i, new_name) elif len(i)==3: new_name = '0' + i os.rename(i,new_name) else: pass os.system('copy /b * '+movie_name+'.mp4') def del_ts(work_path): os.chdir(work_path) for a,b,files in os.walk(work_path): for i in files: if '.' not in i: os.remove(i)
1,如何下载的?
(1)获取index.m3u8文件,改文件记录了每一小段视频的所在的网址。 我用的谷歌浏览器+DouYuVide插件,会自动获得该视频的index.m3u8文件。
效果如图:
index.m3u8文件内容如下:
[Asm] 纯文本查看 复制代码
#EXTM3U #EXT-X-VERSION:3 #EXT-X-ALLOW-CACHE:YES #EXT-X-TARGETDURATION:7 #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:6.960000, /hls/20190515/2ae3349c3c93cf8928a4eba8e1b59d56/1557914849/film_00000.ts #EXTINF:3.040000, /hls/20190515/2ae3349c3c93cf8928a4eba8e1b59d56/1557914849/film_00001.ts #EXTINF:5.120000, /hls/20190515/2ae3349c3c93cf8928a4eba8e1b59d56/1557914849/film_00002.ts ... ...
(2)下载每一小段的ts视频。
url是index.m3u8下载地址的域名部+/hls/20190515/2ae3349c3c93cf8928a4eba8e1b59d56/1557914849/film_***.ts。
(3)使用gevent.monkey协程下载速度要快很多。
2,如何合并的?
使用windows控制台的copy /b命令合并的,但是该命令在我的win7下限制命令长度为8k。
本工具在文件总数超过1800时不得不将视频合并成两部分,
3,具体实现代码:
[Python] 纯文本查看 复制代码
import gevent import gevent.monkey gevent.monkey.patch_all() import requests import re import os import time def get_file_num(path): #获取path目录下的文件总数 for a,b,files in os.walk(path): return len(files) def get_ts(url,name,work_path): #下载一个ts文件。url是下载地址,work_path是要保存磁盘的目录。 print('start ' ,name) urls = 'https://1*'+url headers={'Connection': 'close'} try: #下载太快出现连接错误时的解决方法。 response = requests.get(urls,headers=headers) except: urls = 'https://2*' + url try: response = requests.get(urls, headers=headers) except: urls = 'https://3*' + url try: response = requests.get(urls, headers=headers) except: print('下载失败:',name) return ts = response.content with open(work_path + name, 'wb') as f: f.write(ts) print(urls,'finish') def get_url(path): #从磁盘的path路径读取index.m3u8文件并通过正则将每一个ts文件下载地址的后边部分形成一个list。 pattern = re.compile(r'/hls.+ts') with open(path,'r') as f: l=pattern.findall(f.read()[112:]) return l def downmovie(m3u8_path,work_path): #进行下载 os.chdir(work_path) path = m3u8_path l = get_url(path) p = [] for i,url in enumerate(l): if os.path.exists(str(i)): pass else: p.append(gevent.spawn(get_ts, url, str(i),work_path)) gevent.joinall(p) f_num = get_file_num(work_path) if f_num!=len(l): #验证是否下载完所有的ts文件,没有的话等30s再去下载。(解决暂时封ip) print('部分没有下载完成,请30s后再次启动下载!') def com_ts(movie_name,work_path): #合并ts文件为一个或两个MP4 os.chdir(work_path) tss = '' f_num = get_file_num(work_path) for i in range(f_num): if i>1800: break tss = tss + str(i) + '+' shell_str = 'copy /b ' + tss[:-1] + ' '+movie_name+'.mp4' print(shell_str) os.system(shell_str) if i>1800: for i in range(1800, f_num): tss = tss + str(i) + '+' shell_str = 'copy /b ' + tss[:-1] + ' ' + movie_name + '2.mp4' print(shell_str) os.system(shell_str) def del_ts(work_path): #删除所有ts文件 f_num = get_file_num(work_path) for i in range(f_num-1): os.remove(work_path+str(i)) if __name__ == '__main__': #下边三个函数每次只能运行一个,否则会出错。确保全部ts下载完成再去合并,确保合并完再去删除。 downmovie('C:/Users/admin/Desktop/index.m3u8','C:/Users/admin/Desktop/movies/') com_ts('电影名','C:/Users/wangzi/Desktop/movies/') del_ts('C:/Users/admin/Desktop/movies/')
版权声明:
本站所有资源均为站长或网友整理自互联网或站长购买自互联网,站长无法分辨资源版权出自何处,所以不承担任何版权以及其他问题带来的法律责任,如有侵权或者其他问题请联系站长删除!站长QQ754403226 谢谢。
- 上一篇: 200行代码实现一个有声听书网爬虫下载器
- 下一篇: 喜马拉雅FM专辑下载器[开源+成品]2.0!