diff --git a/api/base.py b/api/base.py index cadcf3b..28d41d1 100644 --- a/api/base.py +++ b/api/base.py @@ -25,10 +25,12 @@ def get_random_seconds(): return random.randint(30, 90) -def init_session(isVideo: bool = False): +def init_session(isVideo: bool = False, isAudio: bool = False): _session = requests.session() if isVideo: _session.headers = gc.VIDEO_HEADERS + elif isAudio: + _session.headers = gc.AUDIO_HEADERS else: _session.headers = gc.HEADERS _session.cookies.update(use_cookies()) @@ -133,7 +135,11 @@ def get_enc(self, clazzId, jobid, objectId, playingTime, duration, userid): f"[{clazzId}][{userid}][{jobid}][{objectId}][{playingTime * 1000}][d_yHJ!$pdA~5][{duration * 1000}][0_{duration}]" .encode()).hexdigest() - def video_progress_log(self, _session, _course, _job, _job_info, _dtoken, _duration, _playingTime): + def video_progress_log(self, _session, _course, _job, _job_info, _dtoken, _duration, _playingTime, _type: str = "Video"): + if "courseId" in _job['otherinfo']: + _mid_text = f"otherInfo={_job['otherinfo']}&" + else: + _mid_text = f"otherInfo={_job['otherinfo']}&courseId={_course['courseId']}&" _url = (f"https://mooc1.chaoxing.com/mooc-ans/multimedia/log/a/" f"{_course['cpi']}/" f"{_dtoken}?" @@ -142,21 +148,23 @@ def video_progress_log(self, _session, _course, _job, _job_info, _dtoken, _durat f"duration={_duration}&" f"clipTime=0_{_duration}&" f"objectId={_job['objectid']}&" - f"otherInfo={_job['otherinfo']}&" - f"courseId={_course['courseId']}&" + f"{_mid_text}" f"jobid={_job['jobid']}&" f"userid={self.get_uid()}&" f"isdrag=3&" f"view=pc&" f"enc={self.get_enc(_course['clazzId'], _job['jobid'], _job['objectid'], _playingTime, _duration, self.get_uid())}&" f"rt=0.9&" - f"dtype=Video&" + f"dtype={_type}&" f"_t={get_timestamp()}") resp = _session.get(_url) return resp.json()["isPassed"] - def study_video(self, _course, _job, _job_info, _speed: float = 1): - _session = init_session(isVideo=True) + def study_video(self, _course, _job, _job_info, _speed: float = 1, _type: str = "Video"): + if _type == "Video": + _session = init_session(isVideo=True) + else: + _session = init_session(isAudio=True) _session.headers.update() _info_url = f"https://mooc1.chaoxing.com/ananas/status/{_job['objectid']}?k={self.get_fid()}&flag=normal" _video_info = _session.get(_info_url).json() @@ -172,7 +180,7 @@ def study_video(self, _course, _job, _job_info, _speed: float = 1): while not _isPassed: if _isFinished: _playingTime = _duration - _isPassed = self.video_progress_log(_session, _course, _job, _job_info, _dtoken, _duration, _playingTime) + _isPassed = self.video_progress_log(_session, _course, _job, _job_info, _dtoken, _duration, _playingTime, _type) if _isPassed: break _wait_time = get_random_seconds() diff --git a/api/config.py b/api/config.py index 251233c..bee24b8 100644 --- a/api/config.py +++ b/api/config.py @@ -11,4 +11,9 @@ class GlobalConst: "Referer": "https://mooc1.chaoxing.com/ananas/modules/video/index.html?v=2023-1110-1610", "Host": "mooc1.chaoxing.com" } + AUDIO_HEADERS = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", + "Referer": "https://mooc1.chaoxing.com/ananas/modules/audio/index_new.html?v=2023-0428-1705", + "Host": "mooc1.chaoxing.com" + } THRESHOLD = 3 \ No newline at end of file diff --git a/api/decode.py b/api/decode.py index bd08e58..219f93d 100644 --- a/api/decode.py +++ b/api/decode.py @@ -64,7 +64,7 @@ def decode_course_card(_text: str): if _temp: _temp = _temp[0] else: - return None + return None, None _cards = json.loads("{" + _temp + "}") _job_info = {} _job_list = [] diff --git a/api/exceptions.py b/api/exceptions.py index 5ee4788..ddbd536 100644 --- a/api/exceptions.py +++ b/api/exceptions.py @@ -1,5 +1,5 @@ from loguru import logger - +from requests.exceptions import JSONDecodeError class BaseException(Exception): def __init__(self, _msg: str = None): if _msg: diff --git a/main.py b/main.py index a19c3ea..2e852ac 100644 --- a/main.py +++ b/main.py @@ -3,8 +3,7 @@ import configparser from api.logger import logger from api.base import Chaoxing, Account -from api.exceptions import LoginError, FormatError - +from api.exceptions import LoginError, FormatError, JSONDecodeError def init_config(): parser = argparse.ArgumentParser(description='Samueli924/chaoxing') # 命令行传参 @@ -66,13 +65,9 @@ def init_config(): point_list = chaoxing.get_course_point(course["courseId"], course["clazzId"], course["cpi"]) for point in point_list["points"]: # 获取当前章节的所有任务点 - jobs=[] - job_info = None - try: - jobs,job_info = chaoxing.get_job_list(course["clazzId"], course["courseId"], course["cpi"], point["id"]) - except : - logger.warning(f"跳过错误章节 -> {point['title']}") - + jobs = [] + job_info = None + jobs, job_info = chaoxing.get_job_list(course["clazzId"], course["courseId"], course["cpi"], point["id"]) # 可能存在章节无任何内容的情况 if not jobs: continue @@ -81,7 +76,18 @@ def init_config(): # 视频任务 if job["type"] == "video": logger.trace(f"识别到视频任务, 任务章节: {course['title']} 任务ID: {job['jobid']}") - chaoxing.study_video(course, job, job_info, _speed=speed) + # 超星的接口没有返回当前任务是否为Audio音频任务 + isAudio = False + try: + chaoxing.study_video(course, job, job_info, _speed=speed, _type="Video") + except JSONDecodeError as e: + logger.warning("当前任务非视频任务,正在尝试音频任务解码") + isAudio = True + if isAudio: + try: + chaoxing.study_video(course, job, job_info, _speed=speed, _type="Audio") + except JSONDecodeError as e: + logger.warning(f"出现异常任务 -> 任务章节: {course['title']} 任务ID: {job['jobid']}, 已跳过") # 文档任务 elif job["type"] == "document": logger.trace(f"识别到文档任务, 任务章节: {course['title']} 任务ID: {job['jobid']}")