Python 学习通(二)功能实现

查看 39|回复 2
作者:7c丶陪你   
接上文,修正Base64是编码,说成加密了{:1_925:}。上文Post登录后获取了Cookie和Userid后,Get课程空间后,获取CourseId、ClazzId、PersonId三个参数,为后面做准备。


1717077093538.jpg (116.55 KB, 下载次数: 0)
下载附件
2024-5-30 21:51 上传

前面的代码环节:用到lxml和fake_useragent库
[Python] 纯文本查看 复制代码
from fake_useragent import UserAgent
import requests as re
from lxml import html
def GetUser_agent():
    user_agent = UserAgent()
    return user_agent.random
def Get_Header():
    Header = {
        'user-agent': GetUser_agent(),
        'Connection': 'keep-alive',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        'Accept-Encoding': 'gzip, deflate, br',
    }
    return Header
def Get_Courselist(Cookie):
    header = Get_Header()
    header.update({'Host': 'mooc1-1.chaoxing.com'})
    Url = 'https://mooc1-1.chaoxing.com/mooc-ans/visit/courselistdata'
    Data = {
        'courseType': '1',
        'courseFolderId': '0',
        'baseEducation': '0',
        'superstarClass': '',
        'courseFolderSize': '0'
    }
    respones = re.post(url=Url, headers=header, data=Data, cookies=Cookie)
    if respones.status_code == 200:
        Htmltext = html.fromstring(respones.text)
        CourseLists = Htmltext.xpath('//*[@id="courseList"]/li')
        print(f'获取到{str(len(CourseLists))}个课程,分别是:')
        if len(CourseLists) != 0:
            Courseid = []
            Clazzid = []
            Personid = []
            for Count in range(len(CourseLists)):
                CourseTitle = Htmltext.xpath(
                    f'//*[@id="courseList"]/li[{str(Count + 1)}]/div[@class="course-info"]/h3/a/span/text()')[0]
                CourseTeacher = Htmltext.xpath(
                    f'//*[@id="courseList"]/li[{str(Count + 1)}]/div[@class="course-info"]/p[@class="line2"]/text()')[0]
                Courseid.append(Htmltext.xpath(
                    f'//*[@id="courseList"]/li[{str(Count + 1)}]/@courseid')[0])
                Clazzid.append(Htmltext.xpath(
                    f'//*[@id="courseList"]/li[{str(Count + 1)}]/@clazzid')[0])
                Personid.append(Htmltext.xpath(
                    f'//*[@id="courseList"]/li[{str(Count + 1)}]/@personid')[0])
                print(
                    f'{str(Count + 1)}、 第{str(Count + 1)}门课程名称:{CourseTitle}  教师:{CourseTeacher}')
            return True, Courseid, Clazzid, Personid
        else:
            print(f'课程数为{len(CourseLists)},无法继续进行下一步操作!')
            return False, "", "", ""
    else:
        print(f'获取课程信息失败,错误代码:{respones.status_code}')
        return False, "", "", ""
获取到CourseId、ClazzId、PersonId三个参数后,Get课程获取章节内容信息并判断当前课程是否有任务点和有多少个小节、获取ENC参数:


1717078975274.jpg (90.47 KB, 下载次数: 0)
下载附件
2024-5-30 22:23 上传

[Python] 纯文本查看 复制代码
def GetNotice(CourseChoose, UserId, Courseid, Clazzid, Personid, Cookie, SaveMP4, SavePPT, FinshPPTTask, FinshVideTask):
    Url = f'https://mooc2-ans.chaoxing.com/mooc2-ans/mycourse/studentcourse?courseid={Courseid[int(CourseChoose) - 1]}&clazzid={Clazzid[int(CourseChoose) - 1]}&cpi={Personid[int(CourseChoose) - 1]}&ut=s&t={str(Get_13Time())}'
    header = Get_Header()
    header.update({'Host': 'mooc2-ans.chaoxing.com'})
    respones = re.get(url=Url, headers=header, cookies=Cookie)
    if respones.status_code == 200:
        Htmltext = html.fromstring(respones.text)
        FishTask = int(Htmltext.xpath(
            '//*[@id="fanyaChapter"]/div[@class="fanyaChapterWhite"]/div[@class="chapter_head clearfix"]/h2/span/text()')[0])
        AllTask = int(Htmltext.xpath(
            '//*[@id="fanyaChapter"]/div[@class="fanyaChapterWhite"]/div[@class="chapter_head clearfix"]/h2/text()')[1].replace("/", ""))
        if FishTask  0:
                Enc = Htmltext.xpath('//*[@id="enc"]/@value')[0]
                print(f'获取Enc成功:{Enc}')
                print(f'该课程下有{str(len(ChapterNum))}个小节')
课程ENC获取到了之后,就该到章节的小节了,接着写顺带获取OpenEnc参数(进入小节会进行重定向),用于后面视频任务点的完成:


1717079112988.jpg (31.78 KB, 下载次数: 0)
下载附件
2024-5-30 22:25 上传

[Python] 纯文本查看 复制代码import re as refind
def get_textafter(text, keyword):
    pattern = refind.compile(f"{refind.escape(keyword)}(.*)")
    match = pattern.search(text)
    if match:
        return match.group(1)  # 返回匹配到的内容
    else:
        return ""
def GetNotice(CourseChoose, UserId, Courseid, Clazzid, Personid, Cookie, SaveMP4, SavePPT, FinshPPTTask, FinshVideTask):
    Url = f'https://mooc2-ans.chaoxing.com/mooc2-ans/mycourse/studentcourse?courseid={Courseid[int(CourseChoose) - 1]}&clazzid={Clazzid[int(CourseChoose) - 1]}&cpi={Personid[int(CourseChoose) - 1]}&ut=s&t={str(Get_13Time())}'
    header = Get_Header()
    header.update({'Host': 'mooc2-ans.chaoxing.com'})
    respones = re.get(url=Url, headers=header, cookies=Cookie)
    if respones.status_code == 200:
        Htmltext = html.fromstring(respones.text)
        FishTask = int(Htmltext.xpath(
            '//*[@id="fanyaChapter"]/div[@class="fanyaChapterWhite"]/div[@class="chapter_head clearfix"]/h2/span/text()')[0])
        AllTask = int(Htmltext.xpath(
            '//*[@id="fanyaChapter"]/div[@class="fanyaChapterWhite"]/div[@class="chapter_head clearfix"]/h2/text()')[1].replace("/", ""))
        if FishTask  0:
                Enc = Htmltext.xpath('//*[@id="enc"]/@value')[0]
                print(f'获取Enc成功:{Enc}')
                print(f'该课程下有{str(len(ChapterNum))}个小节')
                for Chaptercount in range(len(ChapterNum)):
                    Url = f'https://mooc1.chaoxing.com/mycourse/transfer?moocId={Courseid[int(CourseChoose) - 1]}&clazzid={Clazzid[int(CourseChoose) - 1]}&ut=s&refer='+quote(
                        f'https://mooc1.chaoxing.com/mycourse/studentstudy?chapterId={ChapterNum[Chaptercount].replace("cur", "")}&courseId={Courseid[int(CourseChoose) - 1]}&clazzid={Clazzid[int(CourseChoose) - 1]}&cpi={Personid[int(CourseChoose) - 1]}&enc={Enc}&mooc2=1', encoding='utf-8')
                    header = Get_Header()
                    header.update({'Host': 'mooc1.chaoxing.com'})
                    respones = re.get(url=Url, headers=header,
                                      cookies=Cookie, allow_redirects=False)
                    if respones.status_code == 302:
                        StudyUrl = respones.headers.get('Location')
                        OpenEnc = get_textafter(StudyUrl, 'openc=')
接着判断小节内现在存在未完成的任务点,以及即将实现的PPT和video文件下载(之前的selenium写过,PPT是把图片爬下来后合并pdf,视频链接也是从html文档里获取的):
获取小节PPT和Vide任务点的参数,Video参数:LiveId、Jobid;   PPT参数:Objectid


1717079402261.jpg (105.64 KB, 下载次数: 0)
下载附件
2024-5-30 22:30 上传

这个图片内容也是Html里面的,截图这个内容其实可以用json库去解析的(后面才发现的),可以自行改一下。
上代码:
[Python] 纯文本查看 复制代码
def get_textmiddle(Start, End, Text):
    Pattern = rf"{Start}(.*?){End}"
    result = refind.findall(Pattern, Text)
    if result:
        return result
    else:
        return ""
def GetNotice(CourseChoose, UserId, Courseid, Clazzid, Personid, Cookie, SaveMP4, SavePPT, FinshPPTTask, FinshVideTask):
    Url = f'https://mooc2-ans.chaoxing.com/mooc2-ans/mycourse/studentcourse?courseid={Courseid[int(CourseChoose) - 1]}&clazzid={Clazzid[int(CourseChoose) - 1]}&cpi={Personid[int(CourseChoose) - 1]}&ut=s&t={str(Get_13Time())}'
    header = Get_Header()
    header.update({'Host': 'mooc2-ans.chaoxing.com'})
    respones = re.get(url=Url, headers=header, cookies=Cookie)
    if respones.status_code == 200:
        Htmltext = html.fromstring(respones.text)
        FishTask = int(Htmltext.xpath(
            '//*[@id="fanyaChapter"]/div[@class="fanyaChapterWhite"]/div[@class="chapter_head clearfix"]/h2/span/text()')[0])
        AllTask = int(Htmltext.xpath(
            '//*[@id="fanyaChapter"]/div[@class="fanyaChapterWhite"]/div[@class="chapter_head clearfix"]/h2/text()')[1].replace("/", ""))
        if FishTask  0:
                Enc = Htmltext.xpath('//*[@id="enc"]/@value')[0]
                print(f'获取Enc成功:{Enc}')
                print(f'该课程下有{str(len(ChapterNum))}个小节')
                for Chaptercount in range(len(ChapterNum)):
                    Url = f'https://mooc1.chaoxing.com/mycourse/transfer?moocId={Courseid[int(CourseChoose) - 1]}&clazzid={Clazzid[int(CourseChoose) - 1]}&ut=s&refer='+quote(
                        f'https://mooc1.chaoxing.com/mycourse/studentstudy?chapterId={ChapterNum[Chaptercount].replace("cur", "")}&courseId={Courseid[int(CourseChoose) - 1]}&clazzid={Clazzid[int(CourseChoose) - 1]}&cpi={Personid[int(CourseChoose) - 1]}&enc={Enc}&mooc2=1', encoding='utf-8')
                    header = Get_Header()
                    header.update({'Host': 'mooc1.chaoxing.com'})
                    respones = re.get(url=Url, headers=header,
                                      cookies=Cookie, allow_redirects=False)
                    if respones.status_code == 302:
                        StudyUrl = respones.headers.get('Location')
                        OpenEnc = get_textafter(StudyUrl, 'openc=')
                        Url = f'https://mooc1.chaoxing.com/mooc-ans/knowledge/cards?clazzid={Clazzid[int(CourseChoose) - 1]}&courseid={Courseid[int(CourseChoose) - 1]}&knowledgeid={ChapterNum[Chaptercount].replace("cur", "")}&num=0&ut=s&cpi={Personid[int(CourseChoose) - 1]}'
                        respones = re.get(
                            url=Url, headers=header, cookies=Cookie)
                        if respones.status_code == 200:
                            TaskNum = int(respones.text.count('"enc":"'))
                            print(f'第{Chaptercount + 1 }个章节的任务数量:{TaskNum}')
                            # 判断是否存在直播视频,存在则不等于0   不存在则等于0
                            LiveId, Objectid,  = '', ''
                            docJosid, docJosToken, docknowledgeid, docClazzid, docCourseId, _dc = '', '', '', '', '', ''
                            videoisPassed, videoOtherInfo, videoJosid, videoobjectid, videoclazzId, videocourseid, videouserid, videofid,  videoduration, videoFaceCaptureEnc, videoknowledgeid = '', '', '', '', '', '', '', '', '', '', ''
                            if int(respones.text.count('","type":"live","')) != 0:
                                LiveId = get_textmiddle(
                                    'liveId":', ',"streamName', respones.text)
                                if LiveId != '':
                                    JobId = f'live-{LiveId}'
                                else:
                                    print('获取LiveId失败!')
                            if int(respones.text.count('","type":".pdf","')) != 0:
                                Objectid = get_textmiddle(
                                    '","objectid":"', '","_jobid":"', respones.text)
                                PPTname = get_textmiddle(
                                    '","name":"', '","mid":"', respones.text)
                            if SaveMP4 == 'True':
                                print('已开启自动保存mp4视频,将开始自动下载视频文件!')
                                print(f'当前章节视频文件数量为:{str(len(LiveId))}个文件')
                                if LiveId != '':
                                    for Livecount in range(len(LiveId)):
                                        Url = 'https://mooc1.chaoxing.com/ananas/live/liveinfo'
                                        querystring = {"liveid": LiveId[Livecount], "userid": UserId, "clazzid": Clazzid[int(
                                            CourseChoose) - 1], "knowledgeid": ChapterNum[Chaptercount].replace("cur", ""), "courseid": Courseid[int(CourseChoose) - 1], "jobid": JobId, "ut": "s"}
                                        respones = re.get(
                                            url=Url, headers=header, cookies=Cookie, params=querystring)
                                        if respones.status_code == 200:
                                            JsonData = respones.json()
                                            LiveTitle = JsonData['temp']['data']['title']
                                            LiveMp4url = JsonData['temp']['data']['mp4Url']
                                            File_size = down_from_url(
                                                LiveMp4url, Livevideo_path + f'\{LiveTitle}.mp4')
                                            if File_size != 0:
                                                print(
                                                    f'{LiveTitle}.mp4 视频下载完成!')
                                            else:
                                                print('章节视频下载异常,未知文件大小!')
                                        else:
                                            print('获取直播回放视频信息失败!')
                                else:
                                    print('当前章节不存在视频内容!')
                            else:
                                print('未开启mp4视频自动保存,将取消自动下载操作!')
                            if SavePPT == 'True':
                                print('已开启自动保存PPT文件,将开始自动下载PPT文件!')
                                print(f'当前章节PPT文件数量为:{str(len(Objectid))}个文件')
                                for pptcount in range(len(Objectid)):
                                    Url = 'https://mooc1.chaoxing.com/ananas/status/' + \
                                        Objectid[pptcount]
                                    header.update(
                                        {'Referer': 'https://mooc1.chaoxing.com/ananas/modules/pdf/index.html'})
                                    querystring = {
                                        "flag": "normal", "_dc": Get_13Time()}
                                    respones = re.get(
                                        url=Url, headers=header, cookies=Cookie, params=querystring)
                                    if respones.status_code == 200:
                                        JsonData = respones.json()
                                        PDFurl = JsonData['pdf']
                                        Filename = JsonData['filename']
                                        File_size = down_from_url(
                                            PDFurl, ppt_path + f'\{Filename}')
                                        if File_size != 0:
                                            print(f'{Filename} PPT下载完成!')
                                        else:
                                            print('章节PPT下载异常,未知文件大小!')
                                    else:
                                        print('获取PPT文件信息失败!')
                            else:
                                print('未开启PPT文件自动保存,将取消自动下载操作!')
接着获取秒完成PPT任务点的参数:jtoken、jobid、knowledgeid、courseid、clazzid、_dc(这个秒完成任务现在还没有校验,后面的秒完成视频有校验也还没解决,暂时不放了,个人感觉是这个参数的问题videoFaceCaptureEnc)
由于PPT任务点都完成了,抓包参数截不到图了。


1717079812663.jpg (20.96 KB, 下载次数: 0)
下载附件
2024-5-30 22:37 上传

[Python] 纯文本查看 复制代码                            if FinshPPTTask == 'True':  # 秒完成PPT任务点
                                Tasktype = get_textmiddle(
                                    'type":".', '","pagenum', respones.text)
                                if Tasktype != '':
                                    docJosToken = get_textmiddle(
                                        '"jtoken":"', '","property"', respones.text)[0]
                                    docJosid = get_textmiddle(
                                        'jobid":"', '","otherInfo', respones.text)[0]
                                    docknowledgeid = ChapterNum[Chaptercount].replace(
                                        "cur", "")
                                    docCourseId = Courseid[int(
                                        CourseChoose) - 1]
                                    docClazzid = Clazzid[int(CourseChoose) - 1]
                                    _dc = str(Get_13Time())
                                    Url = f'https://mooc1.chaoxing.com/ananas/job/document'
                                    Querystring = {"jobid": docJosid,
                                                   "knowledgeid": docknowledgeid,
                                                   "courseid": docCourseId,
                                                   "clazzid": docClazzid,
                                                   "jtoken": docJosToken,
                                                   "checkMicroTopic": "true",
                                                   "microTopicId": "undefined",
                                                   "_dc": _dc}
                                    respones = re.get(
                                        url=Url, headers=header, cookies=Cookie, params=Querystring, data="")
                                    if respones.status_code == 200:
                                        docJson = respones.json()
                                        docstatus = docJson['status']
                                        if docstatus == True:
                                            print('PPT任务点完成!')
                                        else:
                                            print('PPT任务点完成失败!')
                            sleep(
                                0.5)#延迟提交
视频任务点提交的参数:


1717080171294.jpg (49.58 KB, 下载次数: 0)
下载附件
2024-5-30 22:43 上传

啰嗦了一些,全部代码放出来(试过,现在依然可用,但是秒完成PPT哪里一定要延迟,不然抛个500 给你。
[Python] 纯文本查看 复制代码import json
import os
from fake_useragent import UserAgent
from time import sleep, time
import re as refind
from urllib.parse import quote
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import requests as re
import random
from lxml import html
import pyperclip
from tqdm import tqdm
def set_clipboard_text(text):
    pyperclip.copy(text)
    print("文本已成功设置到剪贴板!")
def GetUser_agent():
    user_agent = UserAgent()
    return user_agent.random
def get_textafter(text, keyword):
    pattern = refind.compile(f"{refind.escape(keyword)}(.*)")
    match = pattern.search(text)
    if match:
        return match.group(1)  # 返回匹配到的内容
    else:
        return ""
def get_textmiddle(Start, End, Text):
    Pattern = rf"{Start}(.*?){End}"
    result = refind.findall(Pattern, Text)
    if result:
        return result
    else:
        return ""
def Get_13Time():
    return int(time()*1000)
def Get_Header():
    Header = {
        'user-agent': GetUser_agent(),
        'Connection': 'keep-alive',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        'Accept-Encoding': 'gzip, deflate, br',
    }
    return Header
def EncryptAES(TransferKey, Encryptcontent):
    AesKey = TransferKey.encode('utf-8')
    Iv = TransferKey.encode('utf-8')
    Encrypttext = Encryptcontent.encode('utf-8')
    EncryptMode = AES.MODE_CBC
    Cipher = AES.new(key=AesKey, mode=EncryptMode, IV=Iv)
    EncrData = Cipher.encrypt(pad(Encrypttext, 16, 'pkcs7'))
    Data = base64.b64encode(EncrData).decode('utf-8')
    return Data
def LoginXXT(Username, Userpassword, TransferKey):
    username = EncryptAES(TransferKey, Username)
    userpassword = EncryptAES(TransferKey, Userpassword)
    Url = 'https://passport2.chaoxing.com/fanyalogin'
    header = Get_Header()
    header.update({'Host': 'passport2.chaoxing.com'})
    Data = {
        'fid': '-1',
        'uname': username,
        'password': userpassword,
        'refer': 'http://i.chaoxing.com',
        't': 'true',
        'forbidotherlogin': '0',
        'validate': '',
        'doubleFactorLogin': '0',
        'independentId': '0',
        'independentNameId': '0'
    }
    respones = re.post(url=Url, headers=header, data=Data)
    if respones.status_code == 200:
        JsonData = respones.json()
        Cause = JsonData['status']
        if Cause:
            Cookies = respones.cookies
            Cookie = re.utils.dict_from_cookiejar(Cookies)
            UserId = Cookie['_uid']
            return Cookie, UserId
        else:
            Cause = JsonData['msg2']
            print(f'登录失败,原因:{Cause}')
            return "", ""
    else:
        print(f'登录失败,POST错误代码:{respones.status_code}')
        return "", ""
def Get_Courselist(Cookie):
    header = Get_Header()
    header.update({'Host': 'mooc1-1.chaoxing.com'})
    Url = 'https://mooc1-1.chaoxing.com/mooc-ans/visit/courselistdata'
    Data = {
        'courseType': '1',
        'courseFolderId': '0',
        'baseEducation': '0',
        'superstarClass': '',
        'courseFolderSize': '0'
    }
    respones = re.post(url=Url, headers=header, data=Data, cookies=Cookie)
    if respones.status_code == 200:
        Htmltext = html.fromstring(respones.text)
        CourseLists = Htmltext.xpath('//*[@id="courseList"]/li')
        print(f'获取到{str(len(CourseLists))}个课程,分别是:')
        if len(CourseLists) != 0:
            Courseid = []
            Clazzid = []
            Personid = []
            for Count in range(len(CourseLists)):
                CourseTitle = Htmltext.xpath(
                    f'//*[@id="courseList"]/li[{str(Count + 1)}]/div[@class="course-info"]/h3/a/span/text()')[0]
                CourseTeacher = Htmltext.xpath(
                    f'//*[@id="courseList"]/li[{str(Count + 1)}]/div[@class="course-info"]/p[@class="line2"]/text()')[0]
                Courseid.append(Htmltext.xpath(
                    f'//*[@id="courseList"]/li[{str(Count + 1)}]/@courseid')[0])
                Clazzid.append(Htmltext.xpath(
                    f'//*[@id="courseList"]/li[{str(Count + 1)}]/@clazzid')[0])
                Personid.append(Htmltext.xpath(
                    f'//*[@id="courseList"]/li[{str(Count + 1)}]/@personid')[0])
                print(
                    f'{str(Count + 1)}、 第{str(Count + 1)}门课程名称:{CourseTitle}  教师:{CourseTeacher}')
            return True, Courseid, Clazzid, Personid
        else:
            print(f'课程数为{len(CourseLists)},无法继续进行下一步操作!')
            return False, "", "", ""
    else:
        print(f'获取课程信息失败,错误代码:{respones.status_code}')
        return False, "", "", ""
def down_from_url(url, dst):
    # 设置stream=True参数读取大文件
    response = re.get(url, stream=True)
    # 通过header的content-length属性可以获取文件的总容量
    file_size = int(response.headers['content-length'])
    if os.path.exists(dst):
        # 获取本地已经下载的部分文件的容量,方便继续下载,如果不存在就从头开始下载。
        first_byte = os.path.getsize(dst)
    else:
        first_byte = 0
    # 如果大于或者等于则表示已经下载完成,否则继续
    if first_byte >= file_size:
        return file_size
    header = {"Range": f"bytes={first_byte}-{file_size}"}
    pbar = tqdm(total=file_size, initial=first_byte,
                unit='B', unit_scale=True, desc=dst)
    req = re.get(url, headers=header, stream=True)
    with open(dst, 'ab') as f:
        # 每次读取一个1024个字节
        for chunk in req.iter_content(chunk_size=1024):
            if chunk:
                f.write(chunk)
                pbar.update(1024)
    pbar.close()
    return file_size
def videoEncode_enc(clazzid, userid, jobid, objectId, playtime, duration):
    import hashlib
    data = "[{0}][{1}][{2}][{3}][{4}][{5}][{6}][0_{7}]".format(
        clazzid, userid, jobid, objectId, playtime*1000, "d_yHJ!$pdA~5", duration*1000, duration)
    # [clazzid][userid][jobid][objectId][playtime*1000]["d_yHJ!$pdA~5"][duration*1000][0_duration]
    return hashlib.md5(data.encode()).hexdigest()
def UpVideoAsk(videoclazzId, videouserid, videoJobid, videoobjectid, playingTime, videoduration,videoOtherInfo,videocourseid,isdrag,videoFaceCaptureEnc,Url,VideoHeader,Cookie,Askupcount,upcount):
    videoEnc = videoEncode_enc(
        videoclazzId, videouserid, videoJobid, videoobjectid, playingTime, videoduration)
    Querystring = {"clazzId": videoclazzId,
                   "playingTime": playingTime,
                   "duration": videoduration,
                   "clipTime": "0_" + str(videoduration),
                   "objectId": videoobjectid,
                   "otherInfo": videoOtherInfo,
                   "courseId": videocourseid,
                   "jobid": videoJobid,
                   "userid": videouserid,
                   "isdrag": isdrag,
                   "view": "pc",
                   "enc": videoEnc,
                   "rt": "0.9",
                   "videoFaceCaptureEnc": videoFaceCaptureEnc,
                   "dtype": "Video",
                   "_t": str(Get_13Time())}
    print(Querystring)
    response = re.request(
        "GET", Url, headers=VideoHeader, params=Querystring, cookies=Cookie)
    if response.status_code == 200:
        Askstate = get_textmiddle(
            '"isPassed":', ',"videoTimeLimit"', response.text)
        if Askstate == True:
            print(
                '完成视频任务点!')
        else:
            print(f'已提交视频任务{Askupcount + 1}次,预计共需提交{upcount}次')
            sleep(
                random.randint(1, 3))
    else:
        print(
            f'请求任务失败{response.status_code}')
        sleep(
            random.randint(1, 3))
def GetNotice(CourseChoose, UserId, Courseid, Clazzid, Personid, Cookie, SaveMP4, SavePPT, FinshPPTTask, FinshVideTask):
    Url = f'https://mooc2-ans.chaoxing.com/mooc2-ans/mycourse/studentcourse?courseid={Courseid[int(CourseChoose) - 1]}&clazzid={Clazzid[int(CourseChoose) - 1]}&cpi={Personid[int(CourseChoose) - 1]}&ut=s&t={str(Get_13Time())}'
    header = Get_Header()
    header.update({'Host': 'mooc2-ans.chaoxing.com'})
    respones = re.get(url=Url, headers=header, cookies=Cookie)
    if respones.status_code == 200:
        Htmltext = html.fromstring(respones.text)
        FishTask = int(Htmltext.xpath(
            '//*[@id="fanyaChapter"]/div[@class="fanyaChapterWhite"]/div[@class="chapter_head clearfix"]/h2/span/text()')[0])
        AllTask = int(Htmltext.xpath(
            '//*[@id="fanyaChapter"]/div[@class="fanyaChapterWhite"]/div[@class="chapter_head clearfix"]/h2/text()')[1].replace("/", ""))
        if FishTask  0:
                Enc = Htmltext.xpath('//*[@id="enc"]/@value')[0]
                print(f'获取Enc成功:{Enc}')
                print(f'该课程下有{str(len(ChapterNum))}个小节')
                for Chaptercount in range(len(ChapterNum)):
                    Url = f'https://mooc1.chaoxing.com/mycourse/transfer?moocId={Courseid[int(CourseChoose) - 1]}&clazzid={Clazzid[int(CourseChoose) - 1]}&ut=s&refer='+quote(
                        f'https://mooc1.chaoxing.com/mycourse/studentstudy?chapterId={ChapterNum[Chaptercount].replace("cur", "")}&courseId={Courseid[int(CourseChoose) - 1]}&clazzid={Clazzid[int(CourseChoose) - 1]}&cpi={Personid[int(CourseChoose) - 1]}&enc={Enc}&mooc2=1', encoding='utf-8')
                    header = Get_Header()
                    header.update({'Host': 'mooc1.chaoxing.com'})
                    respones = re.get(url=Url, headers=header,
                                      cookies=Cookie, allow_redirects=False)
                    if respones.status_code == 302:
                        StudyUrl = respones.headers.get('Location')
                        OpenEnc = get_textafter(StudyUrl, 'openc=')
                        Url = f'https://mooc1.chaoxing.com/mooc-ans/knowledge/cards?clazzid={Clazzid[int(CourseChoose) - 1]}&courseid={Courseid[int(CourseChoose) - 1]}&knowledgeid={ChapterNum[Chaptercount].replace("cur", "")}&num=0&ut=s&cpi={Personid[int(CourseChoose) - 1]}'
                        respones = re.get(
                            url=Url, headers=header, cookies=Cookie)
                        if respones.status_code == 200:
                            TaskNum = int(respones.text.count('"enc":"'))
                            print(f'第{Chaptercount + 1 }个章节的任务数量:{TaskNum}')
                            # 判断是否存在直播视频,存在则不等于0   不存在则等于0
                            LiveId, Objectid,  = '', ''
                            docJosid, docJosToken, docknowledgeid, docClazzid, docCourseId, _dc = '', '', '', '', '', ''
                            videoisPassed, videoOtherInfo, videoJosid, videoobjectid, videoclazzId, videocourseid, videouserid, videofid,  videoduration, videoFaceCaptureEnc, videoknowledgeid = '', '', '', '', '', '', '', '', '', '', ''
                            if int(respones.text.count('","type":"live","')) != 0:
                                LiveId = get_textmiddle(
                                    'liveId":', ',"streamName', respones.text)
                                if LiveId != '':
                                    JobId = f'live-{LiveId}'
                                else:
                                    print('获取LiveId失败!')
                            if int(respones.text.count('","type":".pdf","')) != 0:
                                Objectid = get_textmiddle(
                                    '","objectid":"', '","_jobid":"', respones.text)
                                PPTname = get_textmiddle(
                                    '","name":"', '","mid":"', respones.text)
                            if SaveMP4 == 'True':
                                print('已开启自动保存mp4视频,将开始自动下载视频文件!')
                                print(f'当前章节视频文件数量为:{str(len(LiveId))}个文件')
                                if LiveId != '':
                                    for Livecount in range(len(LiveId)):
                                        Url = 'https://mooc1.chaoxing.com/ananas/live/liveinfo'
                                        querystring = {"liveid": LiveId[Livecount], "userid": UserId, "clazzid": Clazzid[int(
                                            CourseChoose) - 1], "knowledgeid": ChapterNum[Chaptercount].replace("cur", ""), "courseid": Courseid[int(CourseChoose) - 1], "jobid": JobId, "ut": "s"}
                                        respones = re.get(
                                            url=Url, headers=header, cookies=Cookie, params=querystring)
                                        if respones.status_code == 200:
                                            JsonData = respones.json()
                                            LiveTitle = JsonData['temp']['data']['title']
                                            LiveMp4url = JsonData['temp']['data']['mp4Url']
                                            File_size = down_from_url(
                                                LiveMp4url, Livevideo_path + f'\{LiveTitle}.mp4')
                                            if File_size != 0:
                                                print(
                                                    f'{LiveTitle}.mp4 视频下载完成!')
                                            else:
                                                print('章节视频下载异常,未知文件大小!')
                                        else:
                                            print('获取直播回放视频信息失败!')
                                else:
                                    print('当前章节不存在视频内容!')
                            else:
                                print('未开启mp4视频自动保存,将取消自动下载操作!')
                            if SavePPT == 'True':
                                print('已开启自动保存PPT文件,将开始自动下载PPT文件!')
                                print(f'当前章节PPT文件数量为:{str(len(Objectid))}个文件')
                                for pptcount in range(len(Objectid)):
                                    Url = 'https://mooc1.chaoxing.com/ananas/status/' + \
                                        Objectid[pptcount]
                                    header.update(
                                        {'Referer': 'https://mooc1.chaoxing.com/ananas/modules/pdf/index.html'})
                                    querystring = {
                                        "flag": "normal", "_dc": Get_13Time()}
                                    respones = re.get(
                                        url=Url, headers=header, cookies=Cookie, params=querystring)
                                    if respones.status_code == 200:
                                        JsonData = respones.json()
                                        PDFurl = JsonData['pdf']
                                        Filename = JsonData['filename']
                                        File_size = down_from_url(
                                            PDFurl, ppt_path + f'\{Filename}')
                                        if File_size != 0:
                                            print(f'{Filename} PPT下载完成!')
                                        else:
                                            print('章节PPT下载异常,未知文件大小!')
                                    else:
                                        print('获取PPT文件信息失败!')
                            else:
                                print('未开启PPT文件自动保存,将取消自动下载操作!')
                            if FinshPPTTask == 'True':  # 秒完成PPT任务点
                                Tasktype = get_textmiddle(
                                    'type":".', '","pagenum', respones.text)
                                if Tasktype != '':
                                    docJosToken = get_textmiddle(
                                        '"jtoken":"', '","property"', respones.text)[0]
                                    docJosid = get_textmiddle(
                                        'jobid":"', '","otherInfo', respones.text)[0]
                                    docknowledgeid = ChapterNum[Chaptercount].replace(
                                        "cur", "")
                                    docCourseId = Courseid[int(
                                        CourseChoose) - 1]
                                    docClazzid = Clazzid[int(CourseChoose) - 1]
                                    _dc = str(Get_13Time())
                                    Url = f'https://mooc1.chaoxing.com/ananas/job/document'
                                    Querystring = {"jobid": docJosid,
                                                   "knowledgeid": docknowledgeid,
                                                   "courseid": docCourseId,
                                                   "clazzid": docClazzid,
                                                   "jtoken": docJosToken,
                                                   "checkMicroTopic": "true",
                                                   "microTopicId": "undefined",
                                                   "_dc": _dc}
                                    respones = re.get(
                                        url=Url, headers=header, cookies=Cookie, params=Querystring, data="")
                                    if respones.status_code == 200:
                                        docJson = respones.json()
                                        docstatus = docJson['status']
                                        if docstatus == True:
                                            print('PPT任务点完成!')
                                        else:
                                            print('PPT任务点完成失败!')
                            sleep(
                                0.5)#延迟提交
                            if FinshVideTask == 'True':  # 完成视频观看任务点
                                Url = 'https://mooc1.chaoxing.com/mooc-ans/knowledge/cards'
                                Querystring = {"clazzid": Clazzid[int(CourseChoose) - 1],
                                               "courseid": Courseid[int(CourseChoose) - 1],
                                               "knowledgeid": ChapterNum[Chaptercount].replace("cur", ""),
                                               "num": "0",
                                               "ut": "s",
                                               "cpi": Personid[int(CourseChoose) - 1],
                                               "v": "20160407-3",
                                               "mooc2": "1"}
                                Videoheader = Get_Header()
                                Videoheader.update(
                                    {'Referer': f'https://mooc1.chaoxing.com/mycourse/studentstudy?chapterId={ChapterNum[Chaptercount].replace("cur", "")}&courseId={Courseid[int(CourseChoose) - 1]}&clazzid={Clazzid[int(CourseChoose) - 1]}&cpi={Personid[int(CourseChoose) - 1]}&enc={Enc}&mooc2=1&openc={OpenEnc}'})
                                Videoheader.update(
                                    {'Upgrade-Insecure-Requests': '1'})
                                responses = re.request(
                                    "GET", Url, data="", headers=Videoheader, params=Querystring, cookies=Cookie)
                                if responses.status_code == 200:
                                    AskInfo = get_textmiddle(
                                        'mArg = ', ',"isErya":0,"ut":"s"};', responses.text)[0] + ',"isErya":0,"ut":"s"}'
                                    JsonTaskData = json.loads(AskInfo)
                                    for Taskcount in range(len(JsonTaskData['attachments'])):
                                        Tasktype = JsonTaskData['attachments'][Taskcount]['type']
                                        if Tasktype == 'video':
                                            try:
                                                videoisPassed = JsonTaskData['attachments'][Taskcount]['isPassed']
                                                if videoisPassed == True:
                                                    print(
                                                        f'视频任务点完成状态:{videoisPassed}')
                                                elif videoisPassed == False:
                                                    raise Exception(
                                                        '当前任务未开始观看!')
                                            except:
                                                videoJobid = JsonTaskData['attachments'][Taskcount]['property']['_jobid']
                                                videoobjectid = JsonTaskData['attachments'][Taskcount]['property']['objectid']
                                                videoclazzId = JsonTaskData['defaults']['clazzId']
                                                videoknowledgeid = JsonTaskData['defaults']['knowledgeid']
                                                videocourseid = JsonTaskData['defaults']['courseid']
                                                videoFaceCaptureEnc = JsonTaskData['attachments'][
                                                    Taskcount]['videoFaceCaptureEnc']
                                                videoOtherInfo = JsonTaskData['attachments'][Taskcount]['otherInfo'].replace(
                                                    f"&courseId={videocourseid}", "")
                                                videouserid = UserId
                                                videofid = JsonTaskData['defaults']['fid']
                                                reportUrl = JsonTaskData['defaults']['reportUrl']
                                                Url = 'https://mooc1.chaoxing.com/mooc-ans/courseapi/getvideohotdata'
                                                Querystring = {"_dc": str(Get_13Time()),
                                                               "clazzid": videoclazzId,
                                                               "knowledgeid": videoknowledgeid,
                                                               "objectid": videoobjectid,
                                                               "courseid": videocourseid,
                                                               "cpi": Personid[int(CourseChoose) - 1],
                                                               "ut": "s"}
                                                VideoHeader = header
                                                VideoHeader.update(
                                                    {'Referer': 'https://mooc1.chaoxing.com/ananas/modules/video/index.html'})
                                                response = re.request(
                                                    "GET", Url, cookies=Cookie, headers=VideoHeader, params=Querystring)
                                                if response.status_code == 200:
                                                    JsonData = json.loads(
                                                        response.text)
                                                    restatus = JsonData['status']
                                                    if restatus == True:
                                                        
                                                        Url = r'https://mooc1.chaoxing.com/ananas/status/' + videoobjectid
                                                        Querystring = {"k": videofid,
                                                                       "flag": "normal",
                                                                       "_dc": str(Get_13Time())}
                                                        respones = re.get(
                                                            url=Url, headers=VideoHeader, cookies=Cookie, params=Querystring, data="")
                                                        if respones.status_code == 200:
                                                            JsonData = respones.json()
                                                            videoduration = JsonData['duration']
                                                            upcount = round(videoduration / 59)
                                                            countduration = videoduration
                                                            videodtoken = JsonData['dtoken']
                                                            Url = reportUrl + r'/' + videodtoken
                                                            Askupcount = 0
                                                            while True:
                                                                if Askupcount == 0:
                                                                    playingTime = 0
                                                                    isdrag = 3
                                                                    Askupcount += 1
                                                                    UpVideoAsk(videoclazzId, videouserid, videoJobid, videoobjectid, playingTime, videoduration,videoOtherInfo,videocourseid,isdrag,videoFaceCaptureEnc,Url,VideoHeader,Cookie,Askupcount,upcount)
                                                                else:
                                                                    Countnum = countduration - playingTime
                                                                    if Countnum >= 59:
                                                                        playingTime += 59
                                                                        isdrag = 4
                                                                        Askupcount += 1
                                                                        UpVideoAsk(videoclazzId, videouserid, videoJobid, videoobjectid, playingTime, videoduration,videoOtherInfo,videocourseid,isdrag,videoFaceCaptureEnc,Url,VideoHeader,Cookie,Askupcount,upcount)
                                                                    else:
                                                                        playingTime += Countnum
                                                                        isdrag = 4
                                                                        Askupcount += 1
                                                                        UpVideoAsk(videoclazzId, videouserid, videoJobid, videoobjectid, playingTime, videoduration,videoOtherInfo,videocourseid,isdrag,videoFaceCaptureEnc,Url,VideoHeader,Cookie,Askupcount,upcount)
                                                                        break
                                                        else:
                                                            print('获取提交次数失败!')
                                                    else:
                                                        print('请求获取提交次数失败!')
                            if FinshBroadcastTask == 'True':  # 完成直播回放观看
                                pass
                        else:
                            print('学习界面信息获取失败!')
                            return False
                    else:
                        print('获取OpenEnc失败!')
                        return False
                return True
            else:
                print('该课程下无章节内容!')
                return False
        elif FishTask == AllTask:
            print('任务点已全部完成!')
            return False
        elif FishTask > AllTask:
            print('未知错误!')
            return False
    else:
        print('获取课程章节信息失败!')
        return False
def Main(Username, Userpassword, TransferKey, SavePPT, SaveMP4, FinshPPTTask, FinshVideTask):
    Cookie, UserId = LoginXXT(Username, Userpassword, TransferKey)
    if Cookie != '' and UserId != '':
        print(f'获取UserId成功:{UserId}')
        print('登录成功,欢迎使用!正在获取课程内容,请稍等!(附随机延迟)')
        sleep(random.randint(1, 5))
        Boot, Courseid, Clazzid, Personid = Get_Courselist(Cookie)
        print(Personid)
        if Boot == True:
            CourseChoose = input('请选择您需要操作的课程:')
            Boot = GetNotice(
                CourseChoose, UserId, Courseid, Clazzid, Personid, Cookie, SaveMP4, SavePPT, FinshPPTTask, FinshVideTask)
            if Boot == True:
                print('已完成该课程全部任务!')
            else:
                print('获取课程信息失败!')
        else:
            print('获取课程内容失败!')
if __name__ == '__main__':
    global Livevideo_path, ppt_path
    File_path = os.path.join(os.path.dirname(__file__), 'Config.json')
    with open(File_path, 'r', encoding='utf8') as f:
        data = json.load(f)
    f.close()
    Livevideo_path = os.path.dirname(__file__) + '\Livevideo'
    ppt_path = os.path.dirname(__file__) + '\PPT'
    for Info in data['UserInfo']:
        Username = Info['Username']
        Userpassword = Info['Userpassword']
        SavePPT = Info['SavePPT']
        SaveMP4 = Info['SaveMP4']
        FinshPPTTask = Info['FinshPPTTask']
        FinshVideTask = Info['FinshVideTask']
        FinshBroadcastTask = Info['FinshBroadcastTask']
        if Username != '' and Userpassword != '':
            TransferKey = Info['TransferKey']
            if TransferKey != '':
                Main(Username, Userpassword, TransferKey, SavePPT, SaveMP4,
                     FinshPPTTask, FinshVideTask)
            else:
                print('加密密钥为空,无法登录!')
        else:
            print('账号或密码为空,无法登录!')
最后,有那个大佬把秒完成视频哪里解决了麻烦告知一下,谢谢!这个就停了,不再更新了,去年本来还有一个查互评的,硬盘坏了,懂的....

课程, 视频

iFinD   

能自动看课程吗?
编程天下   

这是获取哪平台的课程?
您需要登录后才可以回帖 登录 | 立即注册

返回顶部