这天,韩同学向我抱怨哎要刷学校培训机构的视频了,这得刷到什么时候啊。身为程序员的我,对这种重复性工作及其厌恶,立马掏出一手node,拿出黄鸟来,最终做出了这个刷课脚本。
分析探索
根据我的经验,一定是每个视频在播放的时候都会将观看记录上传到服务器,立刻抓包分析,果不其然,可以看到一条接口在频繁的上传watchTime,立刻锁定他!
拉到node作出代码来,发现可以将watchTime改成99999也不会报错,说明写的还是很烂的,没有验证。
function generatorTask(courseId,sectionId){
const url = `http://39.107.255.238:88/blade-app/startStudy/saveOrUpdateWatchHistory?onlineCourseId=${courseId}§ionId=${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}§ionId=${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¤t=${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,填到代码里跑,这实际应用起来不是很方便。
那做个登录,抓个登陆接口?
这个软件登录需要人脸验证,拍照就行。看着麻烦,哎。
目测如果密码没有加密的话,前面都顺利的话,还要存储人脸照片,上传验证。。。
够麻烦的,不过课也刷完了,无所谓了。