第一步登录:
添加一个登录类:
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();
} // 登录
第二步,查询:
添加一个查询类:
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();
} // 查询
第三步,预定:
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();
} // 预定
第四步,提交订单:
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();
}
}
第五步,购票: 完成!
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();
}
}
本文章内容参考作者:wangle1189