解决方案 »

  1.   

    http://download.csdn.net/download/wangle1189/4998797
      

  2.   

    第一步登录
    public void Login()
            {
                string url = string.Empty;
                string html = string.Empty;
                string data = string.Empty;
                for (int i = 0; i < 10000; i++)
                {
                    try
                    {
                        #region 加载验证码
                        url = "https://dynamic.12306.cn/otsweb/passCodeAction.do?rand=sjrand";   // 登录验证码                    Stream stream = null;                    lock (obj)
                        {
                            for (int j = 0; j < 10000; j++)
                            {
                                stream = HttpHelper.GetResponseImage(url);
                                if (stream != null)
                                {
                                    // 读取并保存登录验证码
                                    imageLogin = Image.FromStream(stream);
                                    Show(imageLogin);
                                    Cracker ck = new Cracker();
                                    imageCodeLogin = ck.Read((Bitmap)imageLogin);                                if (this.btnCheck.Checked == true)
                                    {
                                        if (imageCodeLogin.Length == 4)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            Output("验证码位数不足,重新加载\r\n");
                                        }
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    Output("获取登录验证码失败,正在进行第" + i.ToString() + "次重试\r\n");
                                }
                            }
                        }
                        #endregion                    if (this.btnCheck.Checked == false)
                        {
                            TextFocus();
                            threadBuy.Suspend();                        imageCodeLogin = this.txtCode.Text.Trim();
                        }                    #region 获得随机数
                        string randomUrl = "https://dynamic.12306.cn/otsweb/loginAction.do?method=loginAysnSuggest";
                        html = HttpHelper.GetResponse(randomUrl, "POST", string.Empty);
                        string[] temp = html.Split('"');
                        string random = temp[3];
                        #endregion                    url = "https://dynamic.12306.cn/otsweb/loginAction.do?method=login";
                        data = "loginRand=" + random + "&loginUser.user_name=" + id + "&nameErrorFocus=&user.password=" + password + "&passwordErrorFocus=&randCode=" + imageCodeLogin + "&randErrorFocus=";
                        html = HttpHelper.GetResponse(url, "POST", data);                    // 登录成功
                        if (html.Contains("欢迎您"))
                        {
                            Output("成功登录... 账号:" + id + "\r\n");
                            break;
                        }
                        else
                        {
                            Output("登录失败,再次登录...\r\n");
                        }
                    }
                    catch { }
                }            Search();
            } // 登录
      

  3.   

    第二步,查询:  public void Search()
            {
                Output("购票信息" + date + from_CN + "--" + to_CN + no + type + "\r\n");
                Output("开始查询(1分钟输出一次)...\r\n");
                DateTime date_Out = DateTime.Now;  // 用于输出的临时变量            string url = string.Empty;
                string data = string.Empty;
                string html = string.Empty;            if (!string.IsNullOrEmpty(no))
                {
                    // 在输入车次的时候获得车次代码 这里所获得的no_New为查询所用 如T38获得6300000T3803
                    url = "https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=queryststrainall";
                    data = "date=" + date;
                    data += "&fromstation=" + from;
                    data += "&tostation=" + to;
                    data += "&starttime=00%3A00--24%3A00";
                    html = HttpHelper.GetResponse(url, "Post", data);
                    string[] list = html.Split('}');
                    for (int j = 0; j < list.Length - 1; j++)
                    {
                        string[] temp = list[j].Split('"');
                        if (temp[23].ToLower().Contains(no.ToLower()))
                        {
                            no_Buy = temp[11];
                            break;
                        }
                    }                if (string.IsNullOrEmpty(no_Buy))
                    {
                        Output("未查询到" + no + "车次列车信息,忽略该信息按出发地-->目的地方式操作\r\n");
                    }
                }            // 查询余票
                url = "https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=queryLeftTicket";
                html = string.Empty;
                data = "orderRequest.train_date=" + date;
                data += "&orderRequest.from_station_telecode=" + from;
                data += "&orderRequest.to_station_telecode=" + to;
                data += "&orderRequest.train_no=" + no_Buy;   // 车次
                data += "&trainPassType=QB";
                data += "&trainClass=" + train_type; // QB#D#Z#T#K#QT 全部车型
                data += "&includeStudent=00";                     // 非学生票
                data += "&seatTypeAndNum=";
                data += "&orderRequest.start_time_str=" + date_range;  //00:00--24:00            // 查询
                while (true)
                {
                    html = HttpHelper.GetResponse(url, "Post", data);
                    if (html != "")
                    {
                        if (html == "-10" || html == "-1")
                        {
                            Output("12306暂停服务(崩溃),查询暂停0.5秒\r\n");
                            Thread.Sleep(500);
                        }
                        // 有票时退出
                        else if (CheckSearch(html, ref date_Out) == true)
                        {
                            // 获得的no_New为后续购票所用 因为在没有输入车次的时候该数据此时为Emputy 
                            url = "https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=queryststrainall";
                            data = "date=" + date;
                            data += "&fromstation=" + from;
                            data += "&tostation=" + to;
                            data += "&starttime=00%3A00--24%3A00";
                            html = HttpHelper.GetResponse(url, "Post", data);
                            string[] list = html.Split('}');
                            for (int j = 0; j < list.Length - 1; j++)
                            {
                                string[] temp = list[j].Split('"');
                                if (temp[23].ToLower().Contains(no.ToLower()))
                                {
                                    no_Buy = temp[11];
                                    break;  // 退出查询车次代码循环
                                }
                            }                        break;  // 退出车票查询循环
                        }
                    }
                }            Preprogram();
            } // 查询
      

  4.   

    第三步,预定:  public void Preprogram()
            {
                string[] list = detail.Split('#');
                Output("预定...\r\n");
                try
                {
                    string url = "https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=submutOrderRequest";
                    string data = "station_train_code=" + list[0]; // 车次
                    data += "&train_date=" + date;         // 时间
                    data += "&seattype_num=";
                    data += "&from_station_telecode=" + list[4];   // 起始站代码
                    data += "&to_station_telecode=" + list[5];     // 到达站代码
                    data += "&include_student=00";                 // 非学生票
                    data += "&from_station_telecode_name=" + System.Web.HttpUtility.UrlEncode(list[7], System.Text.Encoding.GetEncoding("UTF-8")); // 起始站名称
                    data += "&to_station_telecode_name=" + System.Web.HttpUtility.UrlEncode(list[8], System.Text.Encoding.GetEncoding("UTF-8"));   // 到达站名称
                    data += "&round_train_date=" + date;      // 时间
                    data += "&round_start_time_str=" + date_range; // 00:00--24:00
                    data += "&single_round_type=1";
                    data += "&train_pass_type=QB";                    // 全部 代表所有列车类型
                    data += "&train_class_arr=" + train_type;  // QB#D#Z#T#K#QT# 代表所有列车类型
                    data += "&start_time_str=" + date_range;       // 00:00--24:00  出发时间
                    data += "&lishi=" + System.Web.HttpUtility.UrlEncode(list[1], System.Text.Encoding.GetEncoding("UTF-8"));              // 总花费时间 
                    data += "&train_start_time=" + System.Web.HttpUtility.UrlEncode(list[2], System.Text.Encoding.GetEncoding("UTF-8"));   // 发车时间
                    data += "&trainno4=" + no_Buy;      // 嵌套车次            
                    data += "&arrive_time=" + System.Web.HttpUtility.UrlEncode(list[6], System.Text.Encoding.GetEncoding("UTF-8"));        // 到站时间          
                    data += "&from_station_name=" + System.Web.HttpUtility.UrlEncode(from_CN, System.Text.Encoding.GetEncoding("UTF-8"));
                    data += "&to_station_name=" + System.Web.HttpUtility.UrlEncode(to_CN, System.Text.Encoding.GetEncoding("UTF-8"));
                    data += "&from_station_no=" + list[9];            // 出发站在该线路的坐标 01开始
                    data += "&to_station_no=" + list[10];             // 到达站在该线路的坐标
                    data += "&ypInfoDetail=" + list[11];
                    data += "&mmStr=" + list[12];
                    data += "&locationCode=" + list[13];
                    data_Buy = data;
                    string html = HttpHelper.GetNewResponse(url, "POST", data);                // 更新 TOKEN 
                    url = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=init";
                    data = string.Empty;
                    html = HttpHelper.GetResponse(url, "POST", data);
                    string temp = html;
                    temp = temp.Substring(temp.IndexOf("name=\"org.apache.struts.taglib.html.TOKEN\" value=\"") + 50);
                    token = temp.Substring(0, temp.IndexOf('"'));  // 获取令牌
                    temp = html;
                    int index = temp.IndexOf("id=\"left_ticket\"");
                    temp = temp.Substring(temp.IndexOf("id=\"left_ticket\"") + 26);
                    leftTicketStr = temp.Substring(0, temp.IndexOf('"'));
                }
                catch { }            Order();
            } // 预定
      

  5.   

    第四步,提交订单: public void Order() // 提交订单
            {
                bool isStop = false;
                string[] list = detail.Split('#');
                Output("提交订单,再次查询余票,在余票>0时提交(每分钟输出一次)\r\n");
                DateTime date_Out = DateTime.Now;  // 用于输出的临时变量            string url = string.Empty;
                string html = string.Empty;
                string data = string.Empty;
                bool isFirst = true;            for (int i = 0; i < 10000; i++)
                {
                    try
                    {
                        if (isFirst == true)   // 第一次进来时加载验证码
                        {
                            #region 加载验证码
                            url = "https://dynamic.12306.cn/otsweb/passCodeAction.do?rand=randp";   // 提交订单验证码                        Stream stream = null;                        lock (obj)
                            {
                                for (int j = 0; j < 10000; j++)
                                {
                                    stream = HttpHelper.GetResponseImage(url);
                                    if (stream != null)
                                    {
                                        // 读取并保存订单验证码
                                        imageOrder = Image.FromStream(stream);
                                        Show(imageOrder);
                                        Cracker ck = new Cracker();
                                        imageCodeOrder = ck.Read((Bitmap)imageOrder);
                                        if (this.btnCheck.Checked == true)
                                        {
                                            if (imageCodeLogin.Length == 4)
                                            {
                                                break;
                                            }
                                            else
                                            {
                                                Output("验证码位数不足,重新加载\r\n");
                                            }
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        Output("获取登录验证码失败,正在进行第" + i.ToString() + "次重试\r\n");
                                    }
                                }
                            }
                            #endregion                        if (this.btnCheck.Checked == false)
                            {
                                TextFocus();
                                threadBuy.Suspend();                            imageCodeOrder = this.txtCode.Text.Trim();
                            }
                        }                    url = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=checkOrderInfo&rand=";
                        url += imageCodeOrder;
                        data_Buy = "org.apache.struts.taglib.html.TOKEN=" + token;
                        data_Buy += "&leftTicketStr=" + leftTicketStr;
                        // 中文或拼音首字母
                        data_Buy += "&textfield=%E4%B8%AD%E6%96%87%E6%88%96%E6%8B%BC%E9%9F%B3%E9%A6%96%E5%AD%97%E6%AF%8D";
                        //data_Buy += "&checkbox" + name_Index + "=" + name_Index; // 联系人在列表中的位置 
                        data_Buy += "&checkbox0=0";
                        data_Buy += "&orderRequest.train_date=" + date;
                        data_Buy += "&orderRequest.train_no=" + no_Buy;
                        data_Buy += "&orderRequest.station_train_code=" + no;
                        data_Buy += "&orderRequest.from_station_telecode=" + from;
                        data_Buy += "&orderRequest.to_station_telecode=" + to;
                        data_Buy += "&orderRequest.seat_type_code=";
                        //data_Buy += "&orderRequest.seat_detail_type_code=";
                        data_Buy += "&orderRequest.ticket_type_order_num=";
                        data_Buy += "&orderRequest.bed_level_order_num=000000000000000000000000000000";
                        data_Buy += "&orderRequest.start_time=" + System.Web.HttpUtility.UrlEncode(list[2], System.Text.Encoding.GetEncoding("UTF-8"));
                        data_Buy += "&orderRequest.end_time=" + System.Web.HttpUtility.UrlEncode(list[6], System.Text.Encoding.GetEncoding("UTF-8"));
                        data_Buy += "&orderRequest.from_station_name=" + System.Web.HttpUtility.UrlEncode(from_CN, System.Text.Encoding.GetEncoding("UTF-8"));
                        data_Buy += "&orderRequest.to_station_name=" + System.Web.HttpUtility.UrlEncode(to_CN, System.Text.Encoding.GetEncoding("UTF-8"));
                        data_Buy += "&orderRequest.cancel_flag=1";
                        data_Buy += "&orderRequest.id_mode=Y";
                        string passengerTickets = seat + ",0,1," + name + ",1," + id_code + "," + phone + ",Y";
                        data_Buy += "&passengerTickets=" + System.Web.HttpUtility.UrlEncode(passengerTickets, System.Text.Encoding.GetEncoding("UTF-8"));
                        string oldPassengers = name + ",1," + id_code;
                        data_Buy += "&oldPassengers=" + System.Web.HttpUtility.UrlEncode(oldPassengers, System.Text.Encoding.GetEncoding("UTF-8"));
                        data_Buy += "&passenger_1_seat=" + seat;   // 1硬座/3硬卧/4软卧
                        data_Buy += "&passenger_1_seat_detail_select=0";
                        data_Buy += "&passenger_1_seat_detail=0";
                        data_Buy += "&passenger_1_ticket=1";
                        data_Buy += "&passenger_1_name=" + System.Web.HttpUtility.UrlEncode(name, System.Text.Encoding.GetEncoding("UTF-8"));
                        data_Buy += "&passenger_1_cardtype=1";
                        data_Buy += "&passenger_1_cardno=" + id_code;
                        data_Buy += "&passenger_1_mobileno=" + phone;
                        data_Buy += "&checkbox9=Y";
                        data_Buy += "&oldPassengers=";
                        data_Buy += "&checkbox9=Y";
                        data_Buy += "&oldPassengers=";
                        data_Buy += "&checkbox9=Y";
                        data_Buy += "&oldPassengers=";
                        data_Buy += "&checkbox9=Y";
                        data_Buy += "&oldPassengers=";
                        data_Buy += "&checkbox9=Y";
                        data_Buy += "&randCode=" + imageCodeOrder;              // 验证码
                        data_Buy += "&orderRequest.reserve_flag=A";
                        data_Buy += "&tFlag=dc";
                        html = HttpHelper.GetResponse(url, "POST", data_Buy);
                        string result = html.Split('"')[15];                    if (result == "Y")
                        {
                            isFirst = false; // 不再加载验证码
                            url = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=getQueueCount";
                            data = "train_date=" + date;
                            data += "&train_no=" + no_Buy;
                            data += "&station=" + no;
                            data += "&seat=" + seat;
                            data += "&from=" + from;
                            data += "&to=" + to;
                            data += "&ticket=" + leftTicketStr;
                            html = HttpHelper.GetResponse(url, "Post", data);                        // 有票时提交订单
                            if (CheckCount(html, ref date_Out) == true)
                            {
                                break;
                            }
                            else
                            {
                                if (no_List.Count > 1) // 如果无票时并且有票集合>1时重新进行第一次查询 再次查询时当前车次会被忽略 30秒后重新恢复
                                {
                                    Search();
                                }
                            }
                        }
                        else if (result.Contains("对不起,由于您取消次数过多"))
                        {
                            Output("对不起,由于您取消次数过多,今日将不能继续受理您的订票请求,程序结束\r\n");
                            isStop = true; // 直接退出
                            break;
                        }
                        else if (result.Contains("输入的验证码不正确") || result.Contains("验证码 必须输入"))
                        {
                            Output("订单验证码比对失败,重新加载...\r\n");
                        }
                        else
                        {
                            Output("未知,再次验证...\r\n");
                        }
                    }
                    catch { }
                }            if (isStop == false)  // 账号无误则购买
                {
                    Buy();
                }
            }
      

  6.   

    第五步,购票: 完成!  public void Buy() // 购票
            {
                bool isBuy = false;            Output("购票\r\n");            string url = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=confirmSingleForQueueOrder";
                string html = HttpHelper.GetResponse(url, "POST", data_Buy.Substring(0, data_Buy.Length - 9));
                string data = string.Empty;            string result = html.Split('"')[3];            if (result == "Y")
                {
                    Output("确认订单成功:");
                }
                else
                {
                    Output("确认订单失败:" + html.Split('"')[3] + "" + (html.Split('"').Length >= 11 ? html.Split('"')[11] : "") + "\r\n");
                }
                ButtonAbled(); // 按钮可用            while (true)
                {
                    url = "https://dynamic.12306.cn/otsweb/order/myOrderAction.do?method=queryMyOrderNotComplete&leftmenu=Y";
                    html = HttpHelper.GetResponse(url, "Post", "");
                    int index = html.IndexOf("<div class=\"clear\"></div>");  //-1
                    if (index == -1)
                    {
                        Output("未完成订单没有数据\r\n");
                        break;
                    }
                    else
                    {
                        html = html.Substring(index);
                        html = html.Substring(0, html.IndexOf("</table>"));
                        html = StripHTML(html);
                        int xxxx = html.IndexOf("\r\n");
                        html = html.Replace("\r\n", "");
                        html = html.Replace(" ", "");
                        html = html.Replace("\t", "");
                        html = html.Replace("\n", "");                    Output("系统返回:" + html.Substring(16) + "\r\n");
                        if (html.Contains("继续支付"))
                        {
                            OutputMusic();
                            Output(DateTime.Now.ToString("hh-mm-ss") + " 购票成功,程序终止\r\n");
                            isBuy = true;
                            break;
                        }
                        else if (html.Contains("取消订单"))
                        {
                            Output("排队中,2秒后查询结果\r\n");
                            Thread.Sleep(2000);
                        }
                        else
                        {
                            Output("购票未成功\r\n");
                            Output(html.Substring(16) + "\r\n");
                            break;
                        }
                    }
                }            if (isBuy == false)
                {
                    Output("0.1秒再次进入购票程序\r\n");
                    Thread.Sleep(10);
                    Search();
                }
            }
      

  7.   

    这个代码是一位同行写的,用这个订到票的童鞋们要向他表示感谢,里面主要用到HttpWebRequest 和HttpWebResponse 模拟浏览器请求12306网站,组装数据和解析数据还有一个牛B的地方是自动识别验证码,这个为买票节省了很多时间,也使本程序整个流程能自动完成不用人看管,哈哈 Cracker ck = new Cracker();
                                  string imageCodeLogin = ck.Read((Bitmap)imageLogin);
    注意这两行代码,把获取到了验证码图片解析,返回4位的验证字符,牛B啊,源码看了看不懂什么原理
      

  8.   

    data_Buy += "&checkbox0=0";
    data_Buy += "&orderRequest.train_date=" + date;
    data_Buy += "&orderRequest.train_no=" + no_Buy;
    data_Buy += "&orderRequest.station_train_code=" + no;
    data_Buy += "&orderRequest.to_station_telecode=" + to;
    --------------------------------------------------
    这些参数是怎么知道的?
    昨晚12306把这些调整了
      

  9.   

    HttpWebRequest Post参数是怎么知道呢?
      

  10.   

    只有debug目录,楼主上传完整的源码吧
      

  11.   


    这个 估计是用loadRunner工具,录制的脚本,
      

  12.   

    源码下载C#大牛们自己根据需求优化优化,造福我们这些草根淫民啊~~~~~~~ http://download.csdn.net/download/wangle1189/5005657