jjjzw 发表于 2022-8-8 22:49

某小姐姐网站在线视频下载分析

本帖最后由 jjjzw 于 2022-8-8 23:47 编辑

近日某有一友张三,向我吐槽,有一视频网站只能在线观看,不能下载,体验很差。

我当即决定助人为乐,前去一探究竟!

## 分析网页

打开其中一个视频网页,https://???.?????.com/?/??e/p/279/2?8/69???21.html

控制台查看网络

![网络](https://s3.bmp.ovh/imgs/2022/08/08/e559c3173c35d27f.png)

原来是m3u8格式的视频。虽然没有学习过,但本着助人为乐的精神,我决定给好友写一个视频下载器。

> m3u8格式是utf-8格式的m3u文件,m3u文件是记录了一个按索引排序的多个.ts视频片段的文件。也就是将一个完整视频,先拆分成多个.ts视频片段,然后把这些.ts视频片段以地址形式存放进.m3u8的文件里。

既然是m3u8格式,重要的当然是m3u8文件的获取。这里有两个m3u8文件,检查两个index.m3u8文件

第一个:

https://????.???.xyz/v/71f97????18ec9080a2/index.m3u8

```txt
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3000000,RESOLUTION=720x406
3000kb/hls/index.m3u8
```

第二个:

https://????.???.xyz/v/71f97????18ec9080a2/3000kb/hls/index.m3u8

```txt
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="key.key"
#EXTINF:5,
l3VymExG.ts
#EXTINF:5,
4RfV0Lvj.ts
#EXTINF:0.08,
RVRxCjSO.ts
#EXT-X-ENDLIST
```

显然,第一个m3u8记录了真正的视频文件的地址,

第二个文件才是我们想要的,记录了该视频所有ts文件名和视频切片长度。

观察网页源码,发现视频控件通过`iframe`嵌入,其`src`属性包含了我们想要的文件地址

```html
<iframe src="images/m3u8/?url=https://????.???.xyz/v/71f97????18ec9080a2/index.m3u8" frameborder="0" allowtransparency="true" scrolling="YES" width="97%" height="340"></iframe>
```

上面的地址指向一个`video.js`来控制视频下载和播放,我们只需要其中m3u8的url。

因此给定一个网页,就可以得到视频的真实m3u8文件,从而下载视频。

此时下载到的视频是无法观看的,因为被加密了。

观察第二个m3u8文件内容,发现其中说明了视频的加密方式:

```txt
#EXT-X-KEY:METHOD=AES-128,URI="key.key"
```

也就是使用AES-128加密,密钥记录在`key.key`文件中

打开一个`key.key`文件,得到16位密钥:

```txt
d9a772b4cbee99ba
```

这里并没有给出偏移量iv,猜测默认为`b'0000000000000000'`。

至此得到了下载视频的完整流程:

获取m3u8->获取真实m3u8->下载视频



## python代码

使用`pycryptodome`库进行AES解密

完整代码如下:

```python
import requests
from bs4 import BeautifulSoup as bs
from Crypto.Cipher import AES
import re
import os
import time


global url1, key, lists


def get_m3u8(url, headers={}):# 获取m3u8url
    global url1, key
    print("获取m3u8文件...")
    url = re.findall("http{1,100}.m3u8", str(bs(requests.get(url, headers).content, "lxml").find(name="iframe")))
    print(url)
    url = re.findall('https{1,100}(?=index.m3u8)', url) + re.findall('{1,10}kb{1,100}.m3u8', str(bs(requests.get(url, headers={}).content, "lxml")))
    print(url)
    url1 = re.findall('https{1,100}(?=index.m3u8)', url)# 用于m3u8列表合并
    key = requests.get(url1 + "key.key", headers={}).text
    return url


def get(url, headers={}):# 返回m3u8内容
    return bs(requests.get(url, headers).content, "lxml")


def extract(text):# 提取m3u8文件列表
    global lists
    print("提取m3u8列表...")
    lists = re.findall("{1,10}.ts", str(text))
    return lists


def join_url(lists):# 拼接url
    lists1 = ["6"] * len(lists)
    for i in range(len(lists)):
      lists1 = url1 + lists
    return lists1


def download(lists, headers={}):# 下载ts文件
    lists_url = join_url(lists)
    if not os.path.exists("./ts"):
      os.makedirs("./ts")
    print("开始下载文件...")
    for i in range(len(lists)):
      print("正在下载:", lists, "(", str(i + 1), "/", str(len(lists)), ")")
      with open("./ts/" + lists, "wb") as f:
            f.write(decrypt(requests.get(lists_url, headers).content, key))
      time.sleep(1)


def decrypt(content, keys, iv=b'0000000000000000'):# AES解密
    cipher = AES.new(keys.encode('utf-8'), AES.MODE_CBC, iv)
    return cipher.decrypt(content)


def merge(filename):# 合并ts文件
    global lists
    print("开始合并文件...")
    f = open(filename + ".ts", "wb")
    for names in lists:
      with open("./ts/" + names, "rb") as f1:
            f.write(f1.read())
    f.close()
    print("合并完毕!")


def remove():# 删除ts文件
    pass


if __name__ == '__main__':
    urls = "https://???.?????.com/?/??e/p/279/2?8/69???21.html"
    download(extract(get(get_m3u8(urls))))
    merge("测试")
```

经过测试,下载得到了完整的视频文件。但是友人张三却道不好用,原来该网站视频通过不同cdn存储资源,每个视频m3u8都不一样,m3u8内容也十分奇怪,只能手动写每个视频的下载。我只能拍拍张三,劝其放下欲望,不如锻炼体魄(笑



## 总结

第一次接触m3u8格式的视频,终于知道论坛大佬们下载器的原理!(又为自己学到新知识而感到高兴)希望我的代码能给大家带来帮助(不是用来下载某种视频嗷

所写代码其中不足还请大佬们指点!

wren0315 发表于 2022-8-9 01:03

如果这种帖子打上马赛克 那将毫无意义

WuJ1n9 发表于 2022-8-9 09:14

cdl279 发表于 2022-8-9 08:26
IDM他不香吗

加密视频,还IDM呢啊

gblz 发表于 2022-8-8 22:54

想知道网站地址{:1_886:}

notifier 发表于 2022-8-8 22:55

不错,分享信息非常有帮助!

nfxq2020 发表于 2022-8-8 22:56

助人为乐

ldwz 发表于 2022-8-8 22:58

网址发我。我批判批判~~

jjjzw 发表于 2022-8-8 22:58

gblz 发表于 2022-8-8 22:54
想知道网站地址

给网址那就违规了{:1_886:}

shaunkelly 发表于 2022-8-8 23:03

没有网址怎么知道可以下载呢?

tianye20110206 发表于 2022-8-8 23:21

看本事下载了

jixingzi 发表于 2022-8-8 23:23

自动解析的路还有很长

sapin 发表于 2022-8-8 23:26

劝其放下欲望,不如锻炼体魄(笑

扎心了 (笑

话说问号替换地址个数都是对应的吗?辛苦了
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 某小姐姐网站在线视频下载分析