小工具:火车票查询_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 小工具:火车票查询

小工具:火车票查询

 2017/9/2 19:08:46  LikeHeart  程序员俱乐部  我要评论(0)
  • 摘要:今天又到了抢火车票的时候,反正是每次抢票都是傻眼。于是写个小工具帮助自己查询火车票,如果有票的话给自己发个邮件提示购买。一、准备工作利用firebug等工具,我们可以获取到当我们单击查询时调用的Get请求。请求地址:https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-09-01&leftTicketDTO.from_station=TJP&leftTicketDTO
  • 标签:工具

      今天又到了抢火车票的时候,反正是每次抢票都是傻眼。于是写个小工具帮助自己查询火车票,如果有票的话给自己发个邮件提示购买。

一、准备工作

 

利用firebug等工具,我们可以获取到当我们单击查询时调用的Get请求。

class="author-p-824761">请求地址: https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-09-01&leftTicketDTO.from_station=TJP&leftTicketDTO.to_station=XHP&purpose_codes=ADULT 分析一下参数,得到以下结果:
  • leftTicketDTO.from_station=TJP              出发站
  • leftTicketDTO.to_station=XHP                 到达站
  • leftTicketDTO.train_date=2017-09-01      出发日期
  • purpose_codes=ADULT                          乘车人类型

 接下来我们要对返回的json进行分析,返回的json如下:

{
  "validateMessagesShowId": "_validatorMessage",
  "status": true,
  "httpstatus": 200,
  "data": {
    "result": [
      "oSIL3O3WIe6kfzF42Zlz%2B%2BsPFUuDm4BbNP13vXPnMnwSVXDgZ03onlMGao1RqJYjWimJDOiBa9Xm%0A59BctbygQhG6xM5mfTPPb9dLuvYg43VQYKGBpYzHere%2B4diEqyOfA64i6OcUFpe8ZJ4ccCEiQK7d%0AsFWdn6qDxY5PDQ2zG%2BCCNeAG216PdgO%2Fv%2F0PIrQTTK%2FTft8oZIxGT9VYlkHeh3TUUdxenyGAts4J%0AJ278LrM%3D|预订|260000Y5160F|Y516|VVP|ZMP|TXP|XHP|12:46|19:00|06:14|Y|rC9CEREwzGPqGayEjfr9YPwYtGX%2B45X6aKXyL0VaY0Bauu4t|20170901|3|P2|11|19|0|0|||||无||有|||有|||||101020|112",
      "wIpyiHG7PkQUnuOjE7gTxQAW39ihKOVttmAMx1lyhE10OyzjXjCe0EzyOsu28FOvw0Yc6CZF4CAQ%0AhR6L%2BAgyc6ca%2FYubiLZ4HuKw%2B0XmN5Us9fmA%2FajP3P%2FZgSoacqyPHPXEhWZ8pfGWSkmLMRNpisgd%0A48kWkp8rhjVIDljoncMagr6t5il3t5FaP8otqcN4ZtnTL1KfslpZt%2B2gxw7GwNFZH0QGTq2uoIuu%0AnYTSCB11w3Ok|预订|25000011360J|1136|TJP|WXC|TJP|XHP|20:52|01:55|05:03|Y|ZhbR6hnByAgL1ejqxJ1AIYiWcW2q08ZgO%2Bfk6UjtmX5mYLHGGlNBCiPVZDc%3D|20170901|3|P2|01|04|0|0||||无|||有||无|无|||||10401030|1413",
      "yG8TT6qCWjH0Aa2LVzxfCFGHf2q0syxOx7RfcXmsbFNyfq2VlWOS3q0oODd5tWAY2I5ddZfSBvnl%0A1GT%2BQCpZAhTPSLyRfDKCvwNMykAFe%2BuRULRPxd1WsQ57uIWepqDtElMcpGR8m7HB6KTnlzXXL9te%0AkumIJNMRMtA0ukPZto5G3sOGSSHgmQdcAxRmRdCVBFEsS9dNprjSQBwy%2BsxXq7KfAovJcemtY%2B3H%0AC7Kx4hnW5HXZ|预订|250000K8880H|K888|TJP|XNO|TJP|XHP|21:38|02:38|05:00|Y|uwEONiPztkLymI5okpF%2FJhWo7bzZA1zPcjbuofQXIXLCubD2gxSlXoz8nI8%3D|20170901|3|PB|01|04|0|0||||无|||有||无|有|||||10401030|1413"
    ],
    "flag": "1",
    "map": {
      "TXP": "天津西",
      "XHP": "宣化",
      "TJP": "天津"
    }
  },
  "messages": [],
  "validateMessages": {}
}

 网页显示:

以Y516车次数据为例,我们主要是搞清楚以下内容的含义: "oSIL3O3WIe6kfzF42Zlz%2B%2BsPFUuDm4BbNP13vXPnMnwSVXDgZ03onlMGao1RqJYjWimJDOiBa9Xm%0A59BctbygQhG6xM5mfTPPb9dLuvYg43VQYKGBpYzHere%2B4diEqyOfA64i6OcUFpe8ZJ4ccCEiQK7d%0AsFWdn6qDxY5PDQ2zG%2BCCNeAG216PdgO%2Fv%2F0PIrQTTK%2FTft8oZIxGT9VYlkHeh3TUUdxenyGAts4J%0AJ278LrM%3D|预订|260000Y5160F|Y516|VVP|ZMP|TXP|XHP|12:46|19:00|06:14|Y|rC9CEREwzGPqGayEjfr9YPwYtGX%2B45X6aKXyL0VaY0Bauu4t|20170901|3|P2|11|19|0|0|||||无||有|||有|||||101020|112"     观察这段字符串,可以发现有一定规律,可以通过|对字符串切割,再对切割后的内容进行分析; 分析中...... 经过若干数据对比,得出以下结论:
  • oSIL3O3WIe6kfzF42Zlz%2B%2BsPFUuDm4BbNP13vXPnMnwSVXDgZ03onlMGao1RqJYjWimJDOiBa9Xm%0A59BctbygQhG6xM5mfTPPb9dLuvYg43VQYKGBpYzHere%2B4diEqyOfA64i6OcUFpe8ZJ4ccCEiQK7d%0AsFWdn6qDxY5PDQ2zG%2BCCNeAG216PdgO%2Fv%2F0PIrQTTK%2FTft8oZIxGT9VYlkHeh3TUUdxenyGAts4J%0AJ278LrM%3D|            未知内容
  • 预订|                 
  • 260000Y5160F|
  • Y516|              车次
  • VVP|               始发站
  • ZMP|              终点站
  • TXP|               出发站   
  • XHP|              到达站
  • 12:46|             出发时间  
  • 19:00|             到达时间
  • 06:14|             历时
  • Y|                   是否有票 N:无票  Y:有票
  • rC9CEREwzGPqGayEjfr9YPwYtGX%2B45X6aKXyL0VaY0Bauu4t|           未知内容
  • 20170901|     未知内容
  • 3|                 未知内容
  • P2|               未知内容
  • 11|                出发站站序
  • 19|               到达站站序
  • 0|                未知内容
  • 0|                未知内容
  • |                  未知内容
  • |                  未知内容
  • |                  未知内容
  • |                   软卧
  • 无|                软座
  • |                   未知内容
  • 有|                无座
  • |                   硬卧
  • |                   未知内容
  • 有|                硬座
  • |                   二等座
  • |                   一等座
  • |                   商务座
  • |                   未知内容
  • 101020|         未知内容
  • 112               未知内容

   好了我们的准备工作差不多就这样了。 

 二、编写代码

      现在的任务就是数据的获取,代码如下:

        /// <summary>
        /// 车票查询数据获取
        /// </summary>
        /// <param name="goTime">出行日期</param>
        /// <param name="fromStationCode">出发站编码</param>
        /// <param name="toStationCode">到达站编码</param>
        /// <param name="errorMsg">错误消息</param>
        /// <returns></returns>
        public TicketSearchJson GetSearchTicketData(DateTime goTime, string fromStationCode, string toStationCode, ref string errorMsg)
        {
            string srcString = string.Empty;
            try
            {
                using (WebClient client = new WebClient())
                {
                    string url = string.Format("https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT",
                        goTime.ToString("yyyy-MM-dd"), fromStationCode, toStationCode);
                    Uri uri = new Uri(url);
                    ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;
                    byte[] responseData = client.DownloadData(uri);
                    srcString = Encoding.UTF8.GetString(responseData);
                    TicketSearchJson ticketSearch = JsonConvert.DeserializeObject<TicketSearchJson>(srcString);
                    return ticketSearch;
                }
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// 服务器证书回调方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="sslPolicyErrors"></param>
        /// <returns></returns>
        private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }

   邮件发送功能可见这篇博客小工具:邮件发送

三、运行截图

 

   切勿过于频繁调用接口!!!

发表评论
用户名: 匿名