统计
  • 建站日期:2022-01-17
  • 文章总数:5626 篇
  • 评论总数:50105条
  • 分类总数:43 个
  • 最后更新:2天前

腾讯课堂最新下载教程(支持企鹅账户、vx)

作者头像
首页 综合教程 正文
广告
广告

就把参数逆出来写了个脚本,比较简单,没加代{过}{滤}理池和多线程,为了防止可能被封加了个sleep。 修改下下面的地方为自己的就可以了

image.png

import re
import base64
import time

import requests
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import json

# 添加下载路径
save_path = "D:\\下载\\"

header = {
        "Host": "ke.qq.com",
        "Sec-Ch-Ua": '"Not.A/Brand";v="8", "Chromium";v="114", "Microsoft Edge";v="114"',
        "Sec-Ch-Ua-Mobile": "?0",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.43",
        "Sec-Ch-Ua-Platform": "Windows",
        "Accept": "*/*",
        "Sec-Fetch-Site": "same-origin",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Dest": "empty",
        "Referer": "https://ke.qq.com/webcourse/index.html",
        "Accept-Encoding": "gzip,deflate",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
}
download_header2 = {
        "Host": "1258712167.vod2.myqcloud.com",
        "Sec-Ch-Ua": '"Not.A/Brand";v="8", "Chromium";v="114", "Microsoft Edge";v="114"',
        "Sec-Ch-Ua-Mobile": "?0",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.43",
        "Sec-Ch-Ua-Platform": "Windows",
        "Accept": "*/*",
        "Origin": "https://ke.qq.com",
        "Referer": "https://ke.qq.com",
}
file_header = {
        "Host": "sngedu-10000074.file.myqcloud.com",
        "Sec-Ch-Ua": '"Not.A/Brand";v="8", "Chromium";v="114", "Microsoft Edge";v="114"',
        "Sec-Ch-Ua-Mobile": "?0",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.43",
        "Sec-Ch-Ua-Platform": "Windows",
        "Accept": "*/*",
        "Origin": "https://ke.qq.com",
        "Referer": "https://ke.qq.com",
}

def reformat(name):
    name = name.replace('\\', '')
    name = name.replace('/', '')
    name = name.replace('?', '')
    name = name.replace(':', '-')
    name = name.replace('*', '')
    name = name.replace('<', '')
    name = name.replace('>', '')
    name = name.replace('|', '')
    return name

def decrypt_sign(sign):
    key = sign[0:32]
    iv = sign[-16:]
    cipher_text = sign[32:-16]

    key = bytes(key, 'ascii')
    iv = bytes(iv, 'ascii')
    ciphertext = ""
    for pos in range(0, len(cipher_text), 2):
        char = int(cipher_text[pos:pos + 2], 16)
        ciphertext += chr(char)
    ciphertext = ciphertext.encode('iso-8859-1')

    encrypted_data = pad(ciphertext, 16)
    # 创建AES CBC解密器
    cipher = AES.new(key, AES.MODE_CBC, iv)

    # 使用解密器解密密文
    plaintext = cipher.decrypt(encrypted_data)
    key_decrypt = base64.b64decode(plaintext)
    return key_decrypt

def get_course_list(cid, tid):
    terms_url = "https://ke.qq.com/cgi-bin/course/get_terms_detail?cid="+ cid +"&term_id_list=%5B"+ tid +"%5D&bkn=&preload=1"
    content = requests.get(terms_url, headers=header).text
    tlist = json.loads(content)
    tlist = tlist['result']['terms'][0]['chapter_info'][0]['sub_info']
    return tlist

def get_course_info(cid, tid, vid):
    course_url = "https://ke.qq.com/cgi-proxy/rec_video/describe_rec_video?course_id=" + cid + "&file_id=" + vid + "&header=%7B%22srv_appid%22%3A201%2C%22cli_appid%22%3A%22ke%22%2C%22uin%22%3A%22"+ "此处添加自己的QQ" +"%22%2C%22cli_info%22%3A%7B%22cli_platform%22%3A3%7D%7D&term_id="+tid+"&vod_type=0"
    res = requests.get(course_url, headers=header)
    content = res.text
    course_info = json.loads(content)
    if course_info["result"]['rec_video_info']:
        course_info = course_info['result']['rec_video_info']
        url = course_info["infos"][0]['url']
        sign = course_info["d_sign"]
        return url, sign
    else:
        course_url = "https://ke.qq.com/cgi-proxy/rec_video/describe_rec_video?course_id=" + cid + "&file_id=" + vid + "&header=%7B%22srv_appid%22%3A201%2C%22cli_appid%22%3A%22ke%22%2C%22uin%22%3A%22"+ "此处添加自己的QQ" +"%22%2C%22cli_info%22%3A%7B%22cli_platform%22%3A103%7D%7D&term_id=" + tid + "&vod_type=0"
        res = requests.get(course_url, headers=header)
        content = res.text
        course_info = json.loads(content)
        course_info = course_info['result']['rec_video_info']
        url = course_info["infos"][0]['url']
        sign = course_info["d_sign"]
        return url, sign

def m3u8_download(m3u8_url, key, course_name):
    # requests得到m3u8文件内容
    content = requests.get(m3u8_url, headers=download_header2).text
    if "#EXTM3U" not in content:
        print("这不是一个m3u8的视频链接!")
        return False

    # download_header2.update({"host": url2.split('/')[2]})
    # 使用re正则得到key和视频地址
    EXT_KEY = re.findall('#EXT-X-KEY:(.*)\n', content)
    IV = re.findall('IV=0x(.*)', EXT_KEY[0])[0]
    IV = bytes.fromhex(IV)
    # 得到每一个ts视频链接
    ts_list = re.findall('EXTINF:(.*),\n(.*)\n#', content)
    host = re.findall(r'(.*)v.', m3u8_url)[0]
    new_list = []
    for ts in ts_list:
        new_list.append(host + ts[1])

    cryptor = AES.new(key, AES.MODE_CBC, IV)

    # for循环获取视频文件
    save_name = save_path + course_name + ".mp4"
    f = open(save_name, 'ab+')
    for ts_url in new_list:
        res = requests.get(ts_url, headers=download_header2)
        # 使用解密方法解密得到的视频文件
        cont = cryptor.decrypt(res.content)
        # 以追加的形式保存为mp4文件
        f.write(cont[16:])
        # sleep(0.2)
    f.close()

def file_download(cid, tid, t_id, fid, filename, aid):
    file_url = "https://ke.qq.com/cgi-bin/file/download?cid=" + cid + "&term_id=" + tid + "&taid=" + t_id + "&cw_id=" + str(fid) + "&a_id=" + str(aid)
    res = requests.get(file_url, headers=header, allow_redirects=False)
    url = res.headers["Location"]
    save_name = save_path + filename
    file = requests.get(url=url, headers=file_header, timeout=5)
    with open(save_name, 'wb') as f:
        f.write(file.content)
    return 0

if __name__ == '__main__':
    # web登陆后获取下述字段值填入
    cookies = "uid_uin=; uid_a2=; uid_origin_uid_type=0; uid_origin_auth_type=1003;"
    header.update({"cookie": cookies})
    download_header2.update({"cookie": cookies})
    # 添加课程链接
    url_host = "https://ke.qq.com/course/"
    course_id = re.findall(r'course/(.*)#', url_host)[0]
    term_id = re.findall(r'term_id=(.*)', url_host)[0]
    terms_list = get_course_list(course_id, term_id)
    # 跳过已经下载的课程数量
    complete = 15
    i = 0
    for term_info in terms_list:
        task_info = term_info['task_info']
        for course in task_info:
            if i < complete:
                i += 1
                continue
            if 'video' in course:
                video_id = course['video']['vid']
                course_name = course['name']
                # 去掉特殊符号
                course_name = reformat(course_name)
                # 获取课程信息
                m3u8, d_sign = get_course_info(course_id, term_id, video_id)
                decrypted_sign = decrypt_sign(d_sign)
                # 下载并解密
                m3u8_download(m3u8, decrypted_sign, course_name)
                print("downloaded :" + str(i))
                time.sleep(30)
            else:
                file_id = course['file']['cw_id']
                file_name = course['file']['cw_name']
                a_id = course['file']['cw_aid']
                t_id = course['taid']
                file_download(course_id, term_id, t_id, file_id, file_name, a_id)
                print("downloaded :" + str(i))
            i += 1

版权说明
文章采用: 《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权。
版权声明:本站资源来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系客服并出示版权证明以便删除!
LibreTube(免翻看油管)
« 上一篇 06-14
2023最新版建设银行P图软件,银行软件模拟(仅供娱乐)
下一篇 » 06-14

发表评论

  • 泡泡
  • 阿呆
  • 阿鲁
  • 蛆音娘
    没有更多评论了