python解決m3u8直播視頻的爬取


一、背景

在爬蟲方面包括圖片,文字,視頻,音頻等的獲取。受到速度的限制,視頻的爬取較為麻煩,因為視頻是進行切片處理的采取的方式是hls,這是蘋果公司制定的一個方案。它會把內容切片,用.m3u8進行組織,在m3u8里面記錄了斷點的位置,將所有的片段下載下來在拼接就可以連接成整個視頻。目前較大的視頻都是采取這樣的方式。同時m3u8的格式也可以被h5直接讀取,這樣從理論上和實際過程中解決了視頻的傳輸問題。模型圖如下。

二、文件信息

2.1 .m3u8的頭文件格式

用檢索我們可以在source/media中看到一個.m3u8的文件,通過對這個文件進行訪問,可以看到下面的結果。

這一部分包括了文件格式的定義,以及加密方式,和解密的密鑰。

# EXTM3U:.m3u8文件的格式定義 # EXT-X-KEY: 密鑰的信息 # METHOD: 加密的方法,這里采用的是AES-128的加密方式 # URI: 密鑰的地址,需要獲取訪問得到密鑰的信息 # IV: 偏移量,AES加密的方法,通過這個密鑰就可以解密,獲取正確的視頻信息

結果:

2.2 每個.ts的文件片段

每一個.m3u8的片段都包含了這個片段的密鑰,加密方法,用於解析視頻內容。

# EXINF:片段切割的大小,大概是10s左右 # v.f...:下載的地址,每一個.ts片段都保留一個地址,可能相同可能不同 # EXT-X-KEY:加密的方式和密鑰,每一個視頻都有一個密鑰,可能相同,可能不同 # METHOD:加密方式,AES-128的加密方式

結果

三、解密

3.1 PyCryptodome安裝

在有密鑰的情況下我們需要進行解密,不然下載的文件就是無法播放的。解密的方法參考加密的手法。這里的密鑰是AES,因此使用AES的解密方法去解密。

使用以下的指令安裝

# PyCryptodome的安裝,由於版本的問題,在使用AES模塊的時候,安裝PyCryptodome pip install PyCryptodome 

結果

3.2 構建解碼器與解碼

首先獲取到VI,然后獲取到key,構建一個解碼器

from Crypto.Cipher import AES url_key = "key.key"  # 省略寫法
content_key = requests.get(url_key).content  # 獲取key值
vi = "0x00000000000000000000000000000000"  # vi值一樣
vt = vi.replace("0x", "")[:16].encode()  # 偏移碼
ci = AES.new(content_key, AES.MODE_CBC, vt)  # 構建解碼器
content = requests.get(url_content_ts).content  # 獲取加密視頻內容
content_ts = ci.decrypt(content)  # 解碼ts中的二進制格式

3.3 對獲取的content解密

完整的代碼

import requests import os import re from Crypto.Cipher import AES url = "https://1252524126.vod2.myqcloud.com/9764a7a5vodtransgzp1252524126/0176cbbd5285890799673243539/drm/v.f230.m3u8?" data = { "time": "" } download_url = "https://1252524126.vod2.myqcloud.com/9764a7a5vodtransgzp1252524126/0176cbbd5285890799673243539/drm/"

""" 列舉一個單位格大小: #EXTINF:2.000000, v.f230.ts?start=0&end=158495&type=mpegts #EXT-X-KEY:METHOD=AES-128,URI="https://app.xiaoe-tech.com/get_video_key.php?edk=CiCTzP%2B6jBR9H5awSTdnrwcCQzZlldD%2BTYaAr%2FlaHOwsPBCO08TAChiaoOvUBCokYjRhNjFiNTgtMmVhNy00OWYxLTgwZGMtZTE0NTIyODc5YWIy&fileId=5285890799673243539&keySource=VodBuildInKMS",IV=0x00000000000000000000000000000000 """


def download(): url_key = "https://app.xiaoe-tech.com/get_video_key.php?edk=CiCTzP%2B6jBR9H5awSTdnrwcCQzZlldD%2BTYaAr%2FlaHOwsPBCO08TAChiaoOvUBCokYjRhNjFiNTgtMmVhNy00OWYxLTgwZGMtZTE0NTIyODc5YWIy&fileId=5285890799673243539&keySource=VodBuildInKMS" content_key = requests.get(url_key).content  # 獲取key值
    download_path = os.getcwd() + r"\download"
    if not os.path.exists(download_path): os.mkdir(download_path) m3u8_content = requests.get(url, params=data).text print(m3u8_content) exit() result = re.compile(r"v\.f230\.ts\?start=[0-9]+&end=[0-9]+&type=mpegts", re.S).findall(m3u8_content)  # 匹配.ts的文件地址
    vi = "0x00000000000000000000000000000000" vt = vi.replace("0x", "")[:16].encode()  # 偏移碼
    ci = AES.new(content_key, AES.MODE_CBC, vt)  # 構建解碼器
    for i in enumerate(result): print(f"正在下載:{i[0]}") content_ts = requests.get(download_url + str(i[1])).content with open(download_path + "\\" + str(i[0] + 1) + ".mp4", 'ab') as f: f.write(ci.decrypt(content_ts)) # 將內容解碼
 f.flush() if __name__ == '__main__': download()

3.4 合並片段

使用以下的指令合並得到的.ts片段

# 首先進入當前的目錄 download/*.ts cd download # 使用和並指令進行合並 # /b表示二進制 最后會在當前的目錄下面產生一個new.mp4的文件 copy /b *.ts new.mp4

四、總結

上述講述了.m3u8文件的爬取和解析方法,例如直播的爬取,或者是是視頻的爬取都涉及到上述的內容。此方法需要自己分析一下內容,沒有寫成接口的形式,同時這個解碼是AES-128的方式,在遇到其他加密方法自行查閱相關解碼方式。在下載之前先拿一個片段進行測試,如果可以在批量下載,使用一個可以讀取.ts文件的播放器。

五、參考:

下面的blog是一下參考

https://blog.csdn.net/weixin_40346015/article/details/102595690

https://www.jianshu.com/p/98756e274fa0

https://www.52pojie.cn/thread-971265-1-1.html

詳細的介紹:https://pakchoi.me/2016/06/21/hls-fe/

包安裝問題https://www.cnblogs.com/new-june/p/9401002.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM