有道精品课
打开视频页面。视频业的链接以
https://live.youdao.com/ 开头
1.安装 篡改猴 ,篡改猴下载看这里
2.添加新脚本

3. 输入如下内容
// ==UserScript==
// @name 有道精品课 - MP4下载
// @namespace http://tampermonkey.net/
// @version 2025-09-14
// @description try to take over the world!
// @author You
// @match https://live.youdao.com/*
// @grant none
// @icon https://www.google.com/s2/favicons?sz=64&domain=deepseek.com
// ==/UserScript==
(function() {
'use strict';
// 交互界面 =======================================================================
function createStyles() {
const style = document.createElement('style');
style.textContent = `
.container {
background: red;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 200px;
position: fixed;
top: 0px;
right: 0px;
}
.input-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.user-input {
color: #28a745;
font-weight: bold;
}
button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
width: 100%;
font-size: 16px;
}
button:hover {
background-color: #45a049;
}
`;
document.head.appendChild(style);
}
// 创建页面结构
function createPage() {
// 创建容器
const container = document.createElement('div');
container.className = 'container';
// 创建输入组 - 提示信息
const messageGroup = document.createElement('div');
messageGroup.className = 'input-group';
const messageLabel = document.createElement('label');
messageLabel.textContent = '课程序号:';
messageLabel.htmlFor = 'promptMessage';
const messageInput = document.createElement('input');
messageInput.type = 'text';
messageInput.id = 'promptMessage';
messageInput.placeholder = '输入课程序号,建议使用2位';
// 创建按钮
const button = document.createElement('button');
button.id = 'demoBtn';
button.textContent = '下载';
messageGroup.appendChild(messageLabel);
messageGroup.appendChild(messageInput);
container.appendChild(messageGroup);
container.appendChild(button);
document.body.appendChild(container);
// 添加事件监听
button.addEventListener('click', function() {
window.localStorage.setItem('promptMessage', messageInput.value);
saveMP4()
});
}
function setIntpuValue(value){
const messageInput = document.getElementById('promptMessage');
messageInput.value = value;
}
function init() {
// 创建样式
createStyles();
// 创建页面元素
const elements = createPage();
// 默认值
let promptMessageValue = window.localStorage.getItem('promptMessage');
if(!promptMessageValue){
promptMessageValue = '01';
}else{
let v = parseInt(promptMessageValue)+1;
// 不足2位,补0
if(v<10){
promptMessageValue = '0'+v;
}else{
promptMessageValue = v;
}
}
setIntpuValue(promptMessageValue);
}
//document.addEventListener('DOMContentLoaded', init);
init()
// 下载处理 =======================================================================
const saveMP4 = function(context){
// mp4 地址
const mp4url = document.getElementById('myVideo_html5_api').src;
// 文件名 序号+标题+文件后缀
const fileName = document.getElementById('promptMessage').value +"."+ document.title + '.txt';
try {
const blob = new Blob([mp4url], { type: 'application/octet-stream' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
console.log('二进制内容已保存:', fileName);
} catch (e) {
console.error('处理二进制响应时出错:', e);
}
}
})();
4. 点击右侧的下载按钮,就会提示保存 .txt 文件,文件中是 mp4 的视频链接。将同一课程的所有视频都保存后,使用 python 批量下载。
5.使用python 代码批量下载
# pip install requests tqdm
import requests
import os
import warnings
from tqdm import tqdm # 用于显示进度条
# 抑制urllib3的SSL警告
warnings.filterwarnings('ignore', message='Unverified HTTPS request')
def download_mp4_with_headers(url, output_path, headers=None, verify_ssl=True):
"""
从URL下载MP4文件,支持自定义请求头
Args:
url (str): MP4文件的URL地址
output_path (str): 保存文件的本地路径
headers (dict): 自定义请求头,默认为None
verify_ssl (bool): 是否验证SSL证书,默认为True
"""
# 默认请求头,模拟浏览器行为
default_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.5',
'Connection': 'keep-alive',
}
# 合并默认请求头和自定义请求头
if headers:
final_headers = {**default_headers, **headers}
else:
final_headers = default_headers
try:
# 发送GET请求,stream=True表示流式下载
response = requests.get(
url,
headers=final_headers,
stream=True,
verify=verify_ssl,
timeout=30
)
response.raise_for_status() # 检查请求是否成功
# 获取文件总大小(如果服务器提供了Content-Length头)
total_size = int(response.headers.get('content-length', 0))
block_size = 8192 # 每次下载的块大小
# 创建输出目录(如果不存在)
dir_name = os.path.dirname(output_path)
if dir_name:
os.makedirs(dir_name, exist_ok=True)
# 使用进度条显示下载进度
with open(output_path, 'wb') as file, tqdm(
desc=output_path,
total=total_size,
unit='iB',
unit_scale=True,
unit_divisor=1024,
) as bar:
for chunk in response.iter_content(chunk_size=block_size):
if chunk:
size = file.write(chunk)
bar.update(size)
print(f"\n文件已成功保存到: {output_path}")
return True
except requests.exceptions.RequestException as e:
print(f"下载过程中出现错误: {e}")
return False
except Exception as e:
print(f"发生未知错误: {e}")
return False
# 单个文件下载
def download_single_file(url, output_path):
"""
从URL下载单个文件,支持自定义请求头
Args:
url (str): 文件的URL地址
output_path (str): 保存文件的本地路径
headers (dict): 自定义请求头,默认为None
verify_ssl (bool): 是否验证SSL证书,默认为True
"""
# 使用示例
video_url = url
output_file = output_path
# 自定义请求头(可选)
custom_headers = {
'Host':'stream.ydstatic.com',
'Range':'bytes=0-',
'Referer': "https://live.youdao.com/",
'User-agent':'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1',
}
# 下载文件
success = download_mp4_with_headers(
url=video_url,
output_path=output_file,
headers=custom_headers,
verify_ssl=False # 如果是自签名证书,可以设置为False
)
if success:
print("下载成功!")
else:
print("下载失败!")
if __name__ == "__main__":
# 使用示例
# 单个文件下载
# main(r'E:\111\【有道博闻美育】高端文学·秋实班\04.茅盾文学奖之《东藏记》一.m3u8')
# 批量下载
directory = r'E:\111\7.《实景课》'
# 遍历目录下的所有文件
for filename in os.listdir(directory):
# 检查文件是否为m3u8文件
if filename.endswith('.txt'):
# 构建完整的文件路径
txt_file_path = os.path.join(directory, filename)
# 读取文件内容
mp4_url = ""
with open(txt_file_path, 'r', encoding='utf-8') as file:
mp4_url = file.read()
print(f"当前文件: {mp4_url} ")
save_path = os.path.join(directory, filename.replace('.txt', '.mp4'))
print(f"保存路径: {save_path} ")
# 下载
download_single_file(mp4_url, save_path)
