def checkOrderInfo(self, train_no, set_type): """ 检查支付订单,需要提交REPEAT_SUBMIT_TOKEN passengerTicketStr : 座位编号,0,票类型,乘客名,证件类型,证件号,手机号码,保存常用联系人(Y或N) oldPassengersStr: 乘客名,证件类型,证件号,乘客类型 :return: """ passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr( ) checkOrderInfoUrl = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo' data = OrderedDict() data['cancel_flag'] = 2 data['bed_level_order_num'] = "000000000000000000000000000000" data['passengerTicketStr'] = self.set_type + "," + ",".join( passengerTicketStrList).rstrip("_{0}".format(self.set_type)) data['oldPassengerStr'] = "".join(oldPassengerStr) data['tour_flag'] = 'dc' data['whatsSelect'] = 1 data['REPEAT_SUBMIT_TOKEN'] = self.token checkOrderInfo = json.loads(myurllib2.Post( checkOrderInfoUrl, data, )) if 'data' in checkOrderInfo: if checkOrderInfo["data"]["ifShowPassCode"] == "y": print("需要验证码,正在使用自动识别验证码功能") for i in range(3): codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&%s' % random.random( ) result = myurllib2.get(codeimg) img_path = './tkcode' open(img_path, 'wb').write(result) data['pass_code'] = DamatuApi( _get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main() checkOrderInfo = json.loads( myurllib2.Post( checkOrderInfoUrl, data, )) if self.getQueueCount(train_no, set_type): return True else: print("验证码识别错误,第{0}次重试".format(i)) if checkOrderInfo['data']['submitStatus'] is True: print('车票提交通过,正在尝试排队') if self.getQueueCount(train_no, set_type): return True else: if "errMsg" in checkOrderInfo['data'] and checkOrderInfo[ 'data']["errMsg"]: print checkOrderInfo['data']["errMsg"] else: print checkOrderInfo elif 'messages' in checkOrderInfo and checkOrderInfo['messages']: print(checkOrderInfo['messages'][0]) print("排队失败,重新刷票中")
def login(user, passwd): """ 登陆 :param user: 账户名 :param passwd: 密码 :return: """ login_num = 0 while True: cookietp() readImg() login_num += 1 randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn' logurl = 'https://kyfw.12306.cn/otn/login/loginAysnSuggest' surl = 'https://kyfw.12306.cn/otn/login/userLogin' randdata = {"randCode": randCode, "rand": "sjrand"} logdata = { "loginUserDTO.user_name": user, "userDTO.password": passwd, "randCode": randCode } ldata = {"_json_att": None} fresult = json.loads(myurllib2.Post(randurl, randdata), encoding='utf8') checkcode = fresult['data']['msg'] if checkcode == 'FALSE': errorinput("验证码有误,第{}次尝试重试".format(login_num)) else: stoidinput("验证码通过,开始登录..") sleep(1) try: tresult = json.loads(myurllib2.Post(logurl, logdata), encoding='utf8') if 'data' not in tresult: errorinput("登录失败: %s" % tresult['messages'][0]) # elif "messages" in tresult and tresult["messages"][0].find("密码输入错误") is not -1: # errorinput("登陆失败:{}".format(tresult["messages"][0])) # break elif 'messages' in tresult and tresult['messages']: messages = tresult['messages'][0] if messages.find("密码输入错误") is not -1: errorinput("登陆失败:{}".format(tresult["messages"][0])) break else: errorinput("登录失败: %s" % tresult['messages'][0]) stoidinput("尝试重新登陆") else: stoidinput("登录成功") myurllib2.Post(surl, ldata) getUserinfo() break except ValueError as e: errorinput(e) sleep(1)
def queryMyOrderNoComplete(self): """ 获取订单列表信息 :return: """ queryMyOrderNoCompleteUrl = "https://kyfw.12306.cn/otn/queryOrder/queryMyOrderNoComplete" data = {"_json_att": None} queryMyOrderNoCompleteResult = json.loads( myurllib2.Post(queryMyOrderNoCompleteUrl, data)) if "data" in queryMyOrderNoCompleteResult and queryMyOrderNoCompleteResult[ "data"] and "orderDBList" in queryMyOrderNoCompleteResult[ "data"] and queryMyOrderNoCompleteResult["data"][ "orderDBList"]: orderId = queryMyOrderNoCompleteResult["data"]["orderDBList"][0][ "sequence_no"] return orderId elif "orderCacheDTO" in queryMyOrderNoCompleteResult[ "data"] and queryMyOrderNoCompleteResult["data"][ "orderCacheDTO"]: if "message" in queryMyOrderNoCompleteResult["data"][ "orderCacheDTO"] and queryMyOrderNoCompleteResult["data"][ "orderCacheDTO"]["message"]: print(queryMyOrderNoCompleteResult["data"]["orderCacheDTO"] ["message"]["message"]) raise ticketNumOutException( queryMyOrderNoCompleteResult["data"]["orderCacheDTO"] ["message"]["message"]) else: if "message" in queryMyOrderNoCompleteResult and queryMyOrderNoCompleteResult[ "message"]: print queryMyOrderNoCompleteResult["message"] return False else: return False
def getPassengerDTOs(self): """ 获取乘客信息 :return: """ get_passengerDTOs = 'https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs' get_data = {'_json_att': None, 'REPEAT_SUBMIT_TOKEN': self.token} jsonData = json.loads(myurllib2.Post(get_passengerDTOs, get_data)) if 'data' in jsonData and jsonData[ 'data'] and 'normal_passengers' in jsonData[ 'data'] and jsonData['data']['normal_passengers']: # return jsonData['data']['normal_passengers'] normal_passengers = jsonData['data']['normal_passengers'] _normal_passenger = [ normal_passengers[i] for i in range(len(normal_passengers)) if normal_passengers[i]["passenger_name"] in self.ticke_peoples ] return _normal_passenger if _normal_passenger else normal_passengers[ 0] # 如果配置乘车人没有在账号,则默认返回第一个用户 else: if 'data' in jsonData and 'exMsg' in jsonData['data'] and jsonData[ 'data']['exMsg']: print(jsonData['data']['exMsg']) elif 'messages' in jsonData and jsonData['messages']: print(jsonData['messages'][0]) else: print("未查找到常用联系人") raise PassengerUserException("未查找到常用联系人,请先添加联系人在试试")
def submit_station(self): """ 提交车次 预定的请求参数,注意参数顺序 注意这里为了防止secretStr被urllib.parse过度编码,在这里进行一次解码 否则调用HttpTester类的post方法将会将secretStr编码成为无效码,造成提交预定请求失败 :param self: :param secretStr: 提交车次加密 :return: """ submit_station_url = 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest' data = [ ('secretStr', urllib.unquote(self.secretStr)), # 字符串加密 ('train_date', self.time()), # 出发时间 ('back_train_date', self.time()), # 返程时间 ('tour_flag', 'dc'), # 旅途类型 ('purpose_codes', 'ADULT'), # 成人票还是学生票 ('query_from_station_name', self.from_station), # 起始车站 ('query_to_station_name', self.to_station), # 终点车站 ] submitResult = json.loads(myurllib2.Post(submit_station_url, data), encoding='utf-8') if 'data' in submitResult and submitResult['data']: if submitResult['data'] == 'N': print('出票成功') else: print('出票失败') elif 'messages' in submitResult and submitResult['messages']: raise ticketIsExitsException(submitResult['messages'][0])
def getQueueCount(self, train_no, set_type): """ # 模拟查询当前的列车排队人数的方法 # 返回信息组成的提示字符串 :param token: :return: """ old_train_date = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_date']+"00:00:00" # 模仿12306格式 Sun May 21 2017 00:00:00 GMT+0800 (中国标准时间) m_time = time.mktime(time.strptime(old_train_date, "%Y%m%d%H:%M:%S")) l_time = time.localtime(m_time) new_train_date = time.strftime("%a %b %d %Y %H:%M:%S", l_time) getQueueCountUrl = 'https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount' data = { 'train_date': new_train_date, 'train_no': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_no'], 'stationTrainCode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['station_train_code'], 'seatType': self.set_type, 'fromStationTelecode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['from_station'], 'toStationTelecode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['to_station'], 'leftTicket': self.get_ticketInfoForPassengerForm()['leftTicketStr'], 'purpose_codes': self.get_ticketInfoForPassengerForm()['purpose_codes'], 'train_location': self.get_ticketInfoForPassengerForm()['train_location'], 'REPEAT_SUBMIT_TOKEN': self.get_token(), } for i in range(3): print("第{0}次排队".format(i+1)) getQueueCountResult = json.loads(myurllib2.Post(getQueueCountUrl, data)) if "status" in getQueueCountResult and getQueueCountResult["status"] is True: if "countT" in getQueueCountResult["data"]: ticket = getQueueCountResult["data"]["ticket"] ticket_split = sum(map(self.conversion_int, ticket.split(","))) if ticket.find(",") != -1 else ticket # ticket_sum = sum([int(ticket_split[0]),int(ticket_split[1])]) # if set_type == "无座": # 修改无座和硬座的座位号提交是个字符串的问题 # ticket = ticket_split[1] # elif set_type == "硬座": # ticket = ticket_split[0] countT = getQueueCountResult["data"]["countT"] if int(countT) is 0: if int(ticket_split) < len(self.user_info): print("当前余票数小于乘车人数,放弃订票") else: print("排队成功, 当前余票还剩余: {0} 张".format(ticket_split)) if self.checkQueueOrder(): return True else: print("当前排队人数:" + str(countT) + "当前余票还剩余:{} 张,继续排队中".format(ticket_split)) else: print("排队发现未知错误{0},将此列车 {1}加入小黑屋".format(getQueueCountResult, train_no)) self.ticket_black_list[train_no] = datetime.datetime.now() break elif "messages" in getQueueCountResult and getQueueCountResult["messages"]: print("排队异常,错误信息:{0}, 将此列车 {1}加入小黑屋".format(getQueueCountResult["messages"][0], train_no)) self.ticket_black_list[train_no] = datetime.datetime.now() break else: print(str(getQueueCountResult["validateMessages"])) self.ticket_black_list[train_no] = datetime.datetime.now() break time.sleep(1)
def initNoComplete(self): """ 获取订单前需要进入订单列表页,获取订单列表页session :return: """ initNoCompleteUrl = "https://kyfw.12306.cn/otn/queryOrder/initNoComplete" data = {"_json_att": None} myurllib2.Post(initNoCompleteUrl, data)
def queryOrderWaitTime(self): """ 排队获取订单等待信息,每隔3秒请求一次,最高请求次数为20次! :return: """ queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime" data = { "random": "149545481029" + str(random.randint(1, 9)), "tourFlag": "dc", "REPEAT_SUBMIT_TOKEN": self.get_token(), } num = 1 while True: num += 1 if num > 20: print("超出排队时间,自动放弃,正在重新刷票") break try: queryOrderWaitTimeResult = json.loads( myurllib2.Post(queryOrderWaitTimeUrl, data)) except ValueError: pass if "status" in queryOrderWaitTimeResult and queryOrderWaitTimeResult[ "status"]: if "orderId" in queryOrderWaitTimeResult[ "data"] and queryOrderWaitTimeResult["data"][ "orderId"] != "null": self.initNoComplete() orderId = self.queryMyOrderNoComplete() if orderId: raise ticketIsExitsException(( "恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!" .format(orderId))) else: print("等待出票中...") continue elif "msg" in queryOrderWaitTimeResult[ "data"] and queryOrderWaitTimeResult["data"]["msg"]: orderId = self.queryMyOrderNoComplete() if orderId: raise ticketIsExitsException(( "恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!" .format(orderId))) else: break elif "messages" in queryOrderWaitTimeResult and queryOrderWaitTimeResult[ "messages"]: print("订单提交失败: " + queryOrderWaitTimeResult["messages"]) orderId = self.queryMyOrderNoComplete() if orderId: raise ticketIsExitsException(( "恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!" .format(orderId))) else: break else: print("订单提交中,请耐心等待") time.sleep(3)
def checkQueueOrder(self): """ 模拟提交订单是确认按钮,参数获取方法还是get_ticketInfoForPassengerForm 中获取 :return: """ passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr( ) checkQueueOrderUrl = "https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue" data = { "passengerTicketStr": self.set_type + "," + ",".join(passengerTicketStrList).rstrip( "_{0}".format(self.set_type)), "oldPassengerStr": "".join(oldPassengerStr), "purpose_codes": self.get_ticketInfoForPassengerForm()["purpose_codes"], "key_check_isChange": self.get_ticketInfoForPassengerForm()["key_check_isChange"], "leftTicketStr": self.get_ticketInfoForPassengerForm()["leftTicketStr"], "train_location": self.get_ticketInfoForPassengerForm()["train_location"], "seatDetailType": "000", # 开始需要选择座位,但是目前12306不支持自动选择作为,那这个参数为默认 "roomType": "00", # 好像是根据一个id来判断选中的,两种 第一种是00,第二种是10,但是我在12306的页面没找到该id,目前写死是00,不知道会出什么错 "dwAll": "N", "REPEAT_SUBMIT_TOKEN": self.get_token(), } try: checkQueueOrderResult = json.loads( myurllib2.Post(checkQueueOrderUrl, data)) if "status" in checkQueueOrderResult and checkQueueOrderResult[ "status"]: c_data = checkQueueOrderResult[ "data"] if "data" in checkQueueOrderResult else {} if 'submitStatus' in c_data and c_data['submitStatus']: print("出票成功!") if self.queryOrderWaitTime(): return True else: if 'errMsg' in c_data and c_data['errMsg']: print("出票失败," + c_data['errMsg']) else: print(c_data) print('订票失败!很抱歉,请重试提交预订功能!') elif "messages" in checkQueueOrderResult and checkQueueOrderResult[ "messages"]: print("提交订单失败,错误信息: " + checkQueueOrderResult["messages"]) else: print("订单提交中,请耐心等待:" + str(checkQueueOrderResult["validateMessages"])) except ValueError: pass
def getUserinfo(): """ 登录成功后,显示用户名 :return: """ url = 'https://kyfw.12306.cn/otn/modifyUser/initQueryUserInfo' data = dict(_json_att=None) result = myurllib2.Post(url, data) userinfo = result name = r'<input name="userDTO.loginUserDTO.user_name" style="display:none;" type="text" value="(\S+)" />' try: stoidinput("欢迎 %s 登录" % re.search(name, result).group(1)) except AttributeError: pass
def check_user(self): """ 检查用户是否达到订票条件 :return: """ check_user_url = 'https://kyfw.12306.cn/otn/login/checkUser' data = dict(_json_att=None) check_user = json.loads(myurllib2.Post(check_user_url, data), encoding='utf-8') check_user_flag = check_user['data']['flag'] if check_user_flag is True: print ('尝试提交订单...') return True else: if check_user['messages']: print ('用户检查失败:%s,可能未登录,可能session已经失效' % check_user['messages'][0]) else: print ('用户检查失败: %s,可能未登录,可能session已经失效' % check_user)
def checkOrderInfo(self, train_no, set_type): """ 检查支付订单,需要提交REPEAT_SUBMIT_TOKEN passengerTicketStr : 座位编号,0,票类型,乘客名,证件类型,证件号,手机号码,保存常用联系人(Y或N) oldPassengersStr: 乘客名,证件类型,证件号,乘客类型 :return: """ passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr( ) checkOrderInfoUrl = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo' data = OrderedDict() data['cancel_flag'] = 2 data['bed_level_order_num'] = "000000000000000000000000000000" data['passengerTicketStr'] = self.set_type + "," + ",".join( passengerTicketStrList).rstrip("_{0}".format(self.set_type)) data['oldPassengerStr'] = "".join(oldPassengerStr) data['tour_flag'] = 'dc' data['whatsSelect'] = 1 data['REPEAT_SUBMIT_TOKEN'] = self.token checkOrderInfo = json.loads(myurllib2.Post( checkOrderInfoUrl, data, )) if 'data' in checkOrderInfo: if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo[ "data"]["ifShowPassCode"] == "Y": is_need_code = True if self.getQueueCount(train_no, set_type, is_need_code): return True if "ifShowPassCode" in checkOrderInfo[ "data"] and checkOrderInfo['data']['submitStatus'] is True: print('车票提交通过,正在尝试排队') is_need_code = False if self.getQueueCount(train_no, set_type, is_need_code): return True else: if "errMsg" in checkOrderInfo['data'] and checkOrderInfo[ 'data']["errMsg"]: print checkOrderInfo['data']["errMsg"] else: print checkOrderInfo elif 'messages' in checkOrderInfo and checkOrderInfo['messages']: print(checkOrderInfo['messages'][0])
def checkOrderInfo(self): """ 检查支付订单,需要提交REPEAT_SUBMIT_TOKEN passengerTicketStr : 座位编号,0,票类型,乘客名,证件类型,证件号,手机号码,保存常用联系人(Y或N) oldPassengersStr: 乘客名,证件类型,证件号,乘客类型 :return: """ passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr( ) checkOrderInfoUrl = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo' data = OrderedDict() data['cancel_flag'] = 2 data['bed_level_order_num'] = "000000000000000000000000000000" # 'passengerTicketStr': self.set_type+',0,'+self.user_info[0]['passenger_id_type_code']+","+self.user_info[0]["passenger_name"]+","+self.user_info[0]['passenger_type']+","+self.user_info[0]['passenger_id_no']+","+self.user_info[0]['mobile_no']+',N', # 'oldPassengerStr': self.user_info[0]['passenger_name']+","+self.user_info[0]['passenger_type']+","+self.user_info[0]['passenger_id_no']+","+self.user_info[0]['passenger_type']+'_', data['passengerTicketStr'] = self.set_type + "," + ",".join( passengerTicketStrList).rstrip("_{0}".format(self.set_type)) data['oldPassengerStr'] = "".join(oldPassengerStr) data['tour_flag'] = 'dc' data['whatsSelect'] = 1 data['REPEAT_SUBMIT_TOKEN'] = self.token checkOrderInfo = json.loads(myurllib2.Post( checkOrderInfoUrl, data, )) if 'data' in checkOrderInfo: if checkOrderInfo['data']['submitStatus'] is True: print('车票提交通过,正在尝试排队') return True else: if "errMsg" in checkOrderInfo['data'] and checkOrderInfo[ 'data']["errMsg"]: print checkOrderInfo['data']["errMsg"] else: print checkOrderInfo elif 'messages' in checkOrderInfo and checkOrderInfo['messages']: print(checkOrderInfo['messages'][0]) print("排队失败,重新刷票中")
def check_user(self): """ 检查用户是否达到订票条件 :return: """ check_user_url = 'https://kyfw.12306.cn/otn/login/checkUser' data = dict(_json_att=None) check_user = json.loads(myurllib2.Post(check_user_url, data), encoding='utf-8') check_user_flag = check_user['data']['flag'] if check_user_flag is True: return True else: if check_user['messages']: print('用户检查失败:%s,可能未登录,可能session已经失效' % check_user['messages'][0]) print('正在尝试重新登录') self.call_login() self.is_check_user["user_time"] = datetime.datetime.now() else: print('用户检查失败: %s,可能未登录,可能session已经失效' % check_user) print('正在尝试重新登录') self.call_login() self.is_check_user["user_time"] = datetime.datetime.now()
def queryOrderWaitTime(self): """ 排队获取订单等待信息,每隔3秒请求一次,最高请求次数为20次! :return: """ # queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime" # data = { # "random": "{0}{1}".format(int(time.time()), random.randint(1, 9)), # "tourFlag": "dc", # "REPEAT_SUBMIT_TOKEN": self.get_token(), # } num = 1 while True: _random = int(round(time.time() * 1000)) num += 1 if num > 30: print("超出排队时间,自动放弃,正在重新刷票") break try: # queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime?random={0}&tourFlag=dc&_json_att=&REPEAT_SUBMIT_TOKEN={1}".format(_random, self.get_token()) data = {"random": _random, "tourFlag": "dc"} queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime" queryOrderWaitTimeResult = json.loads( myurllib2.Post(queryOrderWaitTimeUrl, data)) except ValueError: queryOrderWaitTimeResult = {} if queryOrderWaitTimeResult: if "status" in queryOrderWaitTimeResult and queryOrderWaitTimeResult[ "status"]: if "orderId" in queryOrderWaitTimeResult[ "data"] and queryOrderWaitTimeResult["data"][ "orderId"] is not None: sendEmail( "恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!" .format( queryOrderWaitTimeResult["data"]["orderId"])) raise ticketIsExitsException( "恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!" .format( queryOrderWaitTimeResult["data"]["orderId"])) elif "msg" in queryOrderWaitTimeResult[ "data"] and queryOrderWaitTimeResult["data"]["msg"]: print queryOrderWaitTimeResult["data"]["msg"] break elif "waitTime" in queryOrderWaitTimeResult[ "data"] and queryOrderWaitTimeResult["data"][ "waitTime"]: print("排队等待时间预计还剩 {0} ms".format( 0 - queryOrderWaitTimeResult["data"]["waitTime"])) else: print("正在等待中") elif "messages" in queryOrderWaitTimeResult and queryOrderWaitTimeResult[ "messages"]: print("排队等待失败: " + queryOrderWaitTimeResult["messages"]) else: print("第{}次排队中,请耐心等待".format(num)) else: print("排队中") time.sleep(1) order_id = self.queryMyOrderNoComplete( ) # 尝试查看订单列表,如果有订单,则判断成功,不过一般可能性不大 if order_id: sendEmail( "恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!". format(order_id)) raise ticketIsExitsException( "恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!". format(order_id)) else: print(ticketNumOutException("订单提交失败!,正在重新刷票"))
def checkQueueOrder(self, is_node_code=False): """ 模拟提交订单是确认按钮,参数获取方法还是get_ticketInfoForPassengerForm 中获取 :return: """ passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr( ) checkQueueOrderUrl = "https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue" data = { "passengerTicketStr": self.set_type + "," + ",".join(passengerTicketStrList).rstrip( "_{0}".format(self.set_type)), "oldPassengerStr": "".join(oldPassengerStr), "purpose_codes": self.get_ticketInfoForPassengerForm()["purpose_codes"], "key_check_isChange": self.get_ticketInfoForPassengerForm()["key_check_isChange"], "leftTicketStr": self.get_ticketInfoForPassengerForm()["leftTicketStr"], "train_location": self.get_ticketInfoForPassengerForm()["train_location"], "seatDetailType": "000", # 开始需要选择座位,但是目前12306不支持自动选择作为,那这个参数为默认 "roomType": "00", # 好像是根据一个id来判断选中的,两种 第一种是00,第二种是10,但是我在12306的页面没找到该id,目前写死是00,不知道会出什么错 "dwAll": "N", "whatsSelect": 1, "_json_at": "", "REPEAT_SUBMIT_TOKEN": self.get_token(), } try: for i in range(3): if is_node_code: print("正在使用自动识别验证码功能") randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn' codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp&%s' % random.random( ) result = myurllib2.get(codeimg) img_path = './tkcode' open(img_path, 'wb').write(result) randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main() randData = { "randCode": randCode, "rand": "randp", "_json_att": None, "REPEAT_SUBMIT_TOKEN": self.get_token() } fresult = json.loads(myurllib2.Post(randurl, randData), encoding='utf8') # 校验验证码是否正确 checkcode = fresult['data']['msg'] if checkcode == 'TRUE': print("验证码通过,正在提交订单") data['randCode'] = randCode break else: print("验证码有误, 接口返回{0} 第{1}次尝试重试".format(fresult, i)) else: print("不需要验证码") break # print("".join(data)) checkQueueOrderResult = json.loads( myurllib2.Post(checkQueueOrderUrl, data)) if "status" in checkQueueOrderResult and checkQueueOrderResult[ "status"]: c_data = checkQueueOrderResult[ "data"] if "data" in checkQueueOrderResult else {} if 'submitStatus' in c_data and c_data['submitStatus'] is True: print("提交订单成功!") self.queryOrderWaitTime() else: if 'errMsg' in c_data and c_data['errMsg']: print("提交订单失败,{0}".format(c_data['errMsg'])) else: print(c_data) print('订票失败!很抱歉,请重试提交预订功能!') elif "messages" in checkQueueOrderResult and checkQueueOrderResult[ "messages"]: print("提交订单失败,错误信息: " + checkQueueOrderResult["messages"]) else: print("提交订单中,请耐心等待:" + str(checkQueueOrderResult["validateMessages"])) except ValueError: print("接口 {} 无响应".format(checkQueueOrderUrl))
def getQueueCount(self, train_no, set_type, is_need_code): """ # 模拟查询当前的列车排队人数的方法 # 返回信息组成的提示字符串 :param token: :return: """ l_time = time.localtime(time.time()) new_train_date = time.strftime("%a %b %d %Y", l_time) getQueueCountUrl = 'https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount' data = { 'train_date': str(new_train_date) + " 00:00:00 GMT+0800 (中国标准时间)", 'train_no': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO'] ['train_no'], 'stationTrainCode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO'] ['station_train_code'], 'seatType': self.set_type, 'fromStationTelecode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO'] ['from_station'], 'toStationTelecode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO'] ['to_station'], 'leftTicket': self.get_ticketInfoForPassengerForm()['leftTicketStr'], 'purpose_codes': self.get_ticketInfoForPassengerForm()['purpose_codes'], 'train_location': self.get_ticketInfoForPassengerForm()['train_location'], 'REPEAT_SUBMIT_TOKEN': self.get_token(), } getQueueCountResult = json.loads(myurllib2.Post( getQueueCountUrl, data)) if "status" in getQueueCountResult and getQueueCountResult[ "status"] is True: if "countT" in getQueueCountResult["data"]: ticket = getQueueCountResult["data"]["ticket"] ticket_split = sum(map( self.conversion_int, ticket.split(","))) if ticket.find(",") != -1 else ticket countT = getQueueCountResult["data"]["countT"] if int(countT) is 0: if int(ticket_split) < len(self.user_info): print("当前余票数小于乘车人数,放弃订票") else: print("排队成功, 当前余票还剩余: {0} 张".format(ticket_split)) if self.checkQueueOrder(is_need_code): return True else: print("当前排队人数:" + str(countT) + "当前余票还剩余:{0} 张,继续排队中".format(ticket_split)) else: print("排队发现未知错误{0},将此列车 {1}加入小黑屋".format( getQueueCountResult, train_no)) self.ticket_black_list[train_no] = datetime.datetime.now() elif "messages" in getQueueCountResult and getQueueCountResult[ "messages"]: print("排队异常,错误信息:{0}, 将此列车 {1}加入小黑屋".format( getQueueCountResult["messages"][0], train_no)) self.ticket_black_list[train_no] = datetime.datetime.now() else: if "validateMessages" in getQueueCountResult and getQueueCountResult[ "validateMessages"]: print(str(getQueueCountResult["validateMessages"])) self.ticket_black_list[train_no] = datetime.datetime.now() else: print("未知错误 {0}".format("".join(getQueueCountResult)))