增加余票不足优先提交功能

pull/49/merge
wenxianping 2018-09-21 14:40:46 +08:00
parent cce998d0be
commit 2f2d62af19
8 changed files with 70 additions and 52 deletions

View File

@ -116,3 +116,10 @@
- 修改已知bug - 修改已知bug
- 优化代码结构 - 优化代码结构
- 新增第三方库wrapcache需要重新安装requirements.txt - 新增第三方库wrapcache需要重新安装requirements.txt
- 2018.9.21更新,修复已知问题,增加余票不足优先提交功能
- 修改已知bug
- 优化查询攻略
- 优化随机查询1-3秒经测试很稳定不会封ip
- 增加余票不足优先提交功能(当余票小于乘车人,如果选择优先提交,则删减联系人和余票数一致在提交)
- 开关为ticket_config.yaml配置文件中is_more_ticket参数

View File

@ -5,28 +5,29 @@ set:
# - 2018-01-06 # - 2018-01-06
# - 2018-01-07 # - 2018-01-07
station_dates: station_dates:
- "2018-09-05" - "2018-09-28"
# 过滤车次(list)格式ex # 过滤车次(list)格式ex
# - "G1353" # - "G1353"
# - "G1329" # - "G1329"
station_trains: station_trains:
- "D2304" - ""
# 出发城市,比如深圳北,就填深圳就搜得到 # 出发城市,比如深圳北,就填深圳就搜得到
from_station: "深圳" from_station: ""
# 到达城市 比如深圳北,就填深圳就搜得到 # 到达城市 比如深圳北,就填深圳就搜得到
to_station: "上饶" to_station: ""
# 座位(list) 多个座位ex: # 座位(list) 多个座位ex:
# - "二等座" # - "二等座"
# - "一等座" # - "一等座"
set_type: set_type:
- "二等座" - ""
# 余票不足是否自动提交,目前应该没什么卵用 # 当余票小于乘车人,如果选择优先提交,则删减联系人和余票数一致在提交
is_more_ticket: True is_more_ticket: False
# 乘车人(list) 多个乘车人ex: # 乘车人(list) 多个乘车人ex:
# - "张三" # - "张三"
@ -67,11 +68,11 @@ auto_code_account:
# host: "smtp.qq.com" # host: "smtp.qq.com"
email_conf: email_conf:
is_email: True is_email: True
email: "@qq.com " email: ""
notice_email_list: "@qq.com" notice_email_list: ""
username: "" username: ""
password: "" password: ""
host: "smtp.qq.com" host: ""
# 是否开启cdn查询可以更快的检测票票 1为开启2为关闭 # 是否开启cdn查询可以更快的检测票票 1为开启2为关闭
is_cdn: 2 is_cdn: 2

View File

@ -65,10 +65,9 @@ class select:
ticket_black_list_time = ticket_info_config["ticket_black_list_time"] ticket_black_list_time = ticket_info_config["ticket_black_list_time"]
order_type = ticket_info_config["order_type"] order_type = ticket_info_config["order_type"]
print u"*" * 20 print u"*" * 20
print u"12306刷票小助手最后更新于2018.8.31请勿作为商业用途交流群号286271084" print u"12306刷票小助手最后更新于2018.9.21请勿作为商业用途交流群号286271084"
print u"如果有好的margin请联系作者表示非常感激\n" print u"当前配置:\n出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票优先提交:{4}\n乘车人:{5}\n" \
print u"当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n" \ u"刷新间隔:随机(1-3S)\n候选购买车次:{6}\n僵尸票关小黑屋时长:{7}\n 下单接口:{8}\n".format \
u"刷新间隔:随机(1-4S)\n候选购买车次:{6}\n僵尸票关小黑屋时长:{7}\n 下单接口:{8}\n".format \
( (
from_station, from_station,
to_station, to_station,
@ -197,17 +196,17 @@ class select:
leftTicket = queryResult.get("leftTicket", "") leftTicket = queryResult.get("leftTicket", "")
query_from_station_name = queryResult.get("query_from_station_name", "") query_from_station_name = queryResult.get("query_from_station_name", "")
query_to_station_name = queryResult.get("query_to_station_name", "") query_to_station_name = queryResult.get("query_to_station_name", "")
is_more_ticket_num = queryResult.get("is_more_ticket_num", len(self.ticke_peoples))
if wrapcache.get(train_no): if wrapcache.get(train_no):
print(ticket.QUEUE_WARNING_MSG.format(train_no)) print(ticket.QUEUE_WARNING_MSG.format(train_no))
else: else:
# 获取联系人 # 获取联系人
if not self.passengerTicketStrList and not self.oldPassengerStr: s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples, set_type=seat, is_more_ticket_num=is_more_ticket_num)
s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples, set_type=seat) getPassengerDTOsResult = s.getPassengerTicketStrListAndOldPassengerStr()
getPassengerDTOsResult = s.getPassengerTicketStrListAndOldPassengerStr() if getPassengerDTOsResult.get("status", False):
if getPassengerDTOsResult.get("status", False): self.passengerTicketStrList = getPassengerDTOsResult.get("passengerTicketStrList", "")
self.passengerTicketStrList = getPassengerDTOsResult.get("passengerTicketStrList", "") self.oldPassengerStr = getPassengerDTOsResult.get("oldPassengerStr", "")
self.oldPassengerStr = getPassengerDTOsResult.get("oldPassengerStr", "") self.set_type = getPassengerDTOsResult.get("set_type", "")
self.set_type = getPassengerDTOsResult.get("set_type", "")
# 提交订单 # 提交订单
if self.order_type == 1: # 快读下单 if self.order_type == 1: # 快读下单
a = autoSubmitOrderRequest(session=self, a = autoSubmitOrderRequest(session=self,
@ -228,10 +227,8 @@ class select:
self.passengerTicketStrList, self.oldPassengerStr, train_date, self.passengerTicketStrList, self.oldPassengerStr, train_date,
self.ticke_peoples) self.ticke_peoples)
sor.sendSubmitOrderRequest() sor.sendSubmitOrderRequest()
else: else:
random_time = round(random.uniform(1, 4), 2) random_time = round(random.uniform(1, 3), 2)
time.sleep(random_time) time.sleep(random_time)
print u"正在第{0}次查询 随机停留时长:{6} 乘车日期: {1} 车次:{2} 查询无票 cdn轮询IP{4}当前cdn总数{5} 总耗时:{3}ms".format(num, print u"正在第{0}次查询 随机停留时长:{6} 乘车日期: {1} 车次:{2} 查询无票 cdn轮询IP{4}当前cdn总数{5} 总耗时:{3}ms".format(num,
",".join( ",".join(

View File

@ -1,6 +1,7 @@
# coding=utf-8 # coding=utf-8
from config.TicketEnmu import ticket from config.TicketEnmu import ticket
from myException.PassengerUserException import PassengerUserException from myException.PassengerUserException import PassengerUserException
import wrapcache
class getPassengerDTOs: class getPassengerDTOs:
@ -8,7 +9,7 @@ class getPassengerDTOs:
获取乘客信息 获取乘客信息
:return: :return:
""" """
def __init__(self, session, ticket_peoples, set_type): def __init__(self, session, ticket_peoples, set_type, is_more_ticket_num):
""" """
:param session: 登录实例 :param session: 登录实例
:param ticket_peoples: 乘客 :param ticket_peoples: 乘客
@ -16,6 +17,7 @@ class getPassengerDTOs:
""" """
self.session = session self.session = session
self.ticket_peoples = ticket_peoples self.ticket_peoples = ticket_peoples
self.is_more_ticket_num = is_more_ticket_num
self.set_type = set_type.encode("utf8") self.set_type = set_type.encode("utf8")
def sendGetPassengerDTOs(self): def sendGetPassengerDTOs(self):
@ -57,15 +59,23 @@ class getPassengerDTOs:
获取提交车次人内容格式 获取提交车次人内容格式
passengerTicketStr O,0,1,文贤平,1,43052419950223XXXX,15618715583,N_O,0,1,梁敏,1,43052719920118XXXX,,N passengerTicketStr O,0,1,文贤平,1,43052419950223XXXX,15618715583,N_O,0,1,梁敏,1,43052719920118XXXX,,N
oldPassengerStr 文贤平,1,43052719920118XXXX,1_梁敏,1,43052719920118XXXX,1 oldPassengerStr 文贤平,1,43052719920118XXXX,1_梁敏,1,43052719920118XXXX,1
ps: 如果is_more_ticket打开了的话那就是读取联系人列表里面前符合车次数量的前几个联系人
:return: :return:
""" """
passengerTicketStrList = [] passengerTicketStrList = []
oldPassengerStr = [] oldPassengerStr = []
user_info = self.sendGetPassengerDTOs() if wrapcache.get("user_info"): # 如果缓存中有联系人方式,则读取缓存中的联系人
user_info = wrapcache.get("user_info")
print(u"缓存中找到联系人信息: {0}".format(user_info))
else:
user_info = self.sendGetPassengerDTOs()
wrapcache.set("user_info", user_info, timeout=9999999)
set_type = self.getPassengerTicketStr(self.set_type) set_type = self.getPassengerTicketStr(self.set_type)
if not user_info: if not user_info:
raise PassengerUserException(ticket.DTO_NOT_IN_LIST) raise PassengerUserException(ticket.DTO_NOT_IN_LIST)
if len(user_info) is 1: if len(user_info) < self.is_more_ticket_num: # 如果乘车人填错了导致没有这个乘车人的话,可能乘车人数会小于自动乘车人
self.is_more_ticket_num = len(user_info)
if self.is_more_ticket_num is 1:
passengerTicketStrList.append( passengerTicketStrList.append(
'0,' + user_info[0]['passenger_type'] + "," + user_info[0][ '0,' + user_info[0]['passenger_type'] + "," + user_info[0][
"passenger_name"] + "," + "passenger_name"] + "," +
@ -75,7 +85,7 @@ class getPassengerDTOs:
user_info[0]['passenger_name'] + "," + user_info[0]['passenger_id_type_code'] + "," + user_info[0]['passenger_name'] + "," + user_info[0]['passenger_id_type_code'] + "," +
user_info[0]['passenger_id_no'] + "," + user_info[0]['passenger_type'] + '_') user_info[0]['passenger_id_no'] + "," + user_info[0]['passenger_type'] + '_')
else: else:
for i in xrange(len(user_info)): for i in xrange(self.is_more_ticket_num):
passengerTicketStrList.append( passengerTicketStrList.append(
'0,' + user_info[i]['passenger_type'] + "," + user_info[i][ '0,' + user_info[i]['passenger_type'] + "," + user_info[i][
"passenger_name"] + "," + user_info[i]['passenger_id_type_code'] + "," + user_info[i][ "passenger_name"] + "," + user_info[i]['passenger_id_type_code'] + "," + user_info[i][

View File

@ -80,14 +80,11 @@ class getQueueCount:
ticket_split = sum(map(conversion_int, ticket.split(","))) if ticket.find(",") != -1 else ticket ticket_split = sum(map(conversion_int, ticket.split(","))) if ticket.find(",") != -1 else ticket
countT = getQueueCountResult["data"]["countT"] countT = getQueueCountResult["data"]["countT"]
if int(countT) is 0: if int(countT) is 0:
if int(ticket_split) < len(self.ticket_peoples): print(u"排队成功, 当前余票还剩余: {0}".format(ticket_split))
print(u"当前余票数小于乘车人数,放弃订票") csf = confirmSingleForQueue(self.session, self.ifShowPassCodeTime, self.is_need_code, self.token,
else: self.set_type, self.ticket_peoples, self.ticketInfoForPassengerForm,
print(u"排队成功, 当前余票还剩余: {0}".format(ticket_split)) self.oldPassengerStr, self.passengerTicketStrList)
csf = confirmSingleForQueue(self.session, self.ifShowPassCodeTime, self.is_need_code, self.token, csf.sendConfirmSingleForQueue()
self.set_type, self.ticket_peoples, self.ticketInfoForPassengerForm,
self.oldPassengerStr, self.passengerTicketStrList)
csf.sendConfirmSingleForQueue()
else: else:
print(u"当前排队人数: {1} 当前余票还剩余:{0} 张,继续排队中".format(ticket_split, countT)) print(u"当前排队人数: {1} 当前余票还剩余:{0} 张,继续排队中".format(ticket_split, countT))
else: else:

View File

@ -94,17 +94,14 @@ class getQueueCountAsync:
",") != -1 else ticket_data ",") != -1 else ticket_data
countT = getQueueCountAsyncResult["data"]["countT"] countT = getQueueCountAsyncResult["data"]["countT"]
if int(countT) is 0: if int(countT) is 0:
if int(ticket_split) < self.users: print(u"排队成功, 当前余票还剩余: {0}".format(ticket_split))
print(u"当前余票数小于乘车人数,放弃订票") c = confirmSingleForQueueAsys(session=self.session,
else: passengerTicketStr=self.passengerTicketStr,
print(u"排队成功, 当前余票还剩余: {0}".format(ticket_split)) oldPassengerStr=self.oldPassengerStr,
c = confirmSingleForQueueAsys(session=self.session, result=self.result,)
passengerTicketStr=self.passengerTicketStr, print(u"验证码提交安全期,等待{}MS".format(self.ifShowPassCodeTime))
oldPassengerStr=self.oldPassengerStr, time.sleep(self.ifShowPassCodeTime)
result=self.result,) c.sendConfirmSingleForQueueAsys()
print(u"验证码提交安全期,等待{}MS".format(self.ifShowPassCodeTime))
time.sleep(self.ifShowPassCodeTime)
c.sendConfirmSingleForQueueAsys()
else: else:
print(u"排队发现未知错误{0},将此列车 {1}加入小黑屋".format(getQueueCountAsyncResult, self.train_no)) print(u"排队发现未知错误{0},将此列车 {1}加入小黑屋".format(getQueueCountAsyncResult, self.train_no))
wrapcache.set(key=self.train_no, value=datetime.datetime.now(), wrapcache.set(key=self.train_no, value=datetime.datetime.now(),

View File

@ -68,7 +68,10 @@ class query:
stationTrainCode = ticket_info[3] stationTrainCode = ticket_info[3]
leftTicket = ticket_info[12] leftTicket = ticket_info[12]
seat = self._station_seat[j].encode("utf8") seat = self._station_seat[j].encode("utf8")
ticket_num = ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))] try:
ticket_num = int(ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))])
except ValueError:
ticket_num = ""
print (u'车次: {0} 始发车站: {1} 终点站: {2} {3}: {4}'.format(ticket_info[3], print (u'车次: {0} 始发车站: {1} 终点站: {2} {3}: {4}'.format(ticket_info[3],
self.from_station_h, self.from_station_h,
self.to_station_h, self.to_station_h,
@ -77,10 +80,16 @@ class query:
if wrapcache.get(train_no): if wrapcache.get(train_no):
print(ticket.QUERY_IN_BLACK_LIST.format(train_no)) print(ticket.QUERY_IN_BLACK_LIST.format(train_no))
continue continue
if ticket_num != "" and self.ticke_peoples_num < ticket_num:
# 小于乘车人数则无视此次乘车机会, 以后可以扩展为有票优先提交
continue
else: else:
if ticket_num != "" and self.ticke_peoples_num > ticket_num:
if self.session.is_more_ticket:
print(u"余票数小于乘车人数,当前余票数: {}, 删减人车人数到: {}".format(ticket_num, ticket_num))
is_more_ticket_num = ticket_num
else:
continue
else:
is_more_ticket_num = self.ticke_peoples_num
print (ticket.QUERY_C) print (ticket.QUERY_C)
return { return {
"secretStr": secretStr, "secretStr": secretStr,
@ -93,6 +102,7 @@ class query:
"leftTicket": leftTicket, "leftTicket": leftTicket,
"train_location": train_location, "train_location": train_location,
"code": ticket.SUCCESS_CODE, "code": ticket.SUCCESS_CODE,
"is_more_ticket_num": is_more_ticket_num,
"status": True, "status": True,
} }
else: else:

View File

@ -50,7 +50,6 @@ class submitOrderRequest:
预定的请求参数注意参数顺序 预定的请求参数注意参数顺序
注意这里为了防止secretStr被urllib.parse过度编码在这里进行一次解码 注意这里为了防止secretStr被urllib.parse过度编码在这里进行一次解码
否则调用HttpTester类的post方法将会将secretStr编码成为无效码,造成提交预定请求失败 否则调用HttpTester类的post方法将会将secretStr编码成为无效码,造成提交预定请求失败
:param self:
:param secretStr: 提交车次加密 :param secretStr: 提交车次加密
:return: :return:
""" """