选课助手是如何炼成的

我们学校的教务系统采用了强智科技的数字化校园平台


可能是因为发现和非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); //MultiByteToWideChar
    
    strWChUnicode.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此行课的选课链接,把返回的正文弹出啦,等待用户下一步操作,循环。


你可能感兴趣的:(选课助手是如何炼成的)