某班题库技术分析(1)

对某班题库api的技术分析

因为某种原因需要在易班上进行练习校规校纪,非常好的平台,非常非常好。嗯~
作为社会主义接班人,当代优秀大学生,这么好的题不存下来慢慢学习,对不起自己,对不去社会啊!!!
在这里插入图片描述
然后默默的按下了f12,开发者模式
然后界面如下
在这里插入图片描述
然后seach 一下ajax,发现4个api
1./t/student/updateTraining
2./t/student/collectshiti
3./t/student/showMobileLSjAjax
4./t/student/errorfeedback
按照这个网页的设计的思路来讲,肯定有个报错反馈的api,肯定有个更新试题的api,有个加载页面基础布局的api
然后盲猜一波,
第一个api是请求试题,因为update 更新 traning 训练。嗯~就差不多了
第四个,带着error,那就是错误反馈
第二个 收集 shiti????(疯狂吐槽命名)。根据api所在上下文应该是收藏试题用的,就是收藏然后再次登录的时候错题本之类的就会有,嗯~,就先这样
第三个不知道干啥了emmm
盲猜完毕,开始检验,使用抓包工具,开始抓包
事实证明,盲从错误,啪啪打脸
/t/student/showMobileLSj是加载页面的
在这里插入图片描述
哪我们的目标是数据数据在哪?,当我重新刷新的时候,抓到两个包,第一个就是上面那个
第二个如下在这里插入图片描述
wow~数据在这/t/student/showMobileLSjAjax
哪我们重新理一下思路。
当我们点击题库连接时,发生了什么???
第一步初始化,初始化的时候先访问/t/student/showMobileLSj,加载基本布局,
随后访问/t/student/showMobileLSjAjax,加载数据,这样初始化完成
然后静默,等待用户操作,
如果出错访问/t/student/errorfeedback,
如果收藏访问/t/student/collectshiti,
如果刷新,访问/t/student/showMobileLSjAjax。
至于这个/t/student/updateTraining懒得管了。
数据分析
数据传回来是个json字符串,从外往里面来吧
在这里插入图片描述
最外面是statu msg 和date 嗯就是返回的格式,statu为状态码,msg为提示信息 date 为数据体,顺便说一句,这种形式很常见,后端就是一个dtoresponse这样的类,这样写的好处多多
然后看data
在这里插入图片描述
然后就是英文理解了,继续盲猜
collageid 学校的id
examtype 后面跟的一个应该是枚举的值,现在是1应该就是刷题模式
剩下的有时间慢慢猜
然后是data的对象一个是getshijuaninfor(吐槽命名)
没大用对于我们的目的
然后就是shitilist,emmm

本人非常好奇第一个的加密字符串,但是无奈不会解密啊
然后里面有的就是题和答案,答案在old_answer里面,俺不知道为啥叫 old answer

我们的目标数据完成了,也就不看了
下面分析api

在这里插入图片描述

api的分析
就是分析这个/t/student/showMobileLSjAjax
首先是参数,分析也不算分析,就是抄嘛!抄啥?当然是抓的包啦

在这里插入图片描述
四个参数,不巧上面的数据里面都有,就这个page ,然后多看几道题,发现就是随着题目的位置变化的,由上文可知,一共171道题,那么page的范围就是1-171的整数。
然后进行测试,使用postman,
测试注意的地方
我们是模拟发送请求,那么服务器一定要校验我们的请求是不是合法,对于这种请求,是一定要登录之后才能进行操作的,所以把网页的cookie 复制到herder里面。其余参数用formdate
测试成功。
个人感觉还有别的方法可以申请到试题
程序控制访问171次
这里采用c#演示

static void Main(string[] args)
        {
            Console.WriteLine("*****正在开始*****");
            for (int i = 1; i < 171; i++)
            {
                Console.WriteLine("正在开始第{0}个数据",i+1);
                Console.WriteLine("");
                Console.WriteLine("onloading!!!");
                var date = GetShiti(i + 1);
                WriteShiti(date);
                //我们是正经技术分析,不是攻击,所以速度放慢
                Thread.Sleep(800);
                Console.WriteLine("************************");
            }
        }
        public static Rootobject GetShiti(int num)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("courseid", "13036");
            dic.Add("coursename", "校规校纪题库");
            dic.Add("id", "13036");
            dic.Add("page", num.ToString());
            //请求头处理
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.yiban.cn/t/student/showMobileLSjAjax");
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
            request.Headers.Add("Cookie", "");
            #region 添加Post 参数
            StringBuilder builder = new StringBuilder();
            int i = 0;
            foreach (var item in dic)
            {
                if (i > 0)
                    builder.Append("&");
                builder.AppendFormat("{0}={1}", item.Key, item.Value);
                i++;
            }
            byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
            request.ContentLength = data.Length;
            using (Stream reqStream = request.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();
            }
            #endregion
            var resp = request.GetResponse();

            //获取响应内容
            string result = string.Empty;
            using (StreamReader reader = new StreamReader(resp.GetResponseStream(), Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            };
            Console.WriteLine(result);
            string json = result;
            result += "\r\n";
            result += "---分隔符---";
            WriteFile("jsondate.txt", result);
            return JsonConvert.DeserializeObject<Rootobject>(json);
        }
        public static void WriteShiti(Rootobject item)
        {
            string shiti = string.Empty;
            for (int i = 0; i < item.data.shitilist.Length; i++)
            {
                shiti += Encoding.Unicode.GetString(Encoding.Unicode.GetBytes(item.data.shitilist[i].title));
                shiti += "\r\n";
                for (int j = 0; j < item.data.shitilist[i].options.Length; j++)
                {
                    shiti+= Encoding.Unicode.GetString(Encoding.Unicode.GetBytes(item.data.shitilist[i].options[j]));
                    shiti += "\r\n";
                }
                string[] oldanwer = item.data.shitilist[i].old_answer.Split(',');
                for (int k = 0; k < oldanwer.Length; k++)
                {
                    switch (oldanwer[k])
                    {
                        case "1":
                            shiti += "A";
                            break;
                        case "2":
                            shiti += "B";
                            break;
                        case "3":
                            shiti += "C";
                            break;
                        case "4":
                            shiti += "D";
                            break;
                        case "5":
                            shiti += "E";
                            break;
                    }
                }
                shiti += "\r\n";
                shiti += "*****************************************************";
                shiti += "\r\n";
                WriteFile("shiti.txt", shiti);
            }
        }
        public static void WriteFile(string path,string content)
        {
            Console.WriteLine("开始写入文件");
            FileStream fs = null;
            string filePath = path;
            //将待写的入数据从字符串转换为字节数组  
            Encoding encoder = Encoding.UTF8;
            byte[] bytes = encoder.GetBytes(content);
            try
            {
                fs = File.OpenWrite(filePath);
                //设定书写的開始位置为文件的末尾  
                fs.Position = fs.Length;
                //将待写入内容追加到文件末尾  
                fs.Write(bytes, 0, bytes.Length);
                Console.WriteLine("写入文件完成");
            }
            catch (Exception ex)
            {
                Console.WriteLine("文件打开失败{0}", ex.ToString());
            }
            finally
            {
                fs.Close();
            }
        }

这样就把所有的题目给扒了下来。
我们算一下时间成本,单纯的扒题
两种方式,第一种就是复制黏贴,熟读快的话20s一个题,171个题,差不多也就是50min
第二种方式就是这样敲代码,我写了差不多两个小时吧emmm是有点慢。
我们只是为了把题存下来以后继续好好学习,看样子还是第一种比好好,所以大家还是复制黏贴扒题吧!

本文只是技术交流,如若用于不合规方面,后果自负

发布了19 篇原创文章 · 获赞 7 · 访问量 4050

猜你喜欢

转载自blog.csdn.net/weixin_43906877/article/details/103384713