大家好,又见面了,我是你们的朋友全栈君。
目录 一、两者不同 二、爬虫源码 三、爬虫内容详解
一、两者不同
- m3u8 是一种基于 HTTP Live Streaming 文件视频格式,它主要是存放整个视频的基本信息和分片(Segment)组成。
- 相信大家都看过m3u8格式文件的内容,我们直来对比一下有什么不同,然后教大家怎么用python多进程实现下载并且合并。
- 非加密 的m3u8文件
- 加密 的m3u8文件
- 相信眼尖的小伙伴已经看出了2个内容的不同之处,对的,其实区别就在加密文件的第 5 行的 #EXT-X-KEY 的信息
- 这个信息就是用来视频内容解密的,其实里面的内容大多是一段字符串,其实也就是解密时候的KEY值
- 那么这个怎么去解密呢,我们暂时不管,我们先来解释一下每行的意思
- 第一行: #EXTM3U 声明这是一个m3u8的文件
- 第二行: #EXT-X-VERSION 协议的版本号
- 第三行: #EXT-X-MEDIA-SEQUENCE 每一个media URI 在 PlayList中只有唯一的序号,相邻之间序号 1
- 第四行: #EXT-X-KEY 记录了加密的方式,一般是AES-128以及加密的KEY信息
- 第五行: #EXTINF 表示这段视频碎片的持续时间有多久
- 第六行: sA3LRa6g.ts 视频片段的名称,获取的时候需要拼接上域名,找到文件的正确的路径
二、爬虫源码
代码语言:javascript复制#!/usr/bin/env python
# encoding: utf-8
'''
#-------------------------------------------------------------------
# CONFIDENTIAL --- CUSTOM STUDIOS
#-------------------------------------------------------------------
#
# @Project Name : 多进程M3U8视频下载助手
#
# @File Name : main.py
#
# @Programmer : Felix
#
# @Start Date : 2020/7/30 14:42
#
# @Last Update : 2020/7/30 14:42
#
#-------------------------------------------------------------------
'''
import requests, os, platform, time
from Crypto.Cipher import AES
import multiprocessing
from retrying import retry
class M3u8:
'''
This is a main Class, the file contains all documents.
One document contains paragraphs that have several sentences
It loads the original file and converts the original file to new content
Then the new content will be saved by this class
'''
def __init__(self):
'''
Initial the custom file by self
'''
self.encrypt = False
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0"
}
def hello(self):
'''
This is a welcome speech
:return: self
'''
print("*" * 50)
print(' ' * 15 'm3u8链接下载小助手')
print(' ' * 5 '作者: Felix Date: 2020-05-20 13:14')
print(' ' * 10 '适用于非加密 | 加密链接')
print("*" * 50)
return self
def checkUrl(self, url):
'''
Determine if it is a available link of m3u8
:return: bool
'''
if '.m3u8' not in url:
return False
elif not url.startswith('http'):
return False
else:
return True
def parse(self, url):
'''
Analyze a link of m3u8
:param url: string, the link need to analyze
:return: list
'''
container = list()
response = self.request(url).text.split('n')
for ts in response:
if '.ts' in ts:
container.append(ts)
if '#EXT-X-KEY:' in ts:
self.encrypt = True
return container
def getEncryptKey(self, url):
'''
Access to the secret key
:param url: string, Access to the secret key by the url
:return: string
'''
encryptKey = self.request("{}/key.key".format(url)).content
return encryptKey
def aesDecode(self, data, key):
'''
Decode the data
:param data: stream, the data need to decode
:param key: secret key
:return: decode the data
'''
crypt = AES.new(key, AES.MODE_CBC, key)
plain_text = crypt.decrypt(data)
return plain_text.rstrip(b'