最近辣条君看到一部综艺《心动的信号》,打算看一看,学一学年轻人该怎么谈恋爱。可是,某讯视频要会员,从小艰苦朴素的辣条君当然抉择白嫖了。于是乎,发现有在线资源哎~Tip:本文仅供学习与交换,切勿用于非法用处!!!请大家反对正版!!!
剖析与思路
明天爬取的页面是http://www.ikanmv.com/k/39050.html
。底下一共有10集。
咱们轻易关上一集,点击network
,发现视频是m3u8
格局的。有两个m3u8格式文件,第一个是一些限度条件,真正的m3u8列表。前面就是列表中逐条下载的ts文件。
咱们的指标是,把一集的所有ts文件下载下来,通过ffmpeg
软件进行拼接、转化,最终生成一个.mp4文件。ffmpeg
从官网下载较慢,如有须要请戳上面连贯(windows10版本)。
链接: https://pan.baidu.com/s/1_1htbaRQP_6y_G2xHOmWBw
提取码: wivw
其实间接用ffmpeg
也能够依据m3u8列表连贯间接下载,然而速度较慢,咱们代码中应用多过程,减速下载。
不过还有个问题,通过测试,ffmpeg
合并ts文件,一次性最多合并4、5百个(每集ts文件大略在1500~2000个之间),再多就会报错,所以咱们先以300个ts文件为1组,将他们合并一下,失去几个大个的ts文件,再将这几个大个的ts文件合并成一集一个整个的ts文件,再转化mp4。
所以咱们的代码流程为:==下载某集所有ts文件->合并成几个大个的ts文件->合并成一个ts文件->转化成mp4->删除没用的ts文件==
代码实现
首先创立一个文件夹D:\ts
用于寄存ts文件。
依据上节的代码流程,咱们能够写出主函数,几个办法逐渐实现:
if __name__ == '__main__': urls = [ 'https://zy.kubozy-youku-163-aiqi.com/20190710/13975_9273f090/1000k/hls/index.m3u8', 'https://zy.kubozy-youku-163-aiqi.com/20190717/14563_0eca69d7/1000k/hls/index.m3u8', 'https://zy.kubozy-youku-163-aiqi.com/20190724/15218_7487f9e5/1000k/hls/index.m3u8' ] # 开始的集数 index = 4 for url in urls: # 获取某集须要下载的ts列表 get_list = get_m3u8(url) # 下载ts文件到本地 download('D:\\ts', get_list, url[0:-10]) # 合并 merge_ts('D:\\ts', str(index)+'.mp4') # 删除没用的 ts delete_ts('D:\\ts') # 下一集 index = index + 1
咱们模仿下载4~6集(因为没找到法则,须要手动获取几集的第二个m3u8申请连贯)
轻易点击两个ts连贯就会发现,某一集的ts文件申请后面都是一样的,最初拼接上xxxxx00x.ts,而后get申请就能够失去某个ts视频资源了。首先获取某集所有ts文件后缀,就是==xxxxx00x.ts局部==,实现一下get_m3u8
办法
# 获取某集须要下载的ts列表def get_m3u8(url): result = requests.get(url) lines = result.text.split('\n') all_ts = [] for line in lines: if line.endswith('.ts'): all_ts.append(line) return all_ts
而后下载到本地
# 下载一个ts文件def download_ts(ts, root, url): res = requests.get(url+ts) with open(root+"\\" + ts, 'ab') as f: f.write(res.content) f.flush() print(ts+'下载结束!')# 下载ts文件到本地def download(root, get_list, url): # 曾经下载过的文件 had_list = [] # 还有没下载完的就持续 while len(list(set(get_list).difference(set(had_list)))) > 0: had_list = os.listdir(root) # 还须要下载的 needs = list(set(get_list).difference(set(had_list))) print('还须要下载个数为:'+str(len(needs))) pool = Pool(10) group = ([ts for ts in needs]) pool.map(partial(download_ts, root=root, url=url), group) pool.close() pool.join()
download
办法,即主函数中应用的办法。第一个参数root
是ts视频下载的地址,第二个参数get_list
是某集所有ts文件后缀(==xxxxx00x.ts局部==),第三个参数url
是某个ts申请前缀。首先这里用到了多过程,往期博客介绍过,这里照抄就好。
值得一提的时,这边有个while
循环。因为多过程下载某集所有ts文件过程中,我发现可能会造成某些ts文件的失落未下载,所以每次下载实现,咱们获取已下载实现的文件名称(文件名称就是ts后缀),和某集所有的ts文件后缀,做差集。持续下载这些失落的,晓得差集为空,就证实全副下载结束。
接下来须要合并。
# 合并ts,因为一次无奈合并那么多,合并两次def merge_ts(root, name): os.chdir(root) all_ts = os.listdir(root) # 计数器 counter = 0 big_list = [] per_list = [] # 将多个ts文件名,300为一组拼接在一起 for ts in all_ts: if counter > 300: counter = 0 big_list.append('+'.join(per_list)) per_list = [] else: counter = counter+1 per_list.append(ts) batch = 0 batch_ts = [] for big in big_list: batch = batch + 1 batch_ts.append(str(batch)+'.ts') os.system('copy /b ' + big + f' batch{batch}.ts') shell_str = '+'.join(batch_ts) # 第二次拼接 os.system('copy /b '+shell_str+' '+name)
这里须要两次合并,第二次合并和转mp4格局是一个脚本操作。这里应用os.system
调用零碎办法,因为咱们的ffmpeg
曾经放入到环境变量中,所以这里就是间接操作ffmpeg
软件了。
生成某集的mp4文件之后,咱们须要删除根目录下所有的.ts文件,一来节约硬盘空间,二来为下一集下载.ts文件革除烦扰。
def delete_ts(root): os.chdir(root) all_file = os.listdir(root) for file in all_file: if file.endswith('.ts'): os.remove(root+'\\'+file)
以上咱们就能够下载到喜爱看的视频了。喜爱的小伙伴快去试试吧~