河南工职培训自动学习流程实现
研究的是河南公职,其他地区的可参考流程实现。开发语言:.net core3.1 一、流程梳理要想实现软件自动学习,我们就得像如何把大象塞进冰箱一样,对需要做的事情进行拆分。
①那到底如何实现呢?
第一步:登陆,登陆后官网返回cookie或jwt的token,用于在下次请求时验证用户信息
第二步:罗列所有需要学习的课程。通过访问我的课程接口,获取到用户下的所有课程
第三步:发送学习数据包。很多初学者到了这一步大多都在研究视频播放进度,认为把课程的视频自动播放,就可以实现进度更新。然而并不是这样的,一般网站都会隔段时间进行一次发包请求,请求中必然携带课程信息和当前学习进度。
二、开始动工
所有抓包信息均可通过浏览器F12获取
第一步:抓登陆,点击登陆按钮后的第一条即为登陆包,简单易懂,发送了账号密码和验证码。获取验证码时会返回一个cookie,登陆时用此cookie作为发送cookie即可实现验证码验证
在winform程序中我们可以这样拼接实现
第二步:获取所有课程
通过点击学习->筛选网络格式后,发现一条(/study.do?action=getStudyList),通过getstudylist可以轻松判断这就是获取课程的关键包
第三步:发送关键数据,课程点进去后会有视频列表,此时返回的数据并非json格式,而是html格式,可以通过正则表达式获取,然后耐心看一下课,隔段时间会发一次数据包,分析数据包中的字段实现最后的关键方法
private void UpdatetextBox4(object str)
{
if (textBox4.InvokeRequired)
{
Action<string> actionDelegate = (x) => { this.textBox4.AppendText(x.ToString() + "\r\n"); };
this.textBox4.Invoke(actionDelegate, str);
}
else
{
this.textBox4.AppendText(str.ToString() + "\r\n");
}
}
static string Url = "http://hnpi.newzhihui.cn";
static string codeImageCookie = "";
private void Form1_Load(object sender, EventArgs e)
{
piccheck();
}
string[] needLearnYear;
void piccheck()
{
string url = "/validate.do";
HttpHelper http = new HttpHelper();
HttpItem item = new HttpItem()
{
URL = Url + url,
Method = "GET",
Accept = "text/html, application/xhtml+xml, */*",
ContentType = "text/html",
ResultType = ResultType.Byte,//返回数据类型,是Byte还是String
};
HttpResult result = http.GetHtml(item);
codeImageCookie = result.Cookie;
Bitmap bitmap = (Bitmap)byteArrayToImage(result.ResultByte);
pictureBox1.Image = bitmap;
}
private Image byteArrayToImage(byte[] Bytes)
{
MemoryStream ms = new MemoryStream(Bytes);
return Bitmap.FromStream(ms, true);
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox5.Text.Trim().Length == 0)
{
MessageBox.Show("请填写需要学习的年度", "登陆失败");
return;
}
needLearnYear = textBox5.Text.Trim().Split(',');
string request = newCookiePost("/frontLogin.do", $"loginName={textBox1.Text.Trim()}&password={textBox2.Text.Trim()}&roleType=1&vcode={textBox3.Text.Trim()}&unittitle=1&unit_syscode=1&type=1");
JObject jObject = JObject.Parse(request);
if (jObject["result"].ToString() != "success")
{
MessageBox.Show(jObject["error"].ToString(), "登陆失败");
return;
}
string classList = Post("/study.do?action=getStudyList", "studyState=", codeImageCookie);
JObject JclassList = JObject.Parse(classList);
if (JclassList["result"].ToString() != "success")
{
MessageBox.Show("获取课程信息失败", "提醒");
}
else
{
string list = JclassList["list"].ToString();
if (list.Length == 0)
{
MessageBox.Show("没有需要学习的课程", "提醒");
return;
}
JArray JAClassList = JArray.Parse(list);
for (int a = 0; a < JAClassList.Count; a++)
{
string year = JAClassList["year"].ToString();
if (!isusedLearn(year)) continue;
string name = JAClassList["name"].ToString();
string id = JAClassList["id"].ToString();
string userId = JAClassList["userId"].ToString();
UpdatetextBox4($"正在学习{year}年度-:{name}");
ToStudy(id, codeImageCookie);
}
}
UpdatetextBox4("学习完成");
}
bool isusedLearn(string year)
{
for (int a = 0; a < needLearnYear.Length; a++)
{
if (needLearnYear == year) return true;
}
return false;
}
void ToStudy(string id, string _cookie)
{
string Html = Get("/study.do?action=toStudy&id=" + id, _cookie);
string regexStr = "<div class=\"video-info\" onclick=['\"]*(\\S+)[\"']>";
Regex regex = new Regex(regexStr);
MatchCollection matchs = regex.Matches(Html);
foreach (Match match in matchs)
{
string m = match.Groups.Value;
string Id_1 = Between(m, "playVideo('", "','");
string Id_2 = Between(m, "','", "')");
int lastLearnTime = 0;
if (!GetVideoTime(Id_1, out lastLearnTime, _cookie)) continue;
int _nowLearn = lastLearnTime / 40;
bool islearnOver = false;
while (!islearnOver)
{
string _data = $"id={Id_1}&itemRate={_nowLearn}&wareRate={_nowLearn}&time={_nowLearn * 40}";
string updateItemRate = Post("/study.do?action=updateItemRate", _data, _cookie, true);
int itemRate = 0;
try
{
JObject JEnd = JObject.Parse(updateItemRate);
itemRate = int.Parse(JEnd["itemRate"].ToString());
UpdatetextBox4("当前进度:" + itemRate);
}
catch (Exception ex)
{
Console.WriteLine();
UpdatetextBox4("网络访问错误,频繁出现此错误的话请退出重登");
}
finally
{
if (itemRate >= 100)
{
islearnOver = true;
}
}
_nowLearn++;
}
}
}
bool GetVideoTime(string id, out int lastlearnTime, string _cookie)
{
lastlearnTime = 0;
string getWareItemDetail = Post("/study.do?action=getWareItemDetail", "id=" + id, _cookie, true);
JObject jobject = JObject.Parse(getWareItemDetail);
string data = jobject["data"].ToString();
JObject jdata = JObject.Parse(data);
int vTime = int.Parse(jdata["vtime"].ToString());
int uTime = int.Parse(jdata["playTime"].ToString());
lastlearnTime = uTime;
if (vTime == 0)
{
lastlearnTime = 0;
return true;
}
return vTime - uTime > 0 ? true : false;
}
string newCookiePost(string _url, string _data)
{
HttpHelper http = new HttpHelper();
HttpItem item = new HttpItem()
{
URL = Url + _url,
Cookie = codeImageCookie,
Method = "POST",
Accept = "text/html, application/xhtml+xml, */*",
ContentType = "application/x-www-form-urlencoded",
Postdata = _data,
ResultType = ResultType.String,
};
HttpResult result = http.GetHtml(item);
return result.Html;
}
string Post(string _url, string _data, string _cookie = "", bool iswww = false)
{
HttpHelper http = new HttpHelper();
HttpItem item = new HttpItem()
{
URL = Url + _url,
Postdata = _data,
Method = "POST",
Cookie = _cookie,
Accept = "text/html, application/xhtml+xml, */*",
ContentType = iswww ? "application/x-www-form-urlencoded" : "application/json",
ResultType = ResultType.String,
};
HttpResult result = http.GetHtml(item);
return result.Html;
}
string Get(string _url, string _cookie = "")
{
HttpHelper http = new HttpHelper();
HttpItem item = new HttpItem()
{
URL = Url + _url,
Method = "GET",
Cookie = _cookie,
Accept = "text/html, application/xhtml+xml, */*",
ContentType = "application/json",
ResultType = ResultType.String,
};
HttpResult result = http.GetHtml(item);
return result.Html;
}
string Between(string str, string leftstr, string rightstr)
{
try
{
int i = str.IndexOf(leftstr) + leftstr.Length;
string temp = str.Substring(i, str.IndexOf(rightstr, i) - i);
return temp;
}
catch
{
return "";
}
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
Url = "http://hnpi.newzhihui.cn";
piccheck();
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
Url = "http://hnpizy.newzhihui.cn";
piccheck();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
piccheck();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
Url = "http://hnpi.newzhihui.cn:81";
piccheck();
}
}
因为是winform程序,所以没有图形界面很难实现看懂代码,可以从后方链接中得到完整源码+可执行程序https://wwa.lanzoui.com/iUMGRwnr64h 现在有很多现成的工具 明次 发表于 2021-11-19 17:18
现在有很多现成的工具
对的,工具有很多,实现方法也大同小异{:1_919:}{:1_919:} 高手 纯练手玩 有过程分析,不错!
页:
[1]