吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 23999|回复: 89
上一主题 下一主题
收起左侧

[Python 转载] m3u8、ts 从爬取到自动解密并合成MP4一条龙【含源码、思路解析python】

    [复制链接]
跳转到指定楼层
楼主
长河落 发表于 2020-3-17 17:38 回帖奖励
本帖最后由 长河落 于 2020-3-17 22:52 编辑

###之前代码没贴好,十分抱歉,重新调整了一下###

参考教程:分析部分
  • 今天公司要下载某某一系列的视频教程,注册账号,打算IDM走一波结果凉凉。
  • 所有有了这篇m3u8的帖子
  • 第一步分析m3u8文件
  • 到这里下意识的用F12抓包看了下,这个视频地址是m3u8的格式
  • 我们看看这个包的网址
  • [HTML] 纯文本查看 复制代码
    1
    https://service.sanjieke.cn/video/media/1673668/608p.m3u8?class_id=3003359
  • 简单的分析一下不难得出3003359应该是课程的编号
  • 我们把这个文件的内容直接copy记事本中(完整的比较长,这里放个主要片段,足够分析就行):
[Python] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:17
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-KEY:METHOD=AES-128,URI="https://service.sanjieke.cn/video/key/1673668?class_id=3003359",IV=0x911b4187c0dadc4e886e0187dac9d3e7
#EXTINF:16.733333,
https://vcdn.sanjieke.cn/video/1673668/608p/ts/4d811e2afd060216f14433cec473c0d1.ts?sign=b76ae2ed4e2902153a77f27ce48b26a9&t=5e5f905b
#EXT-X-KEY:METHOD=AES-128,URI="https://service.sanjieke.cn/video/key/1673668?class_id=3003359",IV=0x6d8832d83419a92a0b5a3de830e6a536
#EXTINF:8.333333,
https://vcdn.sanjieke.cn/video/1673668/608p/ts/e015da822e2d1f955b8d8a9ef80c23aa.ts?sign=08cd76f8266c5d6f513376c8b4f88957&t=5e5f905b
#EXT-X-KEY:METHOD=AES-128,URI="https://service.sanjieke.cn/video/key/1673668?class_id=3003359",IV=0xec1ac0f3b5cce5639162e82fc722fe51
#EXTINF:8.333333,
https://vcdn.sanjieke.cn/video/1673668/608p/ts/b4be740df71b5ccaeba7f9494fa69a04.ts?sign=ee3deb256c3f16a35205df8b429bd33e&t=5e5f905b
#EXT-X-KEY:METHOD=AES-128,URI="https://service.sanjieke.cn/video/key/1673668?class_id=3003359",IV=0xfc32cdbda614c4e69e4aa93d92461115
#EXTINF:8.333333,

  • 经过分析不难发现几点信息
  • 从METHOD中可以看出加密方式是AES-128
  • key并没有直接给出来而是一个网址,但是每个ts文件的网址都是相同的,所以我们大胆推测同一个视频的key应该是固定的
  • 可以从看出这个m3u8是由多个ts文件拼接合成
  • 每次get请求的IV都是不一样,IV是16位16进制的key的偏移量
  • 由于aes-cbc-128 文件解密需要 密钥(key) 和 (偏移量)iv
  • 而通过解读m3u8文件,我们已经拿到了所有的iv,现在把key获取下来就行了
  • 第二步 获取视频的key
  • 本来想直接下载key文件,用WinHex打开,但是IDM抽风下载不下来,于是用fiddler抓包,先用textview查看一下获取的内容
  • [Asm] 纯文本查看 复制代码
    1
    3PsaKKqMdq8GFOMj


现在我们要得key值和iv值都齐全了,接下看开始动手写代码
  • 这里特别说明一下,因为时单线程,按顺序下载,所以不会出现视频合成乱序的问题
开发部分
[Python] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
'''
站点地址
https://www.sanjieke.cn/free.html
课程列表json
https://class.sanjieke.cn/course/class_content_with_checkpoint?cid=3003359
加载第一个视频页面
https://class.sanjieke.cn/course/section_content?cid=3003359§ion_id=1673672
https://class.sanjieke.cn/course/class_content_with_checkpoint?cid=17301420
加载第一个视频
https://service.sanjieke.cn/video/master/1673668.m3u8?class_id=3003359
 
从加载页中取出m3u8文件地址
https://service.sanjieke.cn/video/media/1673668/608p.m3u8?class_id=3003359
获取key地址
https://service.sanjieke.cn/video/key/1673668?class_id=3003359
'''
 
print('''
三节课m3u8下载器v2
1、需要先报名这个课程
2、输入课程的id就能下载
3、时间久了可能需要更新一下cookies
''')
import os
import re
import requests
from Crypto.Cipher import AES
 
 
headrer = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36',
    'Cookie':'acw_tc=276aedd715843843846276228e7237cfd3f2985ec8423b6b72e1f786d0f2f0; sajssdk_2015_cross_new_user=1; PHPSESSID=8c8i2ohp56ah69jr6i8jp07pa5; sjk_jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIyIiwianRpIjoiNDE4ZDViOWRjOTQ3YjFmYzNjMGM5MzhmODgxMzU0NmMzZDgwMGQ5NWVkM2JlMjlhNjQ4MmFkODAyMTZlNGU0ZTdiMDY1OWMwNjA3ZDJlMDkiLCJpYXQiOjE1ODQzODQ0MTcsIm5iZiI6MTU4NDM4NDQxNywiZXhwIjoxNTg3MDYyODE3LCJzdWIiOiIyMDc5NTY2NiIsInNjb3BlcyI6W119.bykO1OWL9_mqZKhI6qEpwwrbTEpEk25Xc-bwFXG47lktpRfKLBPw22WOUqYRfl0qi-WkkItBgcEe9TVU8jfFcg; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2220795666%22%2C%22%24device_id%22%3A%22170e4ab2004b55-0f846e6d4f2e96-4313f6a-3686400-170e4ab2005aa9%22%2C%22props%22%3A%7B%22%24latest_referrer%22%3A%22https%3A%2F%2Fwww.baidu.com%2Fs%22%2C%22%24latest_traffic_source_type%22%3A%22%E8%87%AA%E7%84%B6%E6%90%9C%E7%B4%A2%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E4%B8%89%E8%8A%82%E8%AF%BE%22%7D%2C%22first_id%22%3A%22170e4ab2004b55-0f846e6d4f2e96-4313f6a-3686400-170e4ab2005aa9%22%7D; Hm_lvt_85148c078fe4635816b80e5a36990313=1584384385,1584384418; Hm_lpvt_85148c078fe4635816b80e5a36990313=1584384436'
}
class_id =input('请输入课程编号:')
# 获取这个课程所有课时的ID
class_url = 'https://class.sanjieke.cn/course/class_content_with_checkpoint?cid='+class_id
class_contect = requests.get(class_url,headers=headrer).text.encode('utf-8').decode('unicode-escape')
course_title = re.compile('"course_title":"(.*?)"',re.S).findall(class_contect)
 
if len(course_title)==0:
    print('课程不在有效期内或未报名')
    raise IndexError
course_title = course_title[0]
 
course_id_name_list = re.compile('"node_id":(\d*),.*?"title":"(.*?)"',re.S).findall(class_contect) # 课时ID,名称
# 创建与课程同名文件夹
course_title = re.sub(u"([^\u4e00-\u9fa5\u0030-\u0039\u0041-\u005a\u0061-\u007a])", "", course_title)
if not os.path.exists(r'./' + r'./' + course_title):  # 判断文件夹是否存在
    os.makedirs(r'./' + r'./' + course_title)  # 如果不存在则创建文件夹
# 获取m3u8文件的ID以及对应的名称
i = 1
for course_id_name in course_id_name_list:
    course_url = 'https://class.sanjieke.cn/course/section_content?cid='+class_id+'§ion_id='+course_id_name[0]
    course_contect = requests.get(course_url,headers=headrer)
    course_contect = course_contect.text.replace('\\/','/').encode('utf-8','ignore').decode('unicode-escape','ignore')
    course_m3u8_id = re.compile('"id":"(\d*)"', re.S).findall(course_contect)
    if  len(course_m3u8_id) == 0:
        course_m3u8_id = re.compile('"id":(\d*)', re.S).findall(course_contect)
    # 读取每个m3u8文件的内容
    if not len(course_m3u8_id) == 0:
        # 获取m3u8文件下载地址
        course_m3u8_url = 'https://service.sanjieke.cn/video/master/'+course_m3u8_id[0]+'.m3u8?class_id='+class_id[0]
        course_m3u8_contect = requests.get(course_m3u8_url,headers=headrer).text.replace('\\/','/')
        course_m3u8_contect = course_m3u8_contect.encode('utf-8','ignore').decode('unicode-escape','ignore')
        course_m3u8_down_url = re.compile('http.*?\.m3u8',re.S).findall(course_m3u8_contect)[0]
        # 读取m3u8文件原始内容
        m3u8_res = requests.get(course_m3u8_down_url,headers=headrer).text
        m3u8_res = m3u8_res.encode('utf-8','ignore').decode('unicode-escape','ignore')
 
        URI = 'https://service.sanjieke.cn/video/key/'+course_m3u8_id[0]
        key = requests.get(URI,headers=headrer).content
        iv = re.compile('IV=0x(.*)').findall(m3u8_res)
 
        ts_url = re.compile('(https://vcdn.*)').findall(m3u8_res)
        file_url = r'./' + course_title + r'./ ' + str(i).rjust(2, '0') + ' ' + course_id_name[1] + '.mp4'  #构造文件下载地址
 
        for k in range(len(iv)):
            # 获取ts文件的内容
            ts_contrect = requests.get(ts_url[k])
            # 解密ts文件
            cryptor = AES.new(key, AES.MODE_CBC, bytes.fromhex(iv[k]))
            # 下载ts文件
            with open(file_url, 'ab') as f:
                f.write(cryptor.decrypt(ts_contrect.content))
            print(' 正在下载片段'+str(k).rjust(2, '0') + ' ' + course_id_name[1] + '.MP4')
        print(str(i).rjust(2, '0') + ' ' + course_id_name[1] + '.MP4' + ' 下载成功!')
        i = i + 1
print(course_title +'下载完成!')


补充:
  • python版本3.8.0
  • 编译器pycharm
  • 如果报错了,先检查是不是安装了相应的模块
  • 如果都安装了还报错,欢迎在评论中回复

如果对你有帮助不妨免费评分走一波,谢谢!

如果对你有帮助不妨免费评分走一波,谢谢!

如果对你有帮助不妨免费评分走一波,谢谢!

免费评分

参与人数 15吾爱币 +21 热心值 +12 收起 理由
daydreamleo + 1 + 1 谢谢@Thanks!
ghoob321 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
忧伤_ + 1 + 1
mdjvboy + 1 + 1 谢谢@Thanks!
you2012 + 2 + 1 谢谢@Thanks!
shuai23long + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
maoxingren + 1 + 1 谢谢@Thanks!
siweitang + 1 用心讨论,共获提升!
aa008u + 1 + 1 用心讨论,共获提升!
jiededav + 1 + 1 谢谢@Thanks!
华月方昊 + 1 谢谢@Thanks!
Right_Hai + 1 用心讨论,共获提升!
云的彼岸918 + 1 + 1 大佬希望能出个抓取优酷视频的教程,现在优酷大多数都是加密的视频,获取m3.
swj330702 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
janebos 发表于 2021-6-29 16:51
中国大学mooc的已付费课程得不到m3u8地址,这种有办法吗?
推荐
cool98eng 发表于 2020-4-3 20:04
本帖最后由 cool98eng 于 2020-4-3 20:27 编辑
长河落 发表于 2020-4-3 13:29
你这个链接是m3u8中的一个ts切片,这个ts切片是经过加密的所以你没办法直接读取,这个是你打不开的原因
...

原网页是这里的音频https://weixin.kaishustory.com/ksweb/player?id=122013&type=7&productId=2928&pageSize=10&pageNo=1&contentType=3&moduleIndex=0
m3u8文件好像是这个https://cdn.kaishuhezi.com/m3u8-mp3-60-audio/d9843f4c-37b8-4b4a-b83f-ddb176413a88.mp3.a0.m3u8/index.m3u8?rfY3ySQgjoR1G5uxHIfhd7P%2B7LZPmiEE7P%2Bj0w2yDiW8MxqHS8%2FAjPHKMJpSJ9hh
KEY:   https://cdn.kaishuhezi.com/mcourse/m3u8/13082018/key/common.key
IV不知道要如何找?
头像被屏蔽
沙发
maoxingren 发表于 2020-3-17 21:50
3#
y294945022 发表于 2020-3-18 00:09
不错,楼主有机会往寻找API方面走走
4#
eshao2010 发表于 2020-3-18 12:42
感谢分享
5#
NULL2019 发表于 2020-3-18 13:40
某东方在线的可能楼主能搞定吗
6#
 楼主| 长河落 发表于 2020-3-18 19:33 |楼主
NULL2019 发表于 2020-3-18 13:40
某东方在线的可能楼主能搞定吗

你可以发个具体的视频网址上来,我有空的时候试试
7#
NULL2019 发表于 2020-3-18 21:25
本帖最后由 NULL2019 于 2020-3-18 21:26 编辑
长河落 发表于 2020-3-18 19:33
你可以发个具体的视频网址上来,我有空的时候试试

https://www.koolearn.com/
需要注册 我知道的有2种视频 一种是完整的,还有一种是视频跟讲义分离的

目前我用的是录屏大法,哈哈,太累了
8#
sharokku4869 发表于 2020-3-19 15:23
关于视频下载,各位大佬各显神通,感谢这么多大佬提供思路及方法还有工具。
9#
ciker_li 发表于 2020-3-19 16:25
要是能下载收费的就厉害了
10#
wdb8899 发表于 2020-3-19 18:09
有现成的解密工具可用吗
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-7 21:12

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表