选课助手是如何炼成的
我们学校的教务系统采用了强智科技的数字化校园平台
文章图片
可能是因为发现和非ie浏览器有兼容问题,所以在创建XMLHttpRequest时加了一个条件(如下的 1==2 ),限制了非ie浏览器的正常运行:
if(window.XMLHttpRequest && 1==2 )
{
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType)
{
http_request.overrideMimeType("text/xml");
}
}
这在现在流通的win8.1+ie11上问题并不大,只是破灭了许多试图用手机浏览器抢课的孩童的美好心愿,很残忍
第二个比较大的问题是服务器并发性能差,如果是12点整开始选课,11点50就有点难以刷出登陆页了;开始选课之后,大多数人几分钟都是在等待课表被刷出来的状态,而且往往刷出来的是 “请与管理员联系” 在这种寸时寸金的时候,晚一秒钟,心仪的课就没了(比如只有30个名额的乒乓球),这个时候下行的流量率是非常大的:
GET /kdjw/xkglAction.do?method=toXk&xnxq=2014-2015-1&zzdxklbname=1&type=1&xkkssj=2014-09-01%2012:00&xkjzsj=2014-09-15%2000:00&tktime=1410266865000 HTTP/1.1
算了,懒得打码。从上面可以看出服务器使用了struts。 关键是学校蛋疼的把一个80多行的表格分为了两页:
文章图片
第一页显示50行,这样的处理,直接导致了下行更加拥堵,另一页还时常刷不出来,所以很多人都随便在第一页选了一门课就提交了。
而我的选课助手在这里做的改进就是只下载一次表格,然后把两张表的数据都显示出来,以后不再需要下行流量,只要服务器的session没有删除,什么时候都可以提交课表
文章图片
总的来说,我做的选课助手在速度上的优势在:
1、登录过一次后记住账号密码,只需要输入验证码(验证码识别模块因为识别率低,暂时没有加入,否则可能会更快些),这个在ie浏览器上是没有的。
2、减少了很多不必要的下载流量,比如网页、js文件、图片等等,整个下行只有登录页和课表页,三次服务器请求,大概500KB不到的流量。
3、减少了流程步骤。在ie流量器选课需要4-5次点击,而且在并发高的时候很容易中断,以至于无法进行下一次点击。
【选课助手是如何炼成的】当然还有更强大的策略选项,比如在不知道课表的情况下可以选包含某字符串的课程,或者发送多个请求知道请求被服务器响应为止等等。
最后说说在编码中得到的一些经验与收获,可能可以给看到这篇博文的人一个帮助。
1、强智平台在登录过程中需要向http://kdjw.hnust.cn/kdjw/Logon.do?method=logonBySSO 发送一个空白的post,才算正常的登录上了
文章图片
而正因为之前说的js屏蔽了非ie浏览器初始化XMLHttpRequest,导致非ie浏览器无法发送这个post,所以即使能请求出课表,也没有名为选中的链接。
2、因为请求到的网页字符串都是以utf8保存的,导致在转换到char *的时候输出乱码,这个时候需要转换编码,而网上找的转换函数都不太靠谱。这有个很好的函数,贴出来:
int ConvUtf8ToAnsi(CString& strSource, CString& strChAnsi)
{
if (strSource.GetLength() <= 0)
return 0;
CString strWChUnicode;
strSource.TrimLeft();
strSource.TrimRight();
strChAnsi.Empty();
int iLenByWChNeed = MultiByteToWideChar(CP_UTF8, 0,
strSource.GetBuffer(0),
strSource.GetLength(), //MultiByteToWideChar
NULL, 0);
int iLenByWchDone = MultiByteToWideChar(CP_UTF8, 0,
strSource.GetBuffer(0),
strSource.GetLength(),
(LPWSTR)strWChUnicode.GetBuffer(iLenByWChNeed * 2),
iLenByWChNeed);
//MultiByteToWideCharstrWChUnicode.ReleaseBuffer(iLenByWchDone * 2);
int iLenByChNeed= WideCharToMultiByte(CP_ACP, 0,
(LPCWSTR)strWChUnicode.GetBuffer(0),
iLenByWchDone,
NULL, 0,
NULL, NULL);
int iLenByChDone= WideCharToMultiByte(CP_ACP, 0,
(LPCWSTR)strWChUnicode.GetBuffer(0),
iLenByWchDone,
strChAnsi.GetBuffer(iLenByChNeed),
iLenByChNeed,
NULL, NULL);
strChAnsi.ReleaseBuffer(iLenByChDone);
if (iLenByWChNeed != iLenByWchDone || iLenByChNeed != iLenByChDone)
return 1;
return 0;
}
3、至于用到的libcurl、htmlcxx等等开源的库相关的知识,我会另外做一个贴记录下来,可能会对以后的人有帮助。
最后再描述一下整个思路:
先访问登陆页,保存cookie,这个cookie就是身份验证。然后带cookie把账号密码验证码post到登录servlet,判断一下返回的页面是不是登录成功,随后post空白正文到logonBySSO,这个时候再get选课单下来,用htmlcxx分析,把必要的字符串保存到文本中,随后弹出显示表格的对话框,解析文本并显示出来,其中选课的链接就保存到宽度为0的列中,方便解析。之后等待用户操作,当双击某行时,get此行课的选课链接,把返回的正文弹出啦,等待用户下一步操作,循环。
推荐阅读
- 热闹中的孤独
- 我要做大厨
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 爱就是希望你好好活着
- 太平之莲
- 知识
- 叙述作文
- 时间老了
- 清明,是追思、是传承、是感恩。
- 我错了,余生不再打扰