吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 13774|回复: 131
上一主题 下一主题
收起左侧

[Python 转载] 某小姐姐网站在线视频下载分析

    [复制链接]
跳转到指定楼层
楼主
jjjzw 发表于 2022-8-8 22:49 回帖奖励
本帖最后由 jjjzw 于 2022-8-8 23:47 编辑

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

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

分析网页

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

控制台查看网络

网络

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

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

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

第一个:

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

#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

#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属性包含了我们想要的文件地址

<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文件内容,发现其中说明了视频的加密方式:

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

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

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

d9a772b4cbee99ba

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

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

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

python代码

使用pycryptodome库进行AES解密

完整代码如下:

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[0-9A-Za-z.:/]{1,100}.m3u8", str(bs(requests.get(url, headers).content, "lxml").find(name="iframe")))[0]
    print(url)
    url = re.findall('https[0-9A-Za-z.:/]{1,100}(?=index.m3u8)', url)[0] + re.findall('[0-9]{1,10}kb[0-9a-zA-Z./]{1,100}.m3u8', str(bs(requests.get(url, headers={}).content, "lxml")))[0]
    print(url)
    url1 = re.findall('https[0-9A-Za-z.:/]{1,100}(?=index.m3u8)', url)[0]  # 用于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("[0-9A-Za-z]{1,10}.ts", str(text))
    return lists

def join_url(lists):  # 拼接url
    lists1 = ["6"] * len(lists)
    for i in range(len(lists)):
        lists1[i] = url1 + lists[i]
    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[i], "(", str(i + 1), "/", str(len(lists)), ")")
        with open("./ts/" + lists[i], "wb") as f:
            f.write(decrypt(requests.get(lists_url[i], 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格式的视频,终于知道论坛大佬们下载器的原理!(又为自己学到新知识而感到高兴)希望我的代码能给大家带来帮助(不是用来下载某种视频嗷

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

免费评分

参与人数 20吾爱币 +16 热心值 +16 收起 理由
junjia215 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
被偷了的落叶 + 1 + 1 谢谢@Thanks!
慕冬 + 1 + 1 学习了
CLZY + 1 + 1 我有一个朋友???
burpliu + 1 + 1 用心讨论,共获提升!
cocodeemo + 1 + 1 我很赞同!
zzc5794 + 1 我很赞同!
shalj + 1 + 1 热心回复!
pwp + 1 + 1 毫无意义,给个base64加密的地址,也不至于被这么多人喷
guofangjun110 + 1 热心回复!
ba11ab + 1 我很赞同!
zhaoqingdz + 1 我很赞同!
夜游星河 + 1 + 1 我很赞同!
FENGyongtang + 1 我很赞同!
phxi + 1 + 1 我很赞同!
Pather + 1 我很赞同!
xiaohu666 + 1 我很赞同!
局外人K + 1 我很赞同!
lemonrains + 1 + 1 用心讨论,共获提升!
notifier + 1 + 1 我很赞同!

查看全部评分

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

推荐
wren0315 发表于 2022-8-9 01:03
如果这种帖子打上马赛克 那将毫无意义
推荐
WuJ1n9 发表于 2022-8-9 09:14
沙发
gblz 发表于 2022-8-8 22:54
3#
notifier 发表于 2022-8-8 22:55
不错,分享信息非常有帮助!
4#
nfxq2020 发表于 2022-8-8 22:56
助人为乐
5#
ldwz 发表于 2022-8-8 22:58
网址发我。我批判批判~~
6#
 楼主| jjjzw 发表于 2022-8-8 22:58 |楼主
gblz 发表于 2022-8-8 22:54
想知道网站地址

给网址那就违规了
7#
shaunkelly 发表于 2022-8-8 23:03
没有网址怎么知道可以下载呢?
8#
tianye20110206 发表于 2022-8-8 23:21
看本事下载了
9#
jixingzi 发表于 2022-8-8 23:23
自动解析的路还有很长
10#
sapin 发表于 2022-8-8 23:26
劝其放下欲望,不如锻炼体魄(笑


扎心了 (笑

话说问号替换地址个数都是对应的吗?辛苦了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-25 00:09

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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