记某平台课程学习快速通关

admin 2024年6月27日21:22:10评论2 views字数 5004阅读16分40秒阅读模式

0x01 前言

内容比较水很简单,这里主要记录一下后面可能还用得到。

接到通知要完成课程学习任务,占一定比例考试成绩,时长需要满差不多30个小时,头都大了。挨个看不知道要到啥时候,全部点开放到后台播放占用资源不说,且会出现加载不动的现象,效果很差。扫一眼看看有什么好办法吧。

0x02 分析     

首先得了解一下,它是如何记录保存课程学习时间的。

进入视频学习界面,播放视频,播放状态每过一分钟都会请求一次leaveCellLog接口,而且在暂停的时候也会触发,猜测主要目的是为了记录用户的学习进度、防止挂机、统计学习时长以及提供实时反馈。在每次请求发送之后学习进度确实会随之更新。

记某平台课程学习快速通关

观察请求包中的参数,尝试修改非id参数,并不会影响返回包中的时间计时。

记某平台课程学习快速通关

于是尝试回溯id参数,在cellDetail请求包中存在id值,推测这个请求应该就是播放视频的作用,id为对应视频课程标识。尝试之后也确实如此,结合leaveCellLog请求就可以保存观看进度。继续回溯cellId。

记某平台课程学习快速通关

在courseDirectory中存在callId的值,回溯courseOpenId。

记某平台课程学习快速通关

最后发现在list请求中存在courseOpenId的值。

记某平台课程学习快速通关

0x03 脚本编写   

梳理一下写脚本的思路。
1.发送list请求,获取所有课程的courseOpenId。
2.带着courseOpenId请求courseDirectoryProcess获取所有视频的cellId。
3.带着cellId请求cellDetail接口,播放视频,获取保存状态id。
4.发送leaveCellLog请求,每分钟保存学习进度。
import requestsimport jsonimport timeimport randomimport sysfrom concurrent.futures import ThreadPoolExecutor, as_completed# 全局配置BASE_URL = "xxx"PROXIES = {    "http": "http://127.0.0.1:8080",    "https": "http://127.0.0.1:8080"}# User-Agent 列表USER_AGENTS = [    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15",    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:82.0) Gecko/20100101 Firefox/82.0",    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"]def get_random_user_agent():    return random.choice(USER_AGENTS)def send_request(method, endpoint, jwt_token, data=None, params=None):    url = f"{BASE_URL}{endpoint}"    headers = {        "Host": "xxx",        "Accept": "application/json, text/plain, */*",        "access-token": jwt_token,        "User-Agent": get_random_user_agent(),        "Content-Type": "application/json;charset=UTF-8",        "Origin""xxx",        "Referer": "xxx",        "Accept-Encoding": "gzip, deflate",        "Accept-Language": "zh-CN,zh;q=0.9",        "Connection": "close"    }    response = requests.request(method, url, headers=headers, json=data, params=params)    if response.status_code == 200:        return response.json()    else:        print(f"请求 {endpoint} 失败,状态码: {response.status_code}")        return Nonedef get_course_open_ids(jwt_token):    # 第一步:发送list请求,获取所有课程的 courseOpenId    data = {        "isPass": 0,        "order": "",        "orderField": "",        "pageNum": 1,        "pageSize": 1000    }    response_data = send_request("POST", "/LearningSpace/list", jwt_token, data)    if response_data and response_data["code"] == "200":        courses = response_data["data"]["list"]        course_open_ids = list(set(course["id"] for course in courses))        print(f"找到 {len(course_open_ids)} 个课程开放ID。")        return course_open_ids    else:        return []def get_video_ids(course_open_id, jwt_token):    # 第二步:带着courseOpenId请求courseDirectoryProcess获取所有视频的cellId    params = {"courseOpenId": course_open_id}    response_data = send_request("GET", "/studyLearn/courseDirectoryProcess", jwt_token, params=params)    if response_data and response_data["code"] == "200":        video_ids = []        modules = response_data["data"]["moduleList"]        for module in modules:            for topic in module["topics"]:                for cell in topic["cells"]:                    if cell["subName"] == "视频":                        video_ids.append(cell["id"])        print(f"找到 {len(video_ids)} 个视频ID 对应课程开放ID: {course_open_id}。")        return video_ids    else:        return []def get_video_detail(cell_id, jwt_token):    # 第三步:带着cellId请求cellDetail接口,播放视频,获取保存进度的id    params = {"cellId": cell_id}    response_data = send_request("GET", "/studyLearn/cellDetail", jwt_token, params=params)    if response_data and response_data["code"] == "200":        cell_log_id = response_data["data"]["cellLogId"]        print(f"找到保存进度的ID: 视频日志ID {cell_log_id} 对应视频ID: {cell_id}。")        return cell_log_id    else:        return Nonedef save_study_progress(cell_log_id, jwt_token):    print(f"### 发送保存学习进度请求: 视频日志ID {cell_log_id} ###")    data = {        "id": cell_log_id,        "stopSeconds": 0,        "videoEndTime": 0    }    response_data = send_request("POST", "/studyLearn/leaveCellLog", jwt_token, data=data)    if response_data and response_data["code"] == "200":        print(f"成功发送保存学习进度请求: 视频日志ID {cell_log_id}")    else:        print("响应错误:", response_data["message"])def main(jwt_token):    # 第一步:获取所有课程开放ID    course_open_ids = get_course_open_ids(jwt_token)    if not course_open_ids:        print("未找到课程开放ID。")        return    # 第二步:获取所有视频ID    all_video_ids = []    for course_open_id in course_open_ids:        video_ids = get_video_ids(course_open_id, jwt_token)        if video_ids:            all_video_ids.extend(video_ids)    if not all_video_ids:        print("未找到视频ID。")        return    # 第三步:并发获取所有视频保存进度的ID    all_video_log_ids = []    with ThreadPoolExecutor(max_workers=6) as executor:        futures = [executor.submit(get_video_detail, video_id, jwt_token) for video_id in all_video_ids]        for future in as_completed(futures):            video_log_id = future.result()            if video_log_id:                all_video_log_ids.append(video_log_id)    if not all_video_log_ids:        print("未找到视频日志ID。")        return    # 第四步:并发处理所有视频日志ID    start_time = time.time()    duration = random.randint(17 * 60, 25 * 60)    end_time = start_time + duration    print(f"### 开始处理 {len(all_video_log_ids)} 个视频日志ID 的保存学习进度请求 ###")    while time.time() < end_time:        with ThreadPoolExecutor(max_workers=6) as executor:            futures = [executor.submit(save_study_progress, video_log_id, jwt_token) for video_log_id in all_video_log_ids]            for future in as_completed(futures):                future.result()        print(f"### 当前时间: {time.strftime('%Y-%m-%d %H:%M:%S')},休眠 60 秒,继续发送请求 ###")        time.sleep(60)if __name__ == "__main__":    if len(sys.argv) != 2:        print("用法: python script.py <jwt_token>")        sys.exit(1)    jwt_token = sys.argv[1]    main(jwt_token)

运行脚本: python script.py <jwt_token>

记某平台课程学习快速通关

记某平台课程学习快速通关

等个十几分钟的就满了。

记某平台课程学习快速通关

0x03 小密圈‍‍‍‍‍‍‍‍

最后送你一张优惠券,欢迎加入小密圈,好朋友。

记某平台课程学习快速通关

原文始发于微信公众号(小黑说安全):记某平台课程学习快速通关

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年6月27日21:22:10
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   记某平台课程学习快速通关https://cn-sec.com/archives/2892944.html

发表评论

匿名网友 填写信息