在外漂泊的IT人员,估计都有过过年买票难的问题吧。而且最近看到木鱼的12306抢票神器,一个字 牛。
想一想别人能做抢票软件,为什么我们就做不出来呢?(就算功能没那么强大,性能没那么好,好歹也给我把车次,联系人等抓取出来吧)
自己开工,提前准备:HttpWatch 抓包工具,其实也可以用IE FF自带的。只是我用习惯了懒得改了,而且可以把抓包后的保存等以后再看。
流程分析:
a.验证码请求
b.验证码验证
c.登陆
d.获取联系人
e.提交订单
技术难点:
1.验证码
2.IP限制
3.性能
大概先记录这么多吧。后续再补录吧。(标准想到哪做到哪的,要不得)
先看抓包信息吧
大概有以下流程
1.获取验证码: https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&{0}
注:{0}随机字符
看看Http head,没什么特别的,如下图:
2.异步验证输入的验证码是否正确: https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn
看看 Http Head,如下图:
看看PostData,如下图:
如图,提交了2个参数。
第一个参数rand 表示这个异步验证请求,是验证登陆用的(提交订单也是用这个地址,只是此参数不同)
第二个参数randCode就是重点了,是我们点选验证码的坐标位置组合成的。注意:请将上面空白以及左边空白位置考虑进去。如图下图:
去除空白部分后,将图片拆分成2行4列,用Rectangle[]保存
再分析下验证码响应的JSON,如下图:
注意看"msg":"TRUE".这个表示验证码验证通过
验证码验证通过后,就模拟登陆了:https://kyfw.12306.cn/otn/login/loginAysnSuggest
看看 Http Head,如下图:
看看PostData,如下图:
看看返回的Json,如下图:
注意"loginCheck":"Y"表示登陆通过。
ok,抓包分析完了,就模拟提交吧。我用的是HttpWebRequest(也可以考虑WebClient),用 CookieContainer 保存登陆信息。具体代码不贴了,直接下载源代码看看吧。 https://files.cnblogs.com/files/hujunmin/TicketBook.rar
遇到的问题:
不知道为什么,登陆后请求其他页面返回的编码乱了。后来发现,原来是12306开启了Gzip
1 using (WebResponse response = request.GetResponse()) 2 { 3 using (Stream stream = response.GetResponseStream()) 4 { 5 if (stream != null) 6 { 7 System.IO.StreamReader sr = new System.IO.StreamReader(new GZipStream(stream, CompressionMode.Decompress), charsetEncoding); 8 return sr.ReadToEnd().Trim(); 9 } 10 } 11 }