C#利用HttpWebRequest、HttpWebResponse调用12306接口,实现登录、查票、买票。
2017-10-14 17:08
856 查看
【免责申明】本文只为学习使用,若有用作商业、其他行为,与本人无关。
使用工具
- UI bootstrap
- 后台C#
- 插件 datetimepicker.js,select.js
主要的技术还是利用HttpWebRequest、HttpWebResponse来调用12306的接口。
获取验证码接口:
调用的12306的接口获取文件流,然后出入二进制流。
校验验证码:12306的验证码是290px*190px的图片,每个照片分为8个小的图片。12306根据点击小图片的相对坐标。例如第二张小图片相对于整张的坐标(左上角为0,0)为50,90,。到时候post请求时候带的参数就是answer=50,90。
HttpWebRequest 模拟get请求:
因为12306是Https,所以有安全证书,和一般http请求有一些小的区别。
主要是12306业务的逻辑,例如查询火车的json数据很乱,本人也是一个一个对着12306的页面,才一一找到的业务的含义。
希望大家还是买票还是去12306上买,本文只为学习上使用。欢迎大家一起学习。
使用工具
- UI bootstrap
- 后台C#
- 插件 datetimepicker.js,select.js
UI界面效果预览
UI界面源码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no"> <title>火车抢票系统</title> <link href="css/bootstrap.min.css" rel="stylesheet" /> <link href="css/bootstrap-datetimepicker.min.css" rel="stylesheet" /> <link href="css/bootstrap-select.min.css" rel="stylesheet" /> <style> body{ width:90%; margin:0 5%; } table th{ text-align:center; } td{ text-align:center; } </style> </head> <body> <nav class="navbar navbar-default "> <div class="container-fluid"> <p class="navbar-text navbar-right" style="padding-right:5%;"> <a href="#" class="navbar-link" onclick="Login()"> 登录 </a><a href="#" class="navbar-link" onclik="LoginOut()"> 退出 </a></p> </div> </nav> <form class="form-horizontal" > <div class="form-group"> <label class="col-md-1 control-label">出发地</label> <div class="col-md-2"> <select class="selectpicker" data-live-search="true" id="FromStation"> </select> </div> <label class="col-md-1 control-label">目的地</label> <div class="col-md-2 "> <select class="selectpicker" data-live-search="true" id="ToStation"> </select> </div> <label class="col-md-1 control-label">出发日</label> <div class="col-md-2"> <input type="text" class="form-control" id="txtTranDate" placeholder="请输入出发日期"> </div> <div class="col-md-3"> <button type="button" class="btn btn-primary " id="btnSearch">查询</button> </div> </div> </form> <div> <table class="table table-bordered table-hover" > <thead style="background-color:turquoise"><tr><th>车次</th><th>出发站<br />到达站</th><th>出发时间<br />到达时间</th><th>历时</th><th>商务座<br />特等座</th><th>一等座</th><th>二等座</th><th>高级<br />软卧</th><th>软卧</th><th>动卧</th><th>硬卧</th><th>软座</th><th>硬座</th><th>无座</th><th>其他</th><th>备注</th></tr></thead> <tbody id="tbTranContent"></tbody> </table> </div> <script src="scripts/jquery-1.11.1.min.js"></script> <script src="scripts/bootstrap.min.js"></script> <script src="scripts/bootstrap-datetimepicker.min.js" ></script> <script src="scripts/locales/bootstrap-datetimepicker.zh-CN.js" charset="utf-8"></script> <script src="scripts/bootstrap-select.min.js"></script> <script src="scripts/layer/layer.js"></script> <script src="scripts/index.js"></script> </body> </html>
后台
主要的功能查询火车票、查询到站信息、查询价格、获取验证码、校验验证码、校验密码主要的技术还是利用HttpWebRequest、HttpWebResponse来调用12306的接口。
登录界面
获取验证码接口:
调用的12306的接口获取文件流,然后出入二进制流。
void GetValidateImg(HttpContext context) { #region 获取登录验证码 string url = "https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand"; Stream stream = GetStreamByGet(url); if (stream != null) { List<byte> bytes = new List<byte>(); int i = stream.ReadByte(); while (i != -1) { bytes.Add((byte)i); i = stream.ReadByte(); } context.Response.Clear(); context.Response.ContentType = "image/jpeg"; context.Response.BinaryWrite(bytes.ToArray()); } #endregion }
校验验证码:12306的验证码是290px*190px的图片,每个照片分为8个小的图片。12306根据点击小图片的相对坐标。例如第二张小图片相对于整张的坐标(左上角为0,0)为50,90,。到时候post请求时候带的参数就是answer=50,90。
void ValidateCode(HttpContext context) { #region 校验验证码 string answer = ""; if (!string.IsNullOrEmpty(context.Request["answer"])) answer = context.Request["answer"]; string url = "https://kyfw.12306.cn/passport/captcha/captcha-check";// string result = GetValidhtmlByPost(url, "answer=" + answer + "&login_site=E&rand=sjrand"); context.Response.Write(result); context.Response.End(); #endregion }
登陆
登陆需要post参数(username,password,appid)void Login(HttpContext context) { #region 登录 string username = ""; if (!string.IsNullOrEmpty(context.Request["username"])) username = context.Request["username"]; string password = ""; if (!string.IsNullOrEmpty(context.Request["password"])) password = context.Request["password"]; string url = "https://kyfw.12306.cn/passport/web/login"; string result = GetValidhtmlByPost(url, "username=" + username + "&password="+ password + "&appid=otn"); context.Response.Write(result); context.Response.End(); #endregion }
HttpWebRequest 模拟get请求:
因为12306是Https,所以有安全证书,和一般http请求有一些小的区别。
//回调验证证书问题 private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { // 总是接受 return true; } /// <summary> /// get请求(有证书验证) /// </summary> /// <param name="Url">URL</param> /// <returns></returns> private string GetValidhtmlByGet(string Url) { HttpWebRequest webRequest; HttpWebResponse webResponse; try { //这一句一定要写在创建连接的前面。使用回调的方法进行证书验证。 ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); b080 ServicePointManager.CheckCertificateRevocationList = true; webRequest = (HttpWebRequest)WebRequest.Create(Url); webRequest.Method = "GET"; webRequest.Accept = "*/*"; // 获取对应HTTP请求的响应 webResponse = (HttpWebResponse)webRequest.GetResponse(); // 获取响应流 Stream responseStream = webResponse.GetResponseStream(); // 对接响应流(以"utf-8"字符集) StreamReader reader = new StreamReader(responseStream, Encoding.UTF8); string result = reader.ReadToEnd(); reader.Close(); return result; } catch (Exception ex) { return ""; } } /// <summary> /// 获取文件流 /// </summary> /// <param name="Url"></param> /// <returns></returns> private Stream GetStreamByGet(string Url) { HttpWebRequest webRequest; HttpWebResponse webResponse; cookie = new CookieContainer(); try { //这一句一定要写在创建连接的前面。使用回调的方法进行证书验证。 ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); ServicePointManager.CheckCertificateRevocationList = true; webRequest = (HttpWebRequest)WebRequest.Create(Url); webRequest.Method = "GET"; webRequest.Accept = "*/*"; webRequest.CookieContainer = cookie; // 获取对应HTTP请求的响应 webResponse = (HttpWebResponse)webRequest.GetResponse(); // 获取响应流 Stream responseStream = webResponse.GetResponseStream(); return responseStream; } catch (Exception ex) { return null; } } ///<summary> ///post请求(有证书验证) ///</summary> ///<param name="URL">url地址</param> ///<param name="strPostdata">发送的数据</param> ///<returns></returns> public string GetValidhtmlByPost(string url, string strPostData) { HttpWebRequest webRequest; HttpWebResponse webResponse; try { // 这一句一定要写在创建连接的前面。使用回调的方法进行证书验证。 ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); ServicePointManager.CheckCertificateRevocationList = true; webRequest = (HttpWebRequest)HttpWebRequest.Create(url); webRequest.Method = "POST"; webRequest.ContentType = "application/x-www-form-urlencoded"; webRequest.KeepAlive = true; webRequest.CookieContainer = cookie; byte[] buffer = Encoding.UTF8.GetBytes(strPostData); webRequest.ContentLength = buffer.Length; webRequest.GetRequestStream().Write(buffer, 0, buffer.Length); webResponse = (HttpWebResponse)webRequest.GetResponse(); StreamReader reader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8); string result = reader.ReadToEnd(); return result; } catch (Exception ex) { return ex.Message; } }
Demo地址
http://download.csdn.net/download/qq237183141/10024750关于
技术层面就是HTTPWebRequest、HttpWebResponse,这两个类。主要是12306业务的逻辑,例如查询火车的json数据很乱,本人也是一个一个对着12306的页面,才一一找到的业务的含义。
希望大家还是买票还是去12306上买,本文只为学习上使用。欢迎大家一起学习。
相关文章推荐
- 利用HttpWebRequest和HttpWebResponse获取Cookie并实现模拟登录
- C# 利用 HttpWebRequest 和 HttpWebResponse 模拟登录有验证码的网站
- 利用HttpWebRequest和HttpWebResponse获取Cookie并实现模拟登录
- 利用HttpWebRequest和HttpWebResponse获取Cookie并实现模拟登录
- C# 利用 HttpWebRequest 和 HttpWebResponse 模拟登录有验证码的网站
- C# 利用 HttpWebRequest 和 HttpWebResponse 模拟登录有验证码的网站
- C#---HttpWebRequest+HttpWebResponse实现登录人人网
- c# HttpWebRequest 和HttpWebResponse 登录网站或论坛(校内网登陆)
- C#使用HttpWebRequest与HttpWebResponse模拟用户登录
- 【转】C#多线程环境下调用 HttpWebRequest 并发连接限制 HttpClient是否有默认并发数限制? 在.Net 4.0之前,一直是依靠HttpWebRequest实现Htt
- C#利用HttpWebRequest,Stream,HttpWebResponse,StreamReader获取post返回的数据
- 使用HttpWebRequest和HttpWebResponse实现模拟登录需要登陆后才可以访问的页面
- c# HttpWebRequest 和HttpWebResponse 登录网站或论坛(校内网登陆)
- C#使用HttpWebRequest与HttpWebResponse模拟用户登录
- [C#]基于HttpWebRequest和HttpWebResponse的自动登录采集
- 使用 HttpWebRequest 类调用 WEB 服务的示例(C#)【转载】
- c#中HttpWebRequest使用Proxy实现指定IP的域名请求
- 利用HttpWebRequest和HttpWebResponse做黑客注射工具
- HttpWebRequest 发送 POST实现自动用户登录
- C#POST数据,HttpWebRequest请求页面,HttpWebResponse返回数据