首先用Wireshark抓包分析。在浏览器中进入西电研究生院的登陆页面http://210.27.12.1:90/login.jsp, 抓包得到的结果如下:
1. 获取Cookie:
从图中可以看到,此时已从服务器那里得到了Cookie。我做了个测试,如果停留在这个页面时间过长,Cookie就会失效,此时即使输入正确的用户名和密码,也不会正常登陆,而是出现以下情况:
或者
所以PHP模拟登陆第一步要做的就是访问http://210.27.12.1:90/login.jsp这个url并获得Cookie.根据抓包截图,发现有Host、User-Agent、Accept、Accept-Language、Accept-Encoding、Connection、Cookie这7个参数。其中设置User-Agent的PHP语句为curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0'),其他的暂时不会,就先不管了。所以目前语句是这样的:
测试结果如下:
2. 验证:
由图中可以看到,这一步是要带着刚才获取到的Cookie和自己的用户名、密码向http://210.27.12.1:90/j_security_check 这个url POST数据,其中CURLOPT_USERAGENT设置为 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0',Accept和Accept-Language、Accept-Encoding、Connection、Content-Type、Content-Length应该不用管,Cookie值就是刚在第一步中获取到的,j_username和j_password则是需要用户填写的账号和密码,Referer自己构造,代码如下:
测试结果如下:
尼玛啊,又是400号错误。索性之前做过C#模拟登陆,这一步也是400,但是对于最终获取数据并无影响,先不管了。
3. 进入系统主页:
代码如下:
测试结果如下:
一开始我很疑惑,它不是应该把我主页的信息输出吗?后来想明白了,因为主页是用Frame实现的,自然没办法显示详细内容。
4. 获取成绩信息
代码如下:
测试结果如下:
Bingo! 拿到了。虽然最终实现了抓取目的,但还是有很多地方想不透彻。比如说在通过j_security_check进行验证的时候,用浏览器正常登陆的时候,向j_security_check POST数据后返回信息为:
标志码为302,可是PHP模拟登陆的时候,这一步的返回信息为:
标志码为400,且提示“Invalid direct reference to form login page”,为此我调试了半天,后来拿出以前的C#版本发现它在这一步也是这么个情况。难道模拟登陆时出现“Invalid direct reference to form login page”都可以忽略吗?求指点。