【运用Python环境多线程下载加密电视剧电影】

多线程下载加密电视剧电影

代码部分

#!/usr/bin/env python
# -*- coding:utf-8 -*-

# @Name:        多线程下载加密电视剧电影
# @File:        多线程下载加密电视剧电影.py
# @Author:      Ivan·艾凡
# @Description: 描述
# @CreateTime:  2023/11/8 11:11
# @UpdateTime:  2023/11/08 17:15
# @UpdateLog:   更新日志
# @IDE:         PyCharm
# @InAWord:     开始、就意味着结束,结束,就意味着另一个开始。
# --------------------------------------------------------
import os
import queue
import re
import subprocess
import threading
import time
import urllib.parse

import requests
from Cryptodome.Cipher import AES
from bs4 import BeautifulSoup

# 定义请求头

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 safari/537.36'}
# 电影播放页地址
video_url = 'http://www.edugansu.com/dongzuopian/93guojiliechedajieanmosikexingdong/2-1.html'  # 电影93列车大劫案之莫斯科行动
res = requests.get(video_url, headers=headers)
# print(res)
soup = BeautifulSoup(res.text, 'lxml')
# 文件名
file_name = soup.find('title').text.split('抢先')[0]
print(file_name)
# 1.电影的m3u8片段文件地址, 如果在播放页面html,script脚本中,用下面方法提取出来

'''
<script>
    var zanpiancms_player =
        {"player":"\/public\/","url":"https:\/\/hnzy.bfvvs.com\/play\/Yer2EgBe\/index.m3u8",
        "next":"http:\/\/m.hnxzdq.com\/vodplay\/64139-2-2.html","name":"hnm3u8","apiurl":null,"adtime":"0",
        "adurl":"\/\/cdn.97bike.com\/loading.html","copyright":0,"danmu":{"status":0}};
</script>
'''
# 提取video的index.m3u8
# m3u8_url_text = soup.select('div#cms_play > script')[0].text
# print(m3u8_url_text)
# 提取index.m3u8地址并去除\\
# m3u8_url = ''.join(re.findall('"url":"(.*?)","next":', m3u8_url_text)).replace('\\', '')

# 2.或者从network中查看index.m3u8,从请求头中复制地址
m3u8_url = 'https://hnzy.bfvvs.com/play/penkGqWa/index.m3u8'  # 电影93列车大劫案之莫斯科行动
print(m3u8_url)

# m3u8_list ts文件列表
ts_file_urls = requests.get(m3u8_url, headers=headers)
# # 正则去除 以下字段
# '''
# '#EXTM3U\n'
# '#EXT-X-VERSION:3\n'
# '#EXT-X-TARGETDURATION:6\n'
# '#EXT-X-PLAYLIST-TYPE:VOD\n'
# '#EXT-X-MEDIA-SEQUENCE:0\n'
# '#EXTINF:3,\n'
# '''
ts_file_urls = re.sub('#.*\n', '', ts_file_urls.text).replace('\n', ',').split(',')
# print(r'ts文件列表地址', ts_file_urls)
# 去除空值,生成新的ts文件列表
ts_file_new_list = [i for i in ts_file_urls if i != '']
print(r'ts文件列表地址', ts_file_new_list)
print(len(ts_file_new_list))


# 下载ts文件


def download_ts(urlQueue, aes, headers):
    while True:
        try:
            # 不阻塞的读取队列数据
            temp = urlQueue.get_nowait()
            url = temp[0]
            n = temp[1]
        except Exception as e:
            break
        response = requests.get(url, stream=True, headers=headers)
        ts_path = "./ts_cache/%06d.ts" % n  # 注意这里的ts文件命名规则 06代表0开头的6位数字, 如果是04则是0开头的4位数字
        with open(ts_path, "wb+") as file:
            for chunk in response.iter_content(chunk_size=1024):
                if chunk:
                    after = aes.decrypt(chunk)
                    file.write(after)
        print("视频流ts文件:%06d.ts 下载完成!" % n)


# 创建文件夹,去除文件夹命名特殊字符
current_dir = os.getcwd()  # 当前目录
print(current_dir)


def make_folder(folder_name):
    # 处理文件夹名称包含特殊字符
    folder_name = folder_name.replace('/', '_').replace(':', '_').replace('*', '_').replace('?', '_').replace('"', '_') \
        .replace('<', '_').replace('>', '_').replace('|', '_')

    # 处理包含空格的文件夹名称
    folder_name = folder_name.strip().replace(' ', '_')

    new_folder_name = folder_name
    new_folder_path = os.path.join(current_dir, new_folder_name)
    # 判断是否存在电影名称文件夹,若没有就创建文件夹
    if not os.path.exists(new_folder_path):
        os.makedirs(new_folder_path)
        print(f'文件夹名称为→{file_name}←的文件夹已成功创建!')
    else:
        print(f'文件夹名称为→{file_name}←的文件夹已存在!')


if __name__ == '__main__':
    # 请求index.m3u8文件
    r = requests.get(m3u8_url, headers=headers)
    urlQueue = queue.Queue()  # 存储ts文件的网址
    for i in r.text.split('\n'):
        if i.endswith('.ts'):
            urlQueue.put([urllib.parse.urljoin(m3u8_url, i), urlQueue.qsize()])
        elif 'URI' in i:
            URI = urllib.parse.urljoin(m3u8_url, re.findall('URI="(.*?)"', i)[0])  # 秘钥的网址
            print(URI)
            enc_key = requests.get(URI, headers=headers).content  # 得到秘钥
            aes = AES.new(enc_key, AES.MODE_CBC, enc_key)  # 通过秘钥新建解密器

    # 下面开始多线程下载
    startTime = time.time()
    threads = []
    # 可以适当调节线程数,进而控制抓取速度,数字越大越快,但下载的资源不清晰
    # 对于资源清晰度较低的资源,建议线程数为1
    threadNum = 1
    for i in range(threadNum):
        t = threading.Thread(target=download_ts, args=(urlQueue, aes, headers))
        threads.append(t)
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    endTime = time.time()
    print('完成ts下载, 所用时间: %s ' % (endTime - startTime), '秒')

    # 创建文件夹,并判断是否已存在
    make_folder(file_name)

    # 下面是执行cmd命令来合成ts视频
    ts_file_path = fr'{current_dir}\ts_cache\*.ts'
    video_file_path = fr'{current_dir}\{file_name}\{file_name}.ts'
    command = fr'copy/b {ts_file_path} {video_file_path}'
    output = subprocess.getoutput(command)
    print(fr'{file_name}.ts  已完成合并!')

    # 下面是把这一集所有的ts文件给删除
    file_list = []
    for root, dirs, files in os.walk('D:/Demo/python_demo/video_test/ts_cache'):
        for fn in files:
            p = str(root + '/' + fn)
            file_list.append(p)
    for i in file_list:
        os.remove(i)
    print(r'已删除ts视频流文件!')

下载完成效果图

在这里插入图片描述

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值