写在最前:年前,学校某位领导参加了一个省级培训,他认为课程很好,想保存下来二天给他下属学习,故而让我把这视频down下来。
时间一晃就过去了大半年,我早已把这事忘得乙肝二静了,前几天他又问我,下好没,我谎称视频太多,才下得几集,并承诺清明下好。于是就准备大肝一次。
逆向了好半天,时间一点一滴地过去了,已经来到凌晨2点多,都模拟不出来,这里我就不赘述这个过程了。
无奈准备放弃,突然零机移动,既然我不能逆向怎么拿到视频地址,我直接复制服务器给的地址下载不就行啦?
直接上我的土办法:
1、既然服务器发送了课程的全部视频给我,还是json格式的:
2、那我不直接问ai写下载脚本就行啦:
3、稍等110秒,就出来脚本了:
4、打工搞成,给大家json和python玩玩:
[XML] 纯文本查看 复制代码 {
"status": 200,
"data": {
"id": "26359",
"code": "XMTSKC001002",
"name": "学校安全教育的定位、职责与标准",
"recommendLearnTime": 12,
"sectionCount": 0,
"teacher": "李雯",
"introduction": "<p> 课程站在学校安全教育实践的视角,通过理论阐述和案例分析,确定了学校安全教育的基本定位、讲解了学校安全教育的主要职责,明确了学校安全教育的实施标准,总结了学校安全教育的创新探索。本专题课程旨在为中小学校长和教师理解、设计和实施学校安全教育提供整体思路和重要启发。 </p>",
"resourceItemList": [
{
"itemId": "32047a9f-9aa0-439d-8349-49d0f8118388",
"parentItemId": "00000000-0000-0000-0000-000000000000",
"directory": false,
"itemName": "内容提要",
"resourceId": "441",
"resourceUrl": "https://doc.xiaoben365.com/Attachment/SCORM/86FCE567-4C8B-44DF-8247-F02D7028B881/intro.html",
"resourceType": "URL",
"breakPoint": 0,
"finished": true,
"lastTimeView": false
},
{
"itemId": "d31fadcc-1caf-44ba-a373-f451e76f9c27",
"parentItemId": "00000000-0000-0000-0000-000000000000",
"directory": true,
"itemName": "第一讲 学校安全教育的基本定位",
"breakPoint": 0,
"finished": false,
"lastTimeView": false
},
{
"itemId": "389fdd42-5577-4dd6-bdb3-7f9fa0e197d4",
"parentItemId": "d31fadcc-1caf-44ba-a373-f451e76f9c27",
"directory": false,
"itemName": "第一节 从法律、法规的要求看(一)",
"resourceId": "443",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/1_1_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 0,
"finished": true,
"lastTimeView": false
},
{
"itemId": "465760db-5912-4fe5-b757-92f49c982bd2",
"parentItemId": "d31fadcc-1caf-44ba-a373-f451e76f9c27",
"directory": false,
"itemName": "第二节 从法律、法规的要求看(二)",
"resourceId": "445",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/1_2_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 374,
"finished": true,
"lastTimeView": false
},
{
"itemId": "5cde65e3-f7c4-404f-b7f9-5bc1e66a38f6",
"parentItemId": "d31fadcc-1caf-44ba-a373-f451e76f9c27",
"directory": false,
"itemName": "第三节 从学校安全工作的构成看",
"resourceId": "447",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/1_3_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 476,
"finished": true,
"lastTimeView": false
},
{
"itemId": "9df8883e-29e5-4d59-9833-86ffc0c1ba7d",
"parentItemId": "d31fadcc-1caf-44ba-a373-f451e76f9c27",
"directory": false,
"itemName": "第四节 从安全教育在学校工作全局中的位置看",
"resourceId": "449",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/1_4_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 0,
"finished": true,
"lastTimeView": false
},
{
"itemId": "082b5d9b-db45-4749-96a8-216be496b457",
"parentItemId": "00000000-0000-0000-0000-000000000000",
"directory": true,
"itemName": "第二讲 学校安全教育的岗位职责",
"breakPoint": 0,
"finished": false,
"lastTimeView": false
},
{
"itemId": "02d42401-c8f6-4f31-9b0f-b20e6184501f",
"parentItemId": "082b5d9b-db45-4749-96a8-216be496b457",
"directory": false,
"itemName": "第一节 《学校岗位安全工作指导手册》介绍",
"resourceId": "451",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/2_1_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 788,
"finished": true,
"lastTimeView": false
},
{
"itemId": "35f6ea85-b5c3-46af-8814-642ea8540936",
"parentItemId": "082b5d9b-db45-4749-96a8-216be496b457",
"directory": false,
"itemName": "第二节 不同岗位教师的安全岗位职责(一)",
"resourceId": "453",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/2_2_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 1,
"finished": true,
"lastTimeView": false
},
{
"itemId": "57574909-4c68-48aa-944f-0bcfbfca3aff",
"parentItemId": "082b5d9b-db45-4749-96a8-216be496b457",
"directory": false,
"itemName": "第三节 不同岗位教师的安全岗位职责(二)",
"resourceId": "455",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/2_3_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 5,
"finished": true,
"lastTimeView": false
},
{
"itemId": "2a701ffb-57ae-4a61-9fee-b529a5995973",
"parentItemId": "082b5d9b-db45-4749-96a8-216be496b457",
"directory": false,
"itemName": "第四节 使用要点",
"resourceId": "457",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/2_4_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 253,
"finished": true,
"lastTimeView": false
},
{
"itemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"parentItemId": "00000000-0000-0000-0000-000000000000",
"directory": true,
"itemName": "第三讲 学校安全教育的实施标准",
"breakPoint": 0,
"finished": false,
"lastTimeView": false
},
{
"itemId": "b8a65f5c-a550-449c-aef4-38abe48d9ba4",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第一节 基本情况",
"resourceId": "459",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_1_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 242,
"finished": true,
"lastTimeView": false
},
{
"itemId": "8cf37c0c-e751-4fcb-88e0-6051f35bef32",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第二节 学校安全教育的指导思想和目标",
"resourceId": "461",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_2_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 747,
"finished": true,
"lastTimeView": false
},
{
"itemId": "e101d0d1-0f24-4147-85a5-65784d1691e9",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第三节 学校安全教育的内容(一)分学段设置内容",
"resourceId": "463",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_3_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 165,
"finished": true,
"lastTimeView": false
},
{
"itemId": "66e93371-fa09-433f-8214-257eb36a3e4f",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第四节 学校安全教育的内容(二)六个内容模块",
"resourceId": "465",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_4_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 790,
"finished": true,
"lastTimeView": false
},
{
"itemId": "fb6f3bcd-a900-4766-88b6-1d538c74dffd",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第五节 学校安全教育的内容(三)不同学段内容的侧重点",
"resourceId": "467",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_5_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 555,
"finished": true,
"lastTimeView": false
},
{
"itemId": "3695338b-265d-4092-81bb-744ea065a825",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第六节 学校安全教育的内容(四)不同学段的模块安排(一)",
"resourceId": "469",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_6_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 448,
"finished": true,
"lastTimeView": false
},
{
"itemId": "b03b0dd0-b109-4673-a814-880cc3c60448",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第七节 学校安全教育的内容(五)不同学段的模块安排(二)",
"resourceId": "471",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_7_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 659,
"finished": true,
"lastTimeView": false
},
{
"itemId": "74289706-6203-496e-b044-a78ddea3e06b",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第八节 学校安全教育的内容(六)不同学段的模块安排(三)",
"resourceId": "473",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_8_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 691,
"finished": true,
"lastTimeView": false
},
{
"itemId": "ee3a913c-059c-4a91-a547-4462d5fe12d5",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第九节 学校安全教育的内容(七)不同学段的模块安排(四)",
"resourceId": "475",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_9_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 395,
"finished": true,
"lastTimeView": false
},
{
"itemId": "ad8e1139-c47b-4cf5-a576-f7528b89a262",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第十节 学校安全教育的内容(八)不同学段的模块安排(五)",
"resourceId": "477",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_10_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 207,
"finished": true,
"lastTimeView": false
},
{
"itemId": "62d0e4fa-7d93-41da-92c0-422b095a5e93",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第十一节 安全教育的实施原则、途径和方法",
"resourceId": "479",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_11_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 268,
"finished": true,
"lastTimeView": false
},
{
"itemId": "50ad30df-b6eb-4bcd-b811-0997f335c0d7",
"parentItemId": "15ec3146-ca0c-4267-b429-d9663d74965b",
"directory": false,
"itemName": "第十二节 学校安全教育的保障机制",
"resourceId": "481",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/3_12_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 182,
"finished": true,
"lastTimeView": false
},
{
"itemId": "0023840e-2d19-41b6-b942-af231639fa63",
"parentItemId": "00000000-0000-0000-0000-000000000000",
"directory": true,
"itemName": "第四讲 安全教育的实施原则、途径和方法",
"breakPoint": 0,
"finished": false,
"lastTimeView": false
},
{
"itemId": "eb26bde6-530c-44ef-97f3-6a61f42078b5",
"parentItemId": "0023840e-2d19-41b6-b942-af231639fa63",
"directory": false,
"itemName": "第一节 学校安全教育的创新探索(一)",
"resourceId": "483",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/4_1_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 0,
"finished": true,
"lastTimeView": true
},
{
"itemId": "ab826dc4-f266-46ec-8577-ad9bfdeed9a2",
"parentItemId": "0023840e-2d19-41b6-b942-af231639fa63",
"directory": false,
"itemName": "第二节 学校安全教育的创新探索(二)",
"resourceId": "485",
"resourceUrl": "https://gpmp4.open.com.cn/M604/guopei_mp4/2014/gz_ts/XMTS0901/4_2_g.mp4",
"resourceType": "VIDEO",
"breakPoint": 217,
"finished": true,
"lastTimeView": false
}
],
"reportLearnTime": false,
"selectedInRequired": false,
"selectedInOptional": true
},
"time": "1744160879956"
}
[Python] 纯文本查看 复制代码 import json
import os
import re
import requests
from uuid import UUID
def sanitize_filename(filename):
"""清理文件名中的非法字符"""
return re.sub(r'[\\/*?:"<>|]', '_', filename).strip()
# 从文件读取JSON数据
with open('mp4json.json', 'r', encoding='utf-8') as f:
data = json.load(f)
course_name = sanitize_filename(data['data']['name'])
save_dir = os.path.join(os.getcwd(), course_name)
os.makedirs(save_dir, exist_ok=True)
# 构建目录结构映射表
dir_structure = {}
for item in data['data']['resourceItemList']:
item_id = item['itemId']
if item['directory']:
dir_structure[item_id] = {
'name': sanitize_filename(item['itemName']),
'parent': item['parentItemId']
}
def get_full_path(item_id, path=[]):
if str(item_id) == '00000000-0000-0000-0000-000000000000':
return []
node = dir_structure.get(item_id, {})
if node.get('parent'):
return get_full_path(node['parent']) + [node['name']]
return [node['name']]
headers = {'User-Agent': 'Mozilla/5.0'}
for item in data['data']['resourceItemList']:
if item.get('resourceType') == 'VIDEO':
parent_id = item['parentItemId']
path_components = get_full_path(parent_id)
final_dir = os.path.join(save_dir, *path_components)
os.makedirs(final_dir, exist_ok=True)
video_name = sanitize_filename(item['itemName']) + '.mp4'
file_path = os.path.join(final_dir, video_name)
if os.path.exists(file_path):
print(f'Skipped: {file_path}')
continue
print(f'Downloading: {file_path}')
try:
with requests.get(item['resourceUrl'], headers=headers, stream=True, timeout=30) as r:
r.raise_for_status()
with open(file_path, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
print(f'Success: {file_path}')
except Exception as e:
print(f'Failed: {file_path}, Error: {str(e)}')
if os.path.exists(file_path):
os.remove(file_path)
print('All downloads completed!')
|