神一样了 发表于 2019-11-16 15:01

m3u8视频下载分享

本帖最后由 神一样了 于 2019-11-16 15:07 编辑

昨天找学习资料的时候看到喜欢的视频想保存下来
听说56岁地产大佬潘石屹都在学python,所以花了半个小时研究了一下 怎么用python下载
在大哥们的帮助下解决了下载视频卡顿的问题,今天分享一下分析过程

刷新网页 用浏览器自带的F12抓包,找到下面三个文件







接下来用pytohn下载
import requests
import re
import os
import gevent
from Crypto.Cipher import AES
from gevent import monkey,pool
from collections import Counter
import time
import sys
gevent.monkey.patch_all()


url="http://www.91mmd.xyz/play?type=ckplayer&linkId=1886894"
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36","connection":"close"}
r=requests.get(url,headers=headers)

#是否加密flag
haskey=False
m3u8_url=Counter(re.findall("http.*?index\.m3u8", r.text)).most_common(1)
#找到提取内容重复次数最多的链接
if not "hls" in m3u8_url:
    m3u8_url=re.sub("index.m3u8","1000kb/hls/index.m3u8",m3u8_url)
    # video_index=re.sub("index.m3u8",r.text.split("\n")[-1],m3u8_url)

#判断是哪一种m3u8,需要有视频的那页
r=requests.get(m3u8_url,headers=headers)
ts_list=[]
for index,ts in enumerate(re.findall('(\w*?\.ts)', r.text)):
    ts_list.append((str(index).zfill(5),m3u8_url.replace("index.m3u8", ts)))
#视频链接存入列表,为保存顺序加index,补齐5位方便合成 列表内容是(index,url)

a=len(ts_list)
b=a
c=0

#判断文件里有没有key.key来确定是否有加密
if 'URI="key.key"' in r.text:
    key_url=re.sub("index.m3u8","key.key",m3u8_url)
    key=requests.get(key_url,headers=headers).text
    cryptor=AES.new(key, AES.MODE_CBC, key)
    #新建一个对象来处理key
    haskey=True



def save_video(ts):
    try:

      #用了协程所以需要共享一些参数,懒得搞直接上global
      global a
      global b
      file_name=ts
      root = os.getcwd()
      if not os.path.exists(root+"/"+file_name):
            r = requests.get(url=ts, headers=headers,timeout=10)
            with open(file_name+".ts", "wb")as f:
                if haskey==True:
                  #这里判断有没有加密,如果有就解密
                  f.write(cryptor.decrypt(r.content))
                else:
                  f.write(r.content)
      a=a-1

      #简陋的进度条
      hashes = '#' * int((b-a)/int(b) * 40)
      spaces = ' ' * (40 - len(hashes))
      sys.stdout.write("\rPercent: [%s] %d%%"%(hashes + spaces, (b-a)/b*100))
      sys.stdout.flush()
    except:
      #统计失败文件次数
      global c
      a=a-1
      c=c+1
      
def rename(name="学习资料"):
    os.system("(for %a in (*.ts) do @echo file '%a') > list.txt")
    os.system(f"ffmpeg -f concat -safe 0 -i list.txt -c copy {name}.mp4")
    os.system('del /Q *.ts')
    os.system('del /Q list.txt')
    os.system("exit")
   
   
if __name__=="__main__":
    pool = gevent.pool.Pool(50)
    threads = []
    for i in ts_list:
      threads.append(pool.spawn(save_video,i))
    gevent.joinall(threads)
    #视频是拿来学习python的,根本不会去看,所以也没必要考虑重试
    #下载完成后会有一次改名机会
    print(f"下载完成 失败:{c}/{b}")
    name=input("重命名:")
    if name:
      rename(name)
    else:
      rename()




注释写的很详细,另外分享代码是为了共同学习进步 不是开车
网站里还有很多其他类型视频 对深入研究下载复杂视频很有帮助


运行代码需要安装pytohn
依赖Crypto、gevent、requests
视频合成用到了ffmpeg也需要安装




运行效果

a8692375 发表于 2019-11-16 15:04

大佬能整合一下就好了

wizll7865 发表于 2019-11-16 15:08

看得不是太懂[尴尬]

枫音 发表于 2019-11-16 15:08

十分感谢大佬的分享!不过想问下,如果抓直播流的话需要注意什么?

狂侠先森 发表于 2019-11-16 15:13

很不错的思路啊,就是稍显麻烦!

山川灵兮 发表于 2019-11-16 15:15

根本不会啊,太难了

lizhipei78 发表于 2019-11-16 15:21

等 成品出来

色色 发表于 2019-11-16 15:10

这个梗哪来的空手套 来钱快

oy19940810 发表于 2019-11-16 15:12

感觉你们都好流啤

神器 发表于 2019-11-16 15:21

半个小时就可以搞定python,牛逼
页: [1] 2 3 4 5 6 7
查看完整版本: m3u8视频下载分享