+从零实现一款12306刷票软件1.4

咱们接着上一篇《从零实现一款12306刷票软件1.3》继续介绍。

同理,这里也给出验证用户名和密码的接口实现代码:

 1int Client12306::loginAysnSuggest(const char* user, const char* pass, const char* vcode)  
 2{  
 3    string param = "loginUserDTO.user_name=";  
 4    param += user;  
 5    param += "&userDTO.password=";  
 6    param += pass;  
 7    param += "&randCode=";  
 8    param += vcode;  
 9    string strResponse;  
10    string strCookie = "Cookie: ";  
11    strCookie += m_strCookies;  
12    if (!HttpRequest(URL_LOGINAYSNSUGGEST, strResponse, false, strCookie.c_str(), param.c_str(), false, 10))  
13    {  
14        LogError("loginAysnSuggest failed");  
15        return 2;  
16    }  
17    ///** 成功返回  
18    //HTTP/1.1 200 OK  
19    //Date: Thu, 05 Jan 2017 07:49:53 GMT  
20    //Server: Apache-Coyote/1.1  
21    //X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1  
22    //ct: c1_103  
23    //Content-Type: application/json;charset=UTF-8  
24    //Content-Length: 146  
25    //X-Via: 1.1 f186:10 (Cdn Cache Server V2.0)  
26    //Connection: keep-alive  
27    //X-Cdn-Src-Port: 48361  
28    //邮箱不存在  
29    //{"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"data":{},"messages":["该邮箱不存在。"],"validateMessages":{}}  
30    //密码错误  
31    //{"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"data":{},"messages":["密码输入错误。如果输错次数超过4次,用户将被锁定。"],"validateMessages":{}}  
32    //登录成功  
33    //{"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"data":{"otherMsg":"",loginCheck:"Y"},"messages":[],"validateMessages":{}}  
34    //WCHAR* psz1 = Utf8ToAnsi(strResponse.c_str());  
35    //wstring str = psz1;  
36    //delete[] psz1;  
37    Json::Reader JsonReader;  
38    Json::Value JsonRoot;  
39    if (!JsonReader.parse(strResponse, JsonRoot))  
40        return 2;  
41    //{"validateMessagesShowId":"_validatorMessage", "status" : true,   
42    //"httpstatus" : 200, "data" : {"otherMsg":"", loginCheck : "Y"}, "messages" : [], "validateMessages" : {}}  
43    if (JsonRoot["status"].isNull())  
44        return -1;  
45    bool bStatus = JsonRoot["status"].asBool();  
46    if (!bStatus)  
47        return -1;  
48    if (JsonRoot["httpstatus"].isNull() || JsonRoot["httpstatus"].asInt() != 200)  
49        return 2;  
50    if (JsonRoot["data"].isNull() || !JsonRoot["data"].isObject())  
51        return 2;  
52    if (JsonRoot["data"]["otherMsg"].isNull() || JsonRoot["data"]["otherMsg"].asString() != "")  
53        return 2;  
54    if (JsonRoot["data"]["loginCheck"].isNull() || JsonRoot["data"]["loginCheck"].asString() != "Y")  
55        return 1;  
56    return 0;  
57}  

这里还有个注意细节,就是通过POST请求发送的数据需要对一些符号做URL Encode,这个我在上一篇文章《从零实现一个http服务器》也详细做了介绍,还不清楚的可以参见上一篇文章。所以对于向图片验证码坐标信息中含有的逗号信息就要进行URL编码,从

answer=114,54,44,46&login_site=E&rand=sjrand  

变成

answer=114%2C54%2C44%2C46&login_site=E&rand=sjrand  

所以,在http包头中指定的Content-Length字段的值应该是编码后的字符串长度,而不是原始的长度,这个地方特别容易出错。

如果验证成功后,接下来就是查票和购票了。这里就不一一介绍了,所有的原理都是一样的,作者可以自行探索。当然,我已经将大多数的接口都探索完了,并实现了,我这里贴一下吧:

  1/** 
  2 *@desc:    封装获取验证码、校验验证码、登录等12306各个请求的类,Client12306.h文件 
  3 *@author:      zhangyl 
  4 *@date:    2017.01.17 
  5 */  
  6#ifndef __CLIENT_12306_H__  
  7#define __CLIENT_12306_H__  
  8 
  9#include <vector>  
 10#include <string>  
 11  
 12using namespace std;  
 13 
 14//车次类型  
 15#define TRAIN_GC     0x00000001  
 16#define TRAIN_D      (0x00000001 << 1)  
 17#define TRAIN_Z      (0x00000001 << 2)  
 18#define TRAIN_T      (0x00000001 << 3)  
 19#define TRAIN_K      (0x00000001 << 4)  
 20#define TRAIN_OTHER  (0x00000001 << 5)  
 21#define TRAIN_ALL    (TRAIN_GC | TRAIN_D | TRAIN_Z | TRAIN_T | TRAIN_K | TRAIN_OTHER)  
 22  
 23//票信息  
 24struct queryLeftNewDTO  
 25{  
 26    string  train_no;  
 27    string  station_train_code;  
 28    string  start_station_telecode;     //始发站  
 29    string  start_station_name;       
 30    string  end_station_telecode;       //终点站  
 31    string  end_station_name;  
 32    string  from_station_telecode;      //出发站  
 33    string  from_station_name;          //到达站  
 34    string  to_station_telecode;  
 35    string  to_station_name;  
 36    string  start_time;  
 37    string  arrive_time;  
 38    string  day_difference;  
 39    string  train_class_name;  
 40    string  lishi;  
 41    string  canWebBuy;  
 42    string  lishiValue;  
 43    string  yp_info;  
 44    string  control_train_day;  
 45    string  start_train_date;  
 46    string  seat_feature;  
 47    string  yp_ex;  
 48    string  train_seat_feature;  
 49    string  seat_types;  
 50    string  location_code;  
 51    string  from_station_no;  
 52    string  to_station_no;  
 53    string  control_day;  
 54    string  sale_time;  
 55    string  is_support_card;  
 56    string  controlled_train_flag;  
 57    string  controlled_train_message;  
 58    string  train_type_code;  
 59    string  start_province_code;  
 60    string  start_city_code;  
 61    string  end_province_code;  
 62    string  end_city_code;  
 63    string  swz_num;    //商务座     
 64    string  rz_num;     //软座  
 65    string  yz_num;     //硬座  
 66    string  gr_num;     //高级软卧  
 67    string  rw_num;     //软卧  
 68    string  yw_num;     //硬卧  
 69    string  tz_num;     //特等座  
 70    string  zy_num;     //一等座  
 71    string  ze_num;     //二等座     
 72    string  wz_num;     //无座  
 73    string  gg_num;  
 74    string  yb_num;   
 75    string  qt_num;  
 76};  
 77 
 78struct ticketinfo  
 79{  
 80    queryLeftNewDTO DTO;  
 81    string secretStr;  
 82    string buttonTextInfo;  
 83};  
 84  
 85//var station_names = '@bjb|北京北|VAP|beijingbei|bjb|0@bjd|北京东|BOP|beijingdong|bjd|1@bji|北京|BJP|beijing|bj|2  
 86struct stationinfo  
 87{  
 88    string code1;  
 89    string hanzi;  
 90    string code2;  
 91    string pingyin;  
 92    string simplepingyin;  
 93    int no;  
 94};  
 95  
 96struct passenager  
 97{  
 98    string code;  //"8"  
 99    string passenger_name;  //"范蠡"  
100    string sex_code;// "M"  
101    string sex_name; // "男"  
102    string born_date; //"1989-12-08 00:00:00"  
103    string country_code;// "CN"  
104    string passenger_id_type_code;//  "1"  
105    string passenger_id_type_name; // "二代身份证"  
106    string passenger_id_no; // "34262319781108812X"  
107    string passenger_type; // "1"  
108    string passenger_flag; // "0"  
109    string passenger_type_name; // "成人"  
110    string mobile_no; // "13917043320"  
111    string phone_no;  
112    string email; // "balloonwj@qq.com"  
113    string address; //  ""  
114    string postalcode; // ""  
115    string first_letter;// ""  
116    string recordCount;// "13"  
117    string total_times;// "99"  
118    string index_id;// "0"  
119};  
120  
121class Client12306  
122{  
123public:  
124    static Client12306& GetInstance();  
125private:  
126    Client12306();  
127    ~Client12306();  
128private:  
129    Client12306(const Client12306&);  
130    Client12306& operator=(const Client12306&);  
131public:  
132    bool ReloadVCodeImage();  
133    /** 
134     * 游客查票 
135     * https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-05-24&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=SHH&purpose_codes=ADULT 
136     * 应答:{“validateMessagesShowId”:”_validatorMessage”,”status”:true,”httpstatus”:200,”messages”:[],”validateMessages”:{}} 
137     *@param: train_date列车发车日期,格式:2017-01-28 
138     *@param: from_station出发站,格式:SHH 对应上海 
139     *@parma: to_station到站,格式:BJP 对应北京 
140     *@param: purpose_codes 票类型,成人票:ADULT 学生票:0X00 
141     *@param: v 查票结果 
142     */  
143    bool GuestQueryTicket(const char* train_date, const char* from_station, const char* to_station, const char* purpose_codes, vector<ticketinfo>& v);  
144    /** 
145    * 初始化session,获取JSESSIONID 
146    */  
147    bool loginInit();  
148    bool DownloadVCodeImage(const char* module = "login");  
149    /** 
150    *@return 0校验成功;1校验失败;2校验出错 
151    */  
152    int checkRandCodeAnsyn(const char* vcode);  
153    /** 
154    *@return 0校验成功;1校验失败;2校验出错 
155    */  
156    int loginAysnSuggest(const char* user, const char* pass, const char* vcode);  
157    /**  
158     * 正式登录 
159     */  
160    bool userLogin();  
161    /**  
162     * 模拟12306跳转 
163     */  
164    bool initMy12306();  
165    /** 
166     * 拉取乘客买票验证码 
167     */  
168    //bool GetVCodeImage();  
169    /** 
170     * 拉取乘客买票验证码 
171     */  
172    /**  
173     * 查询余票第一步 
174     * https://kyfw.12306.cn/otn/leftTicket/log?leftTicketDTO.train_date=2017-02-08&leftTicketDTO.from_station=SHH&leftTicketDTO.to_station=NJH&purpose_codes=ADULT 
175     * 应答:{“validateMessagesShowId”:”_validatorMessage”,”status”:true,”httpstatus”:200,”messages”:[],”validateMessages”:{}} 
176     *@param: train_date列车发车日期,格式:2017-01-28 
177     *@param: from_station出发站,格式:SHH 对应上海 
178     *@parma: to_station到站,格式:BJP 对应北京 
179     *@param: purpose_codes 票类型,成人票:ADULT 学生票:0X00 
180     */  
181    bool QueryTickets1(const char* train_date, const char* from_station, const char* to_station, const char* purpose_codes);  
182    /** 
183     * 查询余票第二步 
184     * 这几种情形都有可能,所以应该都尝试一下 
185     * https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2017-02-08&leftTicketDTO.from_station=SHH&leftTicketDTO.to_station=NJH&purpose_codes=ADULT 
186     * https://kyfw.12306.cn/otn/leftTicket/queryX?leftTicketDTO.train_date=2017-02-08&leftTicketDTO.from_station=SHH&leftTicketDTO.to_station=NJH&purpose_codes=ADULT 
187     * https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-02-08&leftTicketDTO.from_station=SHH&leftTicketDTO.to_station=NJH&purpose_codes=ADULT 
188     * {"status":false,"c_url":"leftTicket/query","c_name":"CLeftTicketUrl"} 
189     * {"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"messages":["非法请求"],"validateMessages":{}} 
190     * 应答中含有实际余票信息 
191     *@param: train_date列车发车日期,格式:2017-01-28 
192     *@param: from_station出发站,格式:SHH 对应上海 
193     *@parma: to_station到站,格式:BJP 对应北京 
194     *@param: purpose_codes 票类型,成人票:ADULT 学生票:0X00 
195     */  
196    bool QueryTickets2(const char* train_date, const char* from_station, const char* to_station, const char* purpose_codes, vector<ticketinfo>& v);  
197    /**  
198     * 检测用户是否登录 
199     * https://kyfw.12306.cn/otn/login/checkUser POST _json_att= 
200     * Cookie: JSESSIONID=0A01D967FCD9827FC664E43DEE3C7C6EF950F677C2; __NRF=86A7CBA739653C1CC2C3C3AA7C88A1E3; BIGipServerotn=1742274826.64545.0000; BIGipServerportal=3134456074.17695.0000; current_captcha_type=Z; _jc_save_fromStation=%u4E0A%u6D77%2CSHH; _jc_save_toStation=%u5357%u4EAC%2CNJH; _jc_save_fromDate=2017-01-22; _jc_save_toDate=2017-01-22; _jc_save_wfdc_flag=dc 
201     * {"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"data":{"flag":true},"messages":[],"validateMessages":{}} 
202     */  
203    bool checkUser();  
204    /**  
205     * 预提交订单 POST 
206     * https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest?secretStr=secretStr&train_date=2017-01-21&back_train_date=2016-12-23&tour_flag=dc&purpose_codes=ADULT&query_from_station_name=深圳&query_to_station_name=武汉&undefined= 
207     */  
208    bool submitOrderRequest(const char* secretStr, const char* train_date, const char* back_train_date, const char* tour_flag, const char* purpose_codes, const char* query_from_station_name, const char* query_to_station_name);  
209    /**  
210     * 模拟跳转页面InitDc,Post 
211     */  
212    bool initDc();  
213    /** 
214     * 拉取常用联系人 POST 
215     * https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs?_json_att=&REPEAT_SUBMIT_TOKEN=SubmitToken 
216     */  
217    bool getPassengerDTOs(vector<passenager>& v);  
218    /**  
219     * 购票人确定 
220     * https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo 
221     @param oldPassengerStr oldPassengerStr组成的格式:乘客名,passenger_id_type_code,passenger_id_no,passenger_type,’_’ 
222                            示例: 张远龙,1,342623198912088150,1_ 
223     @param passengerTicketStr  passengerTicketStr组成的格式:seatType,0,票类型(成人票填1),乘客名,passenger_id_type_code,passenger_id_no,mobile_no,’N’  
224                            示例: O,0,1,张远龙,1,342623198912088150,13917043320,N    101 
225     @tour_flag dc表示单程票 
226     应答:{"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"data":{"ifShowPassCode":"N","canChooseBeds":"N","canChooseSeats":"N","choose_Seats":"MOP9","isCanChooseMid":"N","ifShowPassCodeTime":"1","submitStatus":true,"smokeStr":""},"messages":[],"validateMessages":{}} 
227     */  
228    bool checkOrderInfo(const char* oldPassengerStr, const char* passengerTicketStr, const char* tour_flag, bool& bVerifyVCode);  
229    /**  
230     * 准备进入排队 
231     * https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount 
232     _json_att      10 
233     fromStationTelecode    VNP 23 
234     leftTicket enu80ehMzuVJlK2Q43c6kn5%2BzQF41LEI6Nr14JuzThrooN57  63 
235     purpose_codes  00  16 
236     REPEAT_SUBMIT_TOKEN    691c09b5605e46bfb2ec2380ee65de0e    52 
237     seatType   O   10 
238     stationTrainCode   G5  19 
239     toStationTelecode  AOH 21 
240     train_date Fri Feb 10 00:00:00 UTC+0800 2017   50 
241     train_location P2  17 
242     train_no   24000000G502    21 
243     应答:{"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"data":{"count":"4","ticket":"669","op_2":"false","countT":"0","op_1":"true"},"messages":[],"validateMessages":{}} 
244     */  
245    bool getQueueCount(const char* fromStationTelecode, const char* leftTicket, const char* purpose_codes, const char* seatType, const char* stationTrainCode, const char* toStationTelecode, const char* train_date, const char* train_location, const char* train_no);  
246    /**  
247     * 确认购买 
248     * https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue 
249     _json_att      10 
250     choose_seats       13 
251     dwAll  N   7 
252     key_check_isChange 7503FD317E01E290C3D95CAA1D26DD8CFA9470C3643BA9799D3FB753    75 
253     leftTicketStr  enu80ehMzuVJlK2Q43c6kn5%2BzQF41LEI6Nr14JuzThrooN57  66 
254     oldPassengerStr    张远龙,1,342623198912088150,1_ 73 
255     passengerTicketStr O,0,1,张远龙,1,342623198912088150,13917043320,N    101 
256     purpose_codes  00  16 
257     randCode       9 
258     REPEAT_SUBMIT_TOKEN    691c09b5605e46bfb2ec2380ee65de0e    52 
259     roomType   00  11 
260     seatDetailType 000 18 
261     train_location P2  17 
262     应答:{"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"data":{"submitStatus":true},"messages":[],"validateMessages":{}} 
263     */  
264    bool confirmSingleForQueue(const char* leftTicketStr, const char* oldPassengerStr, const char* passengerTicketStr, const char* purpose_codes, const char* train_location);  
265    /**  
266     * 查询订单状态: https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime?random=1486368851278&tourFlag=dc&_json_att=&REPEAT_SUBMIT_TOKEN=691c09b5605e46bfb2ec2380ee65de0e 
267     GET 
268     _json_att 
269     random 1486368851278 
270     REPEAT_SUBMIT_TOKEN    691c09b5605e46bfb2ec2380ee65de0e 
271     tourFlag   dc 
272     响应:{"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"data":{"queryOrderWaitTimeStatus":true,"count":0,"waitTime":-1,"requestId":6234282826330508533,"waitCount":0,"tourFlag":"dc","orderId":"E061149209"},"messages":[],"validateMessages":{}} 
273     */  
274    bool queryOrderWaitTime(const char* tourflag, string& orderId);  
275    /**  
276     * https://kyfw.12306.cn/otn/confirmPassenger/resultOrderForDcQueue POST 
277     _json_att      10 
278     orderSequence_no   E061149209  27 
279     REPEAT_SUBMIT_TOKEN    691c09b5605e46bfb2ec2380ee65de0e    52 
280     {"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"data":{"submitStatus":true},"messages":[],"validateMessages":{}} 
281     */  
282    //bool resultOrderForDcQueue();  
283    /**  
284     * 未完成的订单页面 https://kyfw.12306.cn/otn/queryOrder/initNoComplete GET 
285     * 获取未完成的订单 https://kyfw.12306.cn/otn/queryOrder/queryMyOrderNoComplete POST _json_att= 
286     */  
287    /* 
288    { 
289    "validateMessagesShowId": "_validatorMessage", 
290    "status": true, 
291    "httpstatus": 200, 
292    "data": { 
293        "orderDBList": [ 
294            { 
295                "sequence_no": "E079331507", 
296                "order_date": "2017-02-09 10:10:55", 
297                "ticket_totalnum": 1, 
298                "ticket_price_all": 55300, 
299                "cancel_flag": "Y", 
300                "resign_flag": "4", 
301                "return_flag": "N", 
302                "print_eticket_flag": "N", 
303                "pay_flag": "Y", 
304                "pay_resign_flag": "N", 
305                "confirm_flag": "N", 
306                "tickets": [ 
307                    { 
308                        "stationTrainDTO": { 
309                            "trainDTO": {}, 
310                            "station_train_code": "G41", 
311                            "from_station_telecode": "VNP", 
312                            "from_station_name": "北京南", 
313                            "start_time": "1970-01-01 09:16:00", 
314                            "to_station_telecode": "AOH", 
315                            "to_station_name": "上海虹桥", 
316                            "arrive_time": "1970-01-01 14:48:00", 
317                            "distance": "1318" 
318                        }, 
319                        "passengerDTO": { 
320                            "passenger_name": "范蠡", 
321                            "passenger_id_type_code": "1", 
322                            "passenger_id_type_name": "二代身份证", 
323                            "passenger_id_no": "34262319781108815X", 
324                            "total_times": "98" 
325                        }, 
326                        "ticket_no": "E079331507110008B", 
327                        "sequence_no": "E079331507", 
328                        "batch_no": "1", 
329                        "train_date": "2017-02-11 00:00:00", 
330                        "coach_no": "10", 
331                        "coach_name": "10", 
332                        "seat_no": "008B", 
333                        "seat_name": "08B号", 
334                        "seat_flag": "0", 
335                        "seat_type_code": "O", 
336                        "seat_type_name": "二等座", 
337                        "ticket_type_code": "1", 
338                        "ticket_type_name": "成人票", 
339                        "reserve_time": "2017-02-09 10:10:55", 
340                        "limit_time": "2017-02-09 10:10:55", 
341                        "lose_time": "2017-02-09 10:40:55", 
342                        "pay_limit_time": "2017-02-09 10:40:55", 
343                        "ticket_price": 55300, 
344                        "print_eticket_flag": "N", 
345                        "resign_flag": "4", 
346                        "return_flag": "N", 
347                        "confirm_flag": "N", 
348                        "pay_mode_code": "Y", 
349                        "ticket_status_code": "i", 
350                        "ticket_status_name": "待支付", 
351                        "cancel_flag": "Y", 
352                        "amount_char": 0, 
353                        "trade_mode": "", 
354                        "start_train_date_page": "2017-02-11 09:16", 
355                        "str_ticket_price_page": "553.0", 
356                        "come_go_traveller_ticket_page": "N", 
357                        "return_deliver_flag": "N", 
358                        "deliver_fee_char": "", 
359                        "is_need_alert_flag": false, 
360                        "is_deliver": "N", 
361                        "dynamicProp": "", 
362                        "fee_char": "", 
363                        "insure_query_no": "" 
364                    } 
365                ], 
366                "reserve_flag_query": "p", 
367                "if_show_resigning_info": "N", 
368                "recordCount": "1", 
369                "isNeedSendMailAndMsg": "N", 
370                "array_passser_name_page": [ 
371                    "张远龙" 
372                ], 
373                "from_station_name_page": [ 
374                    "北京南" 
375                ], 
376                "to_station_name_page": [ 
377                    "上海虹桥" 
378                ], 
379                "start_train_date_page": "2017-02-11 09:16", 
380                "start_time_page": "09:16", 
381                "arrive_time_page": "14:48", 
382                "train_code_page": "G41", 
383                "ticket_total_price_page": "553.0", 
384                "come_go_traveller_order_page": "N", 
385                "canOffLinePay": "N", 
386                "if_deliver": "N", 
387                "insure_query_no": "" 
388            } 
389        ], 
390        "to_page": "db" 
391    }, 
392    "messages": [], 
393    "validateMessages": {} 
394} 
395    */  
396    /**  
397     * 已完成订单(改/退) : https://kyfw.12306.cn/otn/queryOrder/queryMyOrder POST 
398     * queryType 1 按订票日期 2 按乘车日期 
399     * 查询日期queryStartDate=2017-02-09&queryEndDate=2017-02-09 
400     * come_from_flag: my_order 全部 my_resign 可改签 my_cs_resign 可变更到站 my_refund 可退票 
401     * &pageSize=8&pageIndex=0& 
402     * query_where G 未出行订单 H 历史订单 
403     * sequeue_train_name 订单号/车次/乘客姓名 
404     */  
405    /* 历史订单格式 
406       参见[历史订单.txt] 
407    */  
408    /**  
409     * 获取全国车站信息 
410     *@param si 返回的车站信息 
411     *@param bForceDownload 强制从网络上下载,即不使用本地副本 
412     */  
413    bool GetStationInfo(vector<stationinfo>& si, bool bForceDownload = false);  
414    /**  
415     * 获取所有高校信息 https://kyfw.12306.cn/otn/userCommon/schoolNames POST provinceCode=11&_json_att= 
416     */  
417    /**  
418     * 获取所有城市信息 https://kyfw.12306.cn/otn/userCommon/allCitys POST station_name=&_json_att= 
419     */  
420    /** 
421     * 查询常用联系人 
422     */  
423    bool QueryPassengers(int pageindex = 2, int pagesize = 10);  
424    bool GetVCodeFileName(char* pszDst, int nLength);  
425private:  
426    bool GetCookies(const string& data);  
427    /** 
428     * 发送一个http请求 
429     *@param url 请求的url 
430     *@param strResponse http响应结果 
431     *@param get true为GET,false为POST 
432     *@param headers 附带发送的http头信息 
433     *@param postdata post附带的数据     
434     *@param bReserveHeaders http响应结果是否保留头部信息 
435     *@param timeout http请求超时时间 
436     */  
437    bool HttpRequest(const char* url, string& strResponse, bool get = true, const char* headers = NULL, const char* postdata = NULL, bool bReserveHeaders = false, int timeout = 10);  
438private:  
439    char                m_szCurrVCodeName[256]; //当前验证码图片的名称  
440    string              m_strCookies;  
441    string              m_strGlobalRepeatSubmitToken;  
442    string              m_strKeyCheckIsChange;  
443};  
444#endif //!__CLIENT_12306_H__  

最后当您实现了基本的登录和购票功能后,你就可以不断模拟某些请求去进行刷票了,这就是刷票的基本原理。如果您在开发的过程中遇到任何问题,可以在我的公众号中留言。

文章版权所有,转载请保留版权申明。

原文发布于微信公众号 - 高性能服务器开发(easyserverdev)

原文发表时间:2018-05-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏日暮星辰

phpmyadmin与php.ini中的socket配置问题

昨天在安装完新的perconesql数据后,发现phpmyadmin不能正常连接了。一时查来查去不知出了什么问题。

1264
来自专栏FreeBuf

新手指南:DVWA-1.9全级别教程之Brute Force

目前,最新的DVWA已经更新到1.9版本 ,而网上的教程大多停留在旧版本,且没有针对DVWA high级别的教程,因此萌发了一个撰写新手教程的想法,错误的地方还...

4349
来自专栏安恒网络空间安全讲武堂

赛前福利①最新2018HITB国际赛writeup

FIRST 距离“西湖论剑杯”全国大学生网络空间安全技能大赛只有10天啦! 要拿大奖、赢offer,那必须得来点赛前练习定定心啊~这不,讲武堂就拿到了2018H...

4645
来自专栏Kubernetes

Kubernetes如何通过Devi

Device Plugins Device Pulgins在Kubernetes 1.10中是beta特性,开始于Kubernetes 1.8,用来给第三方设备...

5058
来自专栏AhDung

【手记】解决Resharper 2018.x起本机license server不能用的问题

ReSharper升级到2018版后,一直用的好好的本机license server(下称LS)不能用了,报The license server address...

3373
来自专栏技术小黑屋

每周一脚本:批量对多个文件增加前缀

最近从设计师那里get了超多的图,结果都是1.png,2.png这样的文件名,自己还需要将这些文件变成可读的文件名,不想一个一个得修改,于是就写了一个简单的脚本...

2071
来自专栏安恒网络空间安全讲武堂

[HCTF] share write up

从http://share.2018.hctf.io/robots.txt中获取到题目部分源码

972
来自专栏伪君子的梦呓

网络安全实验室(基础关) writeup~上

因为参加了一个比赛(网鼎杯),所以要快速入门一下信息安全,没想到赛制是线上采用 CTF 的赛制,所以就找了点题目做了一下。

4322
来自专栏Spark学习技巧

Hbase源码系列之regionserver应答数据请求服务设计

一,基本介绍 Hbase源码系列主要是以hbase-1.0.0为例讲解hbase源码。本文主要是将Regionserver服务端RPC的结构及处理流程。希望是帮...

6119
来自专栏FreeBuf

腾讯御见捕获Flash 0day漏洞(CVE-2018-5002)野外攻击

腾讯御见威胁情报中心近日监控到一例使用Adobe Flash 0day漏洞(CVE-2018-5002)的APT攻击,攻击者疑通过即时聊天工具和邮箱等把恶意Ex...

1160

扫码关注云+社区

领取腾讯云代金券