解决慢排队

pull/42/head
wenxianping 2018-08-22 17:03:25 +08:00
parent ff4b397d39
commit 7d263baa56
5 changed files with 148 additions and 102 deletions

View File

@ -41,26 +41,47 @@
set:
station_dates:
- "2018-03-19"
# - "2018-02-21"
- "2018-09-05"
station_trains:
- "G4831"
- "G6504"
- "G6224"
- "G6032"
- "G6346"
- "G6218"
- "G6030"
- "G1006"
- "G818"
- "G532"
- "G6552"
- "G6208"
- "G822"
- "G6506"
- "G1008"
- "G6508"
- "G9710"
- "G6214"
- "G6234"
- "G6510"
- "G6016"
- "G6514"
- "G6512"
- "G1010"
- "G2904"
- "G6204"
- "G6034"
from_station: "上海"
to_station: "长沙"
from_station: "深圳"
to_station: "广州"
set_type:
- "二等座"
- "商务座"
- "一等座"
is_more_ticket: True
ticke_peoples:
- "文贤平"
# - "彭淑杰"
12306count:
# - uesr: ""
# - pwd: "apple1995"
- uesr: "@qq.com"
# - uesr: "qqxin1011"
# - pwd: "quxm19861011"
- uesr: "931128603@qq.com"
- pwd: "QWERTY"
select_refresh_interval: 1
@ -75,14 +96,10 @@ damatu:
email_conf:
is_email: True
email: "@qq.com "
notice_email_list: "@qq.com"
username: ""
password: ""
email: "931128603@qq.com "
notice_email_list: "931128603@qq.com"
username: "931128603"
password: "xrvenridfpnnbehh"
host: "smtp.qq.com"
is_cdn: 2

View File

@ -216,10 +216,6 @@ class GoLogin:
login_num = 0
while True:
self.cookietp()
self.httpClint.set_cookies(_jc_save_showIns="true",
_jc_save_wfdc_flag="dc",
_jc_save_fromDate=_get_yaml()["set"]["station_dates"][0],
_jc_save_toDate=_get_yaml()["set"]["station_dates"][0])
self.urlConf["getCodeImg"]["req_url"] = self.urlConf["getCodeImg"]["req_url"].format(random.random())
self.readImg(self.urlConf["getCodeImg"])
self.randCode = self.getRandCode()

View File

@ -207,7 +207,8 @@ class select:
if 'data' in jsonData and jsonData['data'] and 'normal_passengers' in jsonData['data'] and 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]
_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']:
@ -239,7 +240,8 @@ class select:
} 参照station_seat()方法
:return:
"""
station_tickets = [self.submitOrderRequestFunc(from_station, to_station, station_date) for station_date in self.station_dates]
station_tickets = [self.submitOrderRequestFunc(from_station, to_station, station_date) for station_date in
self.station_dates]
for station_ticket in station_tickets:
value = station_ticket['data']
if not value:
@ -252,13 +254,17 @@ class select:
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 != '*': # 过滤有效目标车次
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 (u'车次: ' + 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):
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(u"该车次{} 正在被关小黑屋,跳过此车次".format(train_no))
break
else:
@ -375,7 +381,7 @@ class select:
self.user_info[0]['mobile_no'] + ',N')
oldPassengerStr.append(
self.user_info[0]['passenger_name'] + "," + self.user_info[0]['passenger_id_type_code'] + "," +
self.user_info[0]['passenger_id_no'] + "," + self.user_info[0]['passenger_type'] + '_')
self.user_info[0]['passenger_id_no'] + "," + self.user_info[0]['passenger_type'])
else:
for i in range(len(self.user_info)):
passengerTicketStrList.append(
@ -397,23 +403,26 @@ class select:
passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr()
checkOrderInfoUrl = self.confUrl["checkOrderInfoUrl"]
data = collections.OrderedDict()
data['passengerTicketStr'] = self.set_type + "," + ",".join(passengerTicketStrList).rstrip(
"_{0}".format(self.set_type))
data['oldPassengerStr'] = "".join(oldPassengerStr)
data['REPEAT_SUBMIT_TOKEN'] = self.token
data['randCode'] = ""
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
data['_json_att'] = ""
checkOrderInfo = self.httpClint.send(checkOrderInfoUrl, data)
if 'data' in checkOrderInfo:
ifShowPassCodeTime = int(checkOrderInfo["data"]["ifShowPassCodeTime"]) / float(1000)
if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo["data"]["ifShowPassCode"] == "Y":
is_need_code = True
if self.getQueueCount(train_no, set_type, is_need_code):
if self.getQueueCount(train_no, set_type, is_need_code, ifShowPassCodeTime):
return True
if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo['data']['submitStatus'] is True:
print (u'车票提交通过,正在尝试排队')
is_need_code = False
if self.getQueueCount(train_no, set_type, is_need_code):
if self.getQueueCount(train_no, set_type, is_need_code, ifShowPassCodeTime):
return True
else:
if "errMsg" in checkOrderInfo['data'] and checkOrderInfo['data']["errMsg"]:
@ -424,24 +433,31 @@ class select:
elif 'messages' in checkOrderInfo and checkOrderInfo['messages']:
print (checkOrderInfo['messages'][0])
def getQueueCount(self, train_no, set_type, is_need_code):
def getQueueCount(self, train_no, set_type, is_need_code, ifShowPassCodeTime):
"""
# 模拟查询当前的列车排队人数的方法
# 返回信息组成的提示字符串
:param token:
:return:
"""
l_time = time.localtime(time.time())
new_train_date = time.strftime("%a %b %d %Y", l_time)
new_train_date = str(time.asctime(time.strptime(self.station_dates[0], "%Y-%m-%d"))).split(" ")
getQueueCountUrl = self.confUrl["getQueueCountUrl"]
data = collections.OrderedDict()
data['train_date'] = str(new_train_date) + " 00:00:00 GMT+0800 (中国标准时间)",
data['train_date'] = "{0} {1} {2} {3} {4} GMT+0800 (CST)".format(
new_train_date[0],
new_train_date[1],
new_train_date[3],
new_train_date[5],
time.strftime("%H:%M:%S", time.localtime(time.time()))
),
data['train_no'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_no'],
data['stationTrainCode'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['station_train_code'],
data['stationTrainCode'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO'][
'station_train_code'],
data['seatType'] = self.set_type,
data['fromStationTelecode'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['from_station'],
data['fromStationTelecode'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO'][
'from_station'],
data['toStationTelecode'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['to_station'],
data['leftTicket'] = self.get_ticketInfoForPassengerForm()['leftTicketStr'],
data['leftTicket'] = urllib.unquote(self.get_ticketInfoForPassengerForm()['leftTicketStr']),
data['purpose_codes'] = self.get_ticketInfoForPassengerForm()['purpose_codes'],
data['train_location'] = self.get_ticketInfoForPassengerForm()['train_location'],
data['REPEAT_SUBMIT_TOKEN'] = self.get_token(),
@ -456,7 +472,7 @@ class select:
print(u"当前余票数小于乘车人数,放弃订票")
else:
print(u"排队成功, 当前余票还剩余: {0}".format(ticket_split))
if self.checkQueueOrder(is_need_code):
if self.checkQueueOrder(ifShowPassCodeTime, is_need_code):
return True
else:
print(u"当前排队人数: {1} 当前余票还剩余:{0} 张,继续排队中".format(ticket_split, countT))
@ -488,7 +504,7 @@ class select:
fresult = self.httpClint.send(checkRandCodeAnsyn, randData) # 校验验证码是否正确
return fresult['data']['msg']
def checkQueueOrder(self, is_node_code=False):
def checkQueueOrder(self, ifShowPassCodeTime, is_node_code=False):
"""
模拟提交订单是确认按钮参数获取方法还是get_ticketInfoForPassengerForm 中获取
:return:
@ -497,13 +513,14 @@ class select:
passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr()
checkQueueOrderUrl = self.confUrl["checkQueueOrderUrl"]
data = {
"passengerTicketStr": self.set_type + "," + ",".join(passengerTicketStrList).rstrip("_{0}".format(self.set_type)),
"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"],
"key_check_isChange": urllib.unquote(self.get_ticketInfoForPassengerForm()["key_check_isChange"]),
"leftTicketStr": urllib.unquote(self.get_ticketInfoForPassengerForm()["leftTicketStr"]),
"train_location": self.get_ticketInfoForPassengerForm()["train_location"],
"seatDetailType": "000", # 开始需要选择座位但是目前12306不支持自动选择作为那这个参数为默认
"seatDetailType": "", # 开始需要选择座位但是目前12306不支持自动选择作为那这个参数为默认
"roomType": "00", # 好像是根据一个id来判断选中的两种 第一种是00第二种是10但是我在12306的页面没找到该id目前写死是00不知道会出什么错
"dwAll": "N",
"whatsSelect": 1,
@ -529,7 +546,8 @@ class select:
print(u"不需要验证码")
buy_end_time = (datetime.datetime.now() - self.buy_ticket_time).seconds
print(u"总共花费时长{0}S".format(buy_end_time))
time.sleep(8-buy_end_time if buy_end_time<8 else 0)
print(ifShowPassCodeTime)
time.sleep(ifShowPassCodeTime)
checkQueueOrderResult = self.httpClint.send(checkQueueOrderUrl, data)
if "status" in checkQueueOrderResult and checkQueueOrderResult["status"]:
c_data = checkQueueOrderResult["data"] if "data" in checkQueueOrderResult else {}
@ -572,13 +590,17 @@ class select:
queryOrderWaitTimeResult = {}
if queryOrderWaitTimeResult:
if "status" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["status"]:
if "orderId" in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["orderId"] is not None:
sendEmail(u"恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付".format(queryOrderWaitTimeResult["data"]["orderId"]))
raise ticketIsExitsException(u"恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付".format(queryOrderWaitTimeResult["data"]["orderId"]))
if "orderId" in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"][
"orderId"] is not None:
sendEmail(u"恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付".format(
queryOrderWaitTimeResult["data"]["orderId"]))
raise ticketIsExitsException(u"恭喜您订票成功,订单号为:{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"]:
elif "waitTime" in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"][
"waitTime"]:
print(u"排队等待时间预计还剩 {0} ms".format(0 - queryOrderWaitTimeResult["data"]["waitTime"]))
else:
print ("正在等待中")
@ -606,13 +628,17 @@ class select:
except ValueError:
queryMyOrderNoCompleteResult = {}
if queryMyOrderNoCompleteResult:
if "data" in queryMyOrderNoCompleteResult and queryMyOrderNoCompleteResult["data"] and "orderDBList" in queryMyOrderNoCompleteResult["data"] and queryMyOrderNoCompleteResult["data"]["orderDBList"]:
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 "data" in queryMyOrderNoCompleteResult and "orderCacheDTO" in queryMyOrderNoCompleteResult["data"] and queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]:
if "message" in queryMyOrderNoCompleteResult["data"]["orderCacheDTO"] and queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]:
elif "data" in queryMyOrderNoCompleteResult and "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"])
raise ticketNumOutException(
queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]["message"])
else:
if "message" in queryMyOrderNoCompleteResult and queryMyOrderNoCompleteResult["message"]:
print queryMyOrderNoCompleteResult["message"]
@ -645,7 +671,8 @@ class select:
"_json_att": ""
}
cancelNoCompleteMyOrderResult = self.httpClint.send(cancelNoCompleteMyOrderUrl, cancelNoCompleteMyOrderData)
if "data" in cancelNoCompleteMyOrderResult and "existError" in cancelNoCompleteMyOrderResult["data"] and cancelNoCompleteMyOrderResult["data"]["existError"] == "N":
if "data" in cancelNoCompleteMyOrderResult and "existError" in cancelNoCompleteMyOrderResult["data"] and \
cancelNoCompleteMyOrderResult["data"]["existError"] == "N":
print(u"排队超时,已为您自动取消订单,订单编号: {0}".format(sequence_no))
time.sleep(2)
return True
@ -715,11 +742,14 @@ class select:
while 1:
try:
num += 1
if "user_time" in self.is_check_user and (datetime.datetime.now() - self.is_check_user["user_time"]).seconds/60 > 5:
if "user_time" in self.is_check_user and (
datetime.datetime.now() - self.is_check_user["user_time"]).seconds / 60 > 5:
# 5分钟检查一次用户是否登录
self.check_user()
time.sleep(self.select_refresh_interval)
if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00" or time.strftime('%H:%M:%S', time.localtime(time.time())) < "06:00:00":
if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00" or time.strftime('%H:%M:%S',
time.localtime(
time.time())) < "06:00:00":
print(u"12306休息时间本程序自动停止,明天早上6点将自动运行")
while 1:
time.sleep(1)
@ -730,9 +760,13 @@ class select:
start_time = datetime.datetime.now()
self.submitOrderRequestImplement(from_station, to_station)
print u"正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 cdn轮询IP {4} 当前cdn总数{5} 总耗时{3}ms".format(num,
",".join(self.station_dates),
",".join(self.station_trains),
(datetime.datetime.now()-start_time).microseconds/1000, self.httpClint.cdn,
",".join(
self.station_dates),
",".join(
self.station_trains),
(
datetime.datetime.now() - start_time).microseconds / 1000,
self.httpClint.cdn,
len(self.cdn_list))
self.set_cdn()
except PassengerUserException as e:
@ -757,8 +791,8 @@ class select:
print(e.message)
except KeyError as e:
print(e.message)
except TypeError as e:
print(u"12306接口无响应正在重试 {0}".format(e.message))
# except TypeError as e:
# print(u"12306接口无响应正在重试 {0}".format(e.message))
except socket.error as e:
print(e.message)

View File

@ -1,6 +1,7 @@
# -*- coding: utf8 -*-
import json
import socket
from collections import OrderedDict
from time import sleep
import requests
@ -48,17 +49,16 @@ class HTTPClient(object):
def _set_header(self):
"""设置header"""
return {
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"X-Requested-With": "application/json, text/javascript, */*; q=0.01",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5",
"Referer": "https://kyfw.12306.cn/otn/login/init",
"Accept": "*/*",
"Accept-Encoding": "br, gzip, deflate",
"Origin": "https://kyfw.12306.cn",
"Accept-Language": "zh-cn",
"Connection": "keep-alive",
}
header_dict = OrderedDict()
header_dict["Host"] = "kyfw.12306.cn"
header_dict["keep-alive"] = "keep-alive"
header_dict["Accept"] = "application/json, text/plain, */*"
header_dict[
"User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) 12306-electron/1.0.1 Chrome/59.0.3071.115 Electron/1.8.4 Safari/537.36"
header_dict["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8"
header_dict["Accept-Encoding"] = "gzip, deflate"
header_dict["Accept-Language"] = "zh-CN"
return header_dict
def setHeaders(self, headers):
self._s.headers.update(headers)
@ -103,7 +103,6 @@ class HTTPClient(object):
allow_redirects = False
is_logger = urls["is_logger"]
error_data = {"code": 99999, "message": u"重试次数达到上限"}
self.setHeadersReferer(urls["Referer"])
if data:
method = "post"
self.setHeaders({"Content-Length": "{0}".format(len(data))})

BIN
tkcode

Binary file not shown.

Before

Width:  |  Height:  |  Size: 0 B

After

Width:  |  Height:  |  Size: 13 KiB