最近,辣条君看了一档综艺《心动的信号》,打算看看,看看年轻人是怎么谈恋爱的。然而某视频需要会员,而从小勤劳单纯的拉条军当然选择了白嫖。于是乎,发现网上有资源~提示:本文仅供学习交流,请勿用于非法用途!!!请支持正版!!!分析与思路今天爬取的页面是http://www.ikanmv.com/k/39050.html。总共有10集。我们随便打开一集,点网络,发现视频是m3u8格式的。m3u8格式文件有两个,第一个是一些限制,真正的m3u8列表。下面是列表中一个一个下载下来的ts文件。我们的目标是下载一个剧集的所有ts文件,用ffmpeg软件拼接转换,最后生成一个.mp4文件。官网下载ffmpeg速度较慢,如有需要请点击下方链接(windows10版)。链接:https://pan.baidu.com/s/1_1htbaRQP_6y_G2xHOmWBw提取码:wivw其实也可以使用ffmpeg直接按照m3u8列表连接下载,但是速度慢。我们在代码中使用多进程来加快下载速度。但是,仍然存在问题。经测试,ffmpeg一次最多可以合并400或500个ts文件(每集ts文件大概1500~2000个),如果多了会报错,所以我们先从300个ts文件为一个组,合并得到几个大的ts文件,然后把这几个大的ts文件合并成一组,一个完整的ts文件,再转成mp4。所以我们的代码流程是:==下载某一集的所有ts文件->合并成几个大ts文件->合并成一个ts文件->转成mp4->删除无用的ts文件==代码实现首先创建一个文件夹D:\ts存放ts文件。按照上一节的代码流程,我们可以写出main函数,一步步实现几个方法: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=4forurlinurls:#获取需要的ts列表为一集下载get_list=get_m3u8(url)#下载ts文件到本地download('D:\\ts',get_list,url[0:-10])#mergemerge_ts('D:\\ts',str(index)+'.mp4')#deleteit使用tsdelete_ts('D:\\ts')#下一集index=index+1,我们模拟下载第4~6集(因为没有找到规则,我们需要手动获取几集的第二个m3u8请求连接)直接点击两个ts连接会发现前面的ts文件重新某集的quest也是一样,最后拼接xxxxx00x.ts,然后get请求就可以拿到某个ts的视频资源。先获取某集的所有ts文件后缀,即==xxxxx00x.ts部分==,实现get_m3u8方法#获取某集需要下载的ts列表defget_m3u8(url):result=requests.get(url)行=结果。text.split('\n')all_ts=[]forlineinlines:ifline.endswith('.ts'):all_ts.append(line)returnall_tsanddownloadtolocal#下载一个ts文件defdownload_ts(ts,root,url):res=requests.get(url+ts)withopen(root+"\\"+ts,'ab')asf:f.write(res.content)f.flush()print(ts+'下载完成!')#下载ts文件到本地defdownload(root,get_list,url):#已经下载的文件had_list=[]#continuewhilelen(list(set(get_list).difference(set(had_list))))>0:had_list=os.listdir(root)#需要下载=list(set(get_list).difference(set(had_list)))print('需要下载的个数是:'+str(len(需要)))pool=Pool(10)group=([tsfortsinneeds])pool.map(partial(download_ts,root=root,url=url),group)pool.close()pool.join()下载方法,也就是main函数中使用的方法。第一个参数root是ts视频的下载地址,第二个参数get_list是某一集所有ts文件的后缀(==xxxxx00x.ts部分==),第三个参数url是某个ts的前缀要求。首先,这里用到了多进程,之前的博客有介绍过,这里直接复制过来。值得一提的是,这里有一个while循环。因为在多进程下载某一集的所有ts文件的过程中,发现可能有部分ts文件丢失没有下载,所以每次下载完成后,获取下载的文件名(文件名是ts后缀),某某收集所有ts文件后缀,做差异化处理。继续下载这些丢失的,知道差异集为空,就证明所有下载完成。接下来你需要合并。#合并ts,因为不能一次合并这么多,合并两次defmerge_ts(root,name):os.chdir(root)all_ts=os.listdir(root)#countercounter=0big_list=[]per_list=[]#将多个ts文件名以300个为一组拼接在一起fortsinall_ts:ifcounter>300:counter=0big_list.append('+'.join(per_list))per_list=[]else:counter=counter+1per_list.append(ts)batch=0batch_ts=[]forbiginbig_list:batch=batch+1batch_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)需要两次合并,第二次合并并转换为mp4format是一个脚本操作。这里我们使用os.system来调用系统方法。由于我们的ffmpeg已经放入了环境变量,这里直接运行ffmpeg软件。生成某集的mp4文件后,我们需要将根目录下的.ts文件全部删除,一来可以节省硬盘空间,二来可以清除对下载下一集.ts文件的干扰。defdelete_ts(root):os.chdir(root)all_file=os.listdir(root)forfileinall_file:iffile.endswith('.ts'):os.remove(root+'\\'+file)上面我们您可以下载要观看的视频。喜欢的朋友快去试试吧~
