def getRepeatSubmitToken(self): """ 获取提交车票请求token :return: token """ initdc_url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc' initdc_result = myurllib2.get(initdc_url) token_name = re.compile(r"var globalRepeatSubmitToken = '(\S+)'") ticketInfoForPassengerForm_name = re.compile( r'var ticketInfoForPassengerForm=(\{.+\})?') order_request_params_name = re.compile( r'var orderRequestDTO=(\{.+\})?') # if token_name and ticketInfoForPassengerForm_name and order_request_params_name: self.token = re.search(token_name, initdc_result).group(1) re_tfpf = re.findall(ticketInfoForPassengerForm_name, initdc_result) re_orp = re.findall(order_request_params_name, initdc_result) if re_tfpf: self.ticketInfoForPassengerForm = json.loads(re_tfpf[0].replace( "'", '"')) else: pass if re_orp: self.order_request_params = json.loads(re_orp[0].replace("'", '"')) else: pass
def logout(self): url = 'https://kyfw.12306.cn/otn/login/loginOut' result = myurllib2.get(url) if result: print(u"已退出") else: print(u"退出失败")
def logout(): url = 'https://kyfw.12306.cn/otn/login/loginOut' result = myurllib2.get(url) if result: stoidinput("已退出") else: errorinput("退出失败")
def readImg(): """ 增加手动打码,只是登录接口,完全不用担心提交票的效率问题 思路 1.调用PIL显示图片 2.图片位置说明,验证码图片中每个图片代表一个下标,依次类推,1,2,3,4,5,6,7,8 3.控制台输入对应下标,按照英文逗号分开,即可手动完成打码, :return: """ global randCode stoidinput("下载验证码...") img_path = './tkcode' result = myurllib2.get(codeimg) try: open(img_path, 'wb').write(result) if _get_yaml()["is_aotu_code"]: randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main() else: img = Image.open('./tkcode') img.show() codexy() except OSError as e: print(e) pass
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 submitOrderRequest(self, from_station, to_station): """ 提交车次信息 车次对应字典 {32: '商务座 ', 31: '一等座 ', 30: '二等座 ', 25: '特等座 ', 23: '软卧 ', 28: '硬卧 ', 29: '硬座 ', 26: '无座 ' } 参照station_seat()方法 :return: """ select_url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT'.format(self.station_date, from_station, to_station) station_ticket = json.loads(myurllib2.get(select_url), encoding='utf-8') value = station_ticket['data'] if not value: print ('{0}-{1} 车次坐席查询为空...'.format(self.from_station, self.to_station)) else: if value['result']: for i in value['result']: ticket_info = i.split('|') if ticket_info[11] == "Y" and ticket_info[1] == "预订": # 筛选未在开始时间内的车次 for j in range(len(self._station_seat)): is_ticket_pass = ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))] # print self._station_seat[j] if is_ticket_pass != '' and is_ticket_pass != '无' and ticket_info[3] in self.station_trains and is_ticket_pass != '*': # 过滤有效目标车次 # tiket_values = [k for k in value['map'].values()] self.secretStr = ticket_info[0] train_no = ticket_info[3] print ('车次: ' + train_no + ' 始发车站: ' + self.from_station + ' 终点站: ' + self.to_station + ' ' + self._station_seat[j].encode("utf8") + ':' + ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))]) if self.ticket_black_list.has_key(train_no) and (datetime.datetime.now() - self.ticket_black_list[train_no]).seconds/60 < int(self.ticket_black_list_time): print("该车次{} 正在被关小黑屋,跳过此车次".format(train_no)) break else: print ('正在尝试提交订票...') if self.check_user(): self.submit_station() self.getPassengerTicketStr(self._station_seat[j].encode("utf8")) self.getRepeatSubmitToken() self.user_info = self.getPassengerDTOs() if self.checkOrderInfo(train_no, self._station_seat[j].encode("utf8")): break else: pass print "当前车次{0} 查询无符合条件坐席,正在重新查询".format(ticket_info[3]) elif ticket_info[11] == "N": print("当前车次{0} 无票".format(ticket_info[3])) else: print("当前这次还处于待售状态,请耐心等待") time.sleep(self.expect_refresh_interval) else: raise ticketConfigException("车次配置信息有误,请检查")
def submitOrderRequestFunc(self, from_station, to_station, station_date=None): select_url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT'.format( self.station_date if station_date is None else station_date, from_station, to_station) station_ticket = json.loads(myurllib2.get(select_url), encoding='utf-8') return station_ticket
def logout(self): url = 'https://kyfw.12306.cn/otn/login/loginOut' result = myurllib2.get(url) if result: print(u"已退出") else: print(u"退出失败") # if __name__ == "__main__": # # main() # # logout()
def logout(self): url = 'https://kyfw.12306.cn/otn/login/loginOut' result = myurllib2.get(url) if result: print (u"已退出") else: print (u"退出失败") # if __name__ == "__main__": # # main() # # logout()
def readImg(): global randCode stoidinput("下载验证码...") img_path = './tkcode' result = myurllib2.get(codeimg) try: open(img_path, 'wb').write(result) randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main() except OSError as e: print(e) pass
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()) queryOrderWaitTimeResult = json.loads(myurllib2.get(queryOrderWaitTimeUrl)) 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 leftTicketLog(self, from_station, to_station): """ 模拟进入车次列表页 :param from_station: :param to_station: :return: """ leftTicketLogUrl = 'https://kyfw.12306.cn/otn/leftTicket/log?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT'.format( self.station_date, from_station, to_station) leftTicketLog = json.loads(myurllib2.get(leftTicketLogUrl), encoding='utf-8') if "status" in leftTicketLog and leftTicketLog["status"] is True: return True else: if "message" in leftTicketLog and leftTicketLog["message"]: print leftTicketLog["message"] elif "validateMessages" in leftTicketLog and leftTicketLog["validateMessages"]: print leftTicketLog["validateMessages"]
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 cookietp(): stoidinput("获取Cookie") Url = "https://kyfw.12306.cn/otn/login/init" myurllib2.get(Url)