抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

这天,韩同学向我抱怨哎要刷学校培训机构的视频了,这得刷到什么时候啊。身为程序员的我,对这种重复性工作及其厌恶,立马掏出一手node,拿出黄鸟来,最终做出了这个刷课脚本。

分析探索

根据我的经验,一定是每个视频在播放的时候都会将观看记录上传到服务器,立刻抓包分析,果不其然,可以看到一条接口在频繁的上传watchTime,立刻锁定他!

拉到node作出代码来,发现可以将watchTime改成99999也不会报错,说明写的还是很烂的,没有验证。

function generatorTask(courseId,sectionId){
    const url = `http://39.107.255.238:88/blade-app/startStudy/saveOrUpdateWatchHistory?onlineCourseId=${courseId}&sectionId=${sectionId}&watchCourseType=1&watchTime=9999999`

    const data = {"onlineCourseId":courseId,"sectionId":sectionId,"watchCourseType":"1","watchTime":9999999}
    const headers = {
    "user-agent":"LM-V500N(Android/10) (com.example.lwd.uniapp/1.0) Weex/0.26.0 1440x3026" ,
        "Blade-Auth":authCode,
        "Content-Type":"application/json; charset=utf-8",
        Host:"39.107.255.238:88",
        Connection:"Keep-Alive",
        "Accept-Encoding":"gzip",
        "User-Type":'app', 
        Authorization:"Basic c2FiZXI6c2FiZXJfc2VjcmV0"
    }

    return axios.post(url,data,{
        headers
    })
}

那这只能刷一个视频,不如继续拓展一下,获取所有所学课程,获取所有课程的所有视频!

实现解决

最终做出来这个成品:

import axios from "axios"
const deep = 5
const authCode = "这里是authCode,抓包获得"
function generatorTask(courseId,sectionId){
    const url = `http://39.107.255.238:88/blade-app/startStudy/saveOrUpdateWatchHistory?onlineCourseId=${courseId}&sectionId=${sectionId}&watchCourseType=1&watchTime=9999999`

    const data = {"onlineCourseId":courseId,"sectionId":sectionId,"watchCourseType":"1","watchTime":9999999}
    const headers = {
    "user-agent":"LM-V500N(Android/10) (com.example.lwd.uniapp/1.0) Weex/0.26.0 1440x3026" ,
        "Blade-Auth":authCode,
        "Content-Type":"application/json; charset=utf-8",
        Host:"39.107.255.238:88",
        Connection:"Keep-Alive",
        "Accept-Encoding":"gzip",
        "User-Type":'app', 
        Authorization:"Basic c2FiZXI6c2FiZXJfc2VjcmV0"
    }

    return axios.post(url,data,{
        headers
    })
}

async function getCourseId(){
    function get(index){
        const url = `http://39.107.255.238:88/blade-app/startStudy/getOnlineClassInfoByDate?classDate=&size=2&current=${index}&type=0`
        const headers = {
            "Host":"39.107.255.238:88",
            "Connection":"Keep-Alive",
            "Accept-Encoding":"gzip",
            "Blade-Auth":authCode,
             "user-agent":"LM-V500N(Android/10) (com.example.lwd.uniapp/1.0) Weex/0.26.0 1440x3026"
        }
        return axios.get(url,{
            headers
        })
    }
    let res = []
    for(let i = 1;i <= deep;i++){
        res.push((await get(i)).data.data.records)
    }
    res = res.flat().map(elem=>elem.id)

    return res
}


// generatorTask().then(console.log)
function getCourseInfo(courseId){
 
    const url = `http://39.107.255.238:88/blade-app/startStudy/getOnlineCourseInfoById?id=${courseId}&classId=-1`
    const headers = {
        "Accept-Encoding":"gzip",
        "Connection":"Keep-Alive", 
        "Host":"39.107.255.238:88" ,
        "user-agent":"LM-V500N(Android/10) (com.example.lwd.uniapp/1.0) Weex/0.26.0 1440x3026" ,
        "Blade-Auth":authCode
    }
    
    return axios.get(url,{
        headers
    })
}

function extractId(courseId){
    return new Promise((resolve,reject)=>{
        try{
            getCourseInfo(courseId)
            .then((res)=>{
                return res.data.data.appOnlineChapterVOList
            })
            .then(list=>list.map((list)=>list.sectionVO))
            .then(element=>element.flat().map(el=>el.id))
            .then((ids)=>{
                resolve(ids)
            })
        }catch(e){
            reject(e)
        }
    })    
}

async function executer(){
    let courseIds = await getCourseId()
    for (let courseId of courseIds){
        const sectionIds = await extractId(courseId)
        for await(const sectionId of sectionIds){
            const flag = (await generatorTask(courseId,sectionId)).data.msg
            console.log('课程id:',courseId,'章节id:',sectionId,'状态:',flag)
        }
    }
}
executer()

,效果如图:

可能的设想

现在只能抓到用户的authcode,填到代码里跑,这实际应用起来不是很方便。

那做个登录,抓个登陆接口?

这个软件登录需要人脸验证,拍照就行。看着麻烦,哎。

目测如果密码没有加密的话,前面都顺利的话,还要存储人脸照片,上传验证。。。

够麻烦的,不过课也刷完了,无所谓了。

评论