diff --git a/Update.md b/Update.md index c59ec86..9b0e2e8 100644 --- a/Update.md +++ b/Update.md @@ -116,3 +116,10 @@ - 修改已知bug - 优化代码结构 - 新增第三方库wrapcache,需要重新安装requirements.txt + +- 2018.9.21更新,修复已知问题,增加余票不足优先提交功能 + - 修改已知bug + - 优化查询攻略 + - 优化随机查询1-3秒,经测试很稳定,不会封ip + - 增加余票不足优先提交功能(当余票小于乘车人,如果选择优先提交,则删减联系人和余票数一致在提交) + - 开关为ticket_config.yaml配置文件中is_more_ticket参数 diff --git a/config/ticket_config.yaml b/config/ticket_config.yaml index faa0f02..ac42908 100755 --- a/config/ticket_config.yaml +++ b/config/ticket_config.yaml @@ -5,28 +5,29 @@ set: # - 2018-01-06 # - 2018-01-07 station_dates: - - "2018-09-05" + - "2018-09-28" # 过滤车次(list),格式ex: # - "G1353" # - "G1329" station_trains: - - "D2304" + - "" + # 出发城市,比如深圳北,就填深圳就搜得到 - from_station: "深圳" + from_station: "" # 到达城市 比如深圳北,就填深圳就搜得到 - to_station: "上饶" + to_station: "" # 座位(list) 多个座位ex: # - "二等座" # - "一等座" set_type: - - "二等座" + - "" - # 余票不足是否自动提交,目前应该没什么卵用 - is_more_ticket: True + # 当余票小于乘车人,如果选择优先提交,则删减联系人和余票数一致在提交 + is_more_ticket: False # 乘车人(list) 多个乘车人ex: # - "张三" @@ -67,11 +68,11 @@ auto_code_account: # host: "smtp.qq.com" email_conf: is_email: True - email: "@qq.com " - notice_email_list: "@qq.com" + email: "" + notice_email_list: "" username: "" password: "" - host: "smtp.qq.com" + host: "" # 是否开启cdn查询,可以更快的检测票票 1为开启,2为关闭 is_cdn: 2 diff --git a/init/select_ticket_info.py b/init/select_ticket_info.py index 55d523c..7767818 100755 --- a/init/select_ticket_info.py +++ b/init/select_ticket_info.py @@ -65,10 +65,9 @@ class select: ticket_black_list_time = ticket_info_config["ticket_black_list_time"] order_type = ticket_info_config["order_type"] print u"*" * 20 - print u"12306刷票小助手,最后更新于2018.8.31,请勿作为商业用途,交流群号:286271084" - print u"如果有好的margin,请联系作者,表示非常感激\n" - print u"当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n" \ - u"刷新间隔:随机(1-4S)\n候选购买车次:{6}\n僵尸票关小黑屋时长:{7}\n 下单接口:{8}\n".format \ + print u"12306刷票小助手,最后更新于2018.9.21,请勿作为商业用途,交流群号:286271084" + print u"当前配置:\n出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票优先提交:{4}\n乘车人:{5}\n" \ + u"刷新间隔:随机(1-3S)\n候选购买车次:{6}\n僵尸票关小黑屋时长:{7}\n 下单接口:{8}\n".format \ ( from_station, to_station, @@ -197,17 +196,17 @@ class select: leftTicket = queryResult.get("leftTicket", "") query_from_station_name = queryResult.get("query_from_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): print(ticket.QUEUE_WARNING_MSG.format(train_no)) else: # 获取联系人 - if not self.passengerTicketStrList and not self.oldPassengerStr: - s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples, set_type=seat) - getPassengerDTOsResult = s.getPassengerTicketStrListAndOldPassengerStr() - if getPassengerDTOsResult.get("status", False): - self.passengerTicketStrList = getPassengerDTOsResult.get("passengerTicketStrList", "") - self.oldPassengerStr = getPassengerDTOsResult.get("oldPassengerStr", "") - self.set_type = getPassengerDTOsResult.get("set_type", "") + s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples, set_type=seat, is_more_ticket_num=is_more_ticket_num) + getPassengerDTOsResult = s.getPassengerTicketStrListAndOldPassengerStr() + if getPassengerDTOsResult.get("status", False): + self.passengerTicketStrList = getPassengerDTOsResult.get("passengerTicketStrList", "") + self.oldPassengerStr = getPassengerDTOsResult.get("oldPassengerStr", "") + self.set_type = getPassengerDTOsResult.get("set_type", "") # 提交订单 if self.order_type == 1: # 快读下单 a = autoSubmitOrderRequest(session=self, @@ -228,10 +227,8 @@ class select: self.passengerTicketStrList, self.oldPassengerStr, train_date, self.ticke_peoples) sor.sendSubmitOrderRequest() - - else: - random_time = round(random.uniform(1, 4), 2) + random_time = round(random.uniform(1, 3), 2) time.sleep(random_time) print u"正在第{0}次查询 随机停留时长:{6} 乘车日期: {1} 车次:{2} 查询无票 cdn轮询IP:{4}当前cdn总数:{5} 总耗时:{3}ms".format(num, ",".join( diff --git a/inter/GetPassengerDTOs.py b/inter/GetPassengerDTOs.py index f577cb9..df4c743 100644 --- a/inter/GetPassengerDTOs.py +++ b/inter/GetPassengerDTOs.py @@ -1,6 +1,7 @@ # coding=utf-8 from config.TicketEnmu import ticket from myException.PassengerUserException import PassengerUserException +import wrapcache class getPassengerDTOs: @@ -8,7 +9,7 @@ class getPassengerDTOs: 获取乘客信息 :return: """ - def __init__(self, session, ticket_peoples, set_type): + def __init__(self, session, ticket_peoples, set_type, is_more_ticket_num): """ :param session: 登录实例 :param ticket_peoples: 乘客 @@ -16,6 +17,7 @@ class getPassengerDTOs: """ self.session = session self.ticket_peoples = ticket_peoples + self.is_more_ticket_num = is_more_ticket_num self.set_type = set_type.encode("utf8") def sendGetPassengerDTOs(self): @@ -57,15 +59,23 @@ class getPassengerDTOs: 获取提交车次人内容格式 passengerTicketStr O,0,1,文贤平,1,43052419950223XXXX,15618715583,N_O,0,1,梁敏,1,43052719920118XXXX,,N oldPassengerStr 文贤平,1,43052719920118XXXX,1_梁敏,1,43052719920118XXXX,1 + ps: 如果is_more_ticket打开了的话,那就是读取联系人列表里面前符合车次数量的前几个联系人 :return: """ passengerTicketStrList = [] 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) if not user_info: 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( '0,' + user_info[0]['passenger_type'] + "," + user_info[0][ "passenger_name"] + "," + @@ -75,7 +85,7 @@ class getPassengerDTOs: user_info[0]['passenger_name'] + "," + user_info[0]['passenger_id_type_code'] + "," + user_info[0]['passenger_id_no'] + "," + user_info[0]['passenger_type'] + '_') else: - for i in xrange(len(user_info)): + for i in xrange(self.is_more_ticket_num): passengerTicketStrList.append( '0,' + user_info[i]['passenger_type'] + "," + user_info[i][ "passenger_name"] + "," + user_info[i]['passenger_id_type_code'] + "," + user_info[i][ diff --git a/inter/GetQueueCount.py b/inter/GetQueueCount.py index f2fc0a2..a34bf82 100644 --- a/inter/GetQueueCount.py +++ b/inter/GetQueueCount.py @@ -80,14 +80,11 @@ class getQueueCount: ticket_split = sum(map(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.ticket_peoples): - print(u"当前余票数小于乘车人数,放弃订票") - else: - print(u"排队成功, 当前余票还剩余: {0} 张".format(ticket_split)) - csf = confirmSingleForQueue(self.session, self.ifShowPassCodeTime, self.is_need_code, self.token, - self.set_type, self.ticket_peoples, self.ticketInfoForPassengerForm, - self.oldPassengerStr, self.passengerTicketStrList) - csf.sendConfirmSingleForQueue() + print(u"排队成功, 当前余票还剩余: {0} 张".format(ticket_split)) + csf = confirmSingleForQueue(self.session, self.ifShowPassCodeTime, self.is_need_code, self.token, + self.set_type, self.ticket_peoples, self.ticketInfoForPassengerForm, + self.oldPassengerStr, self.passengerTicketStrList) + csf.sendConfirmSingleForQueue() else: print(u"当前排队人数: {1} 当前余票还剩余:{0} 张,继续排队中".format(ticket_split, countT)) else: diff --git a/inter/GetQueueCountAsync.py b/inter/GetQueueCountAsync.py index b9ef235..ba21a91 100644 --- a/inter/GetQueueCountAsync.py +++ b/inter/GetQueueCountAsync.py @@ -94,17 +94,14 @@ class getQueueCountAsync: ",") != -1 else ticket_data countT = getQueueCountAsyncResult["data"]["countT"] if int(countT) is 0: - if int(ticket_split) < self.users: - print(u"当前余票数小于乘车人数,放弃订票") - else: - print(u"排队成功, 当前余票还剩余: {0} 张".format(ticket_split)) - c = confirmSingleForQueueAsys(session=self.session, - passengerTicketStr=self.passengerTicketStr, - oldPassengerStr=self.oldPassengerStr, - result=self.result,) - print(u"验证码提交安全期,等待{}MS".format(self.ifShowPassCodeTime)) - time.sleep(self.ifShowPassCodeTime) - c.sendConfirmSingleForQueueAsys() + print(u"排队成功, 当前余票还剩余: {0} 张".format(ticket_split)) + c = confirmSingleForQueueAsys(session=self.session, + passengerTicketStr=self.passengerTicketStr, + oldPassengerStr=self.oldPassengerStr, + result=self.result,) + print(u"验证码提交安全期,等待{}MS".format(self.ifShowPassCodeTime)) + time.sleep(self.ifShowPassCodeTime) + c.sendConfirmSingleForQueueAsys() else: print(u"排队发现未知错误{0},将此列车 {1}加入小黑屋".format(getQueueCountAsyncResult, self.train_no)) wrapcache.set(key=self.train_no, value=datetime.datetime.now(), diff --git a/inter/Query.py b/inter/Query.py index e742fc6..9c645f0 100644 --- a/inter/Query.py +++ b/inter/Query.py @@ -68,7 +68,10 @@ class query: stationTrainCode = ticket_info[3] leftTicket = ticket_info[12] 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], self.from_station_h, self.to_station_h, @@ -77,10 +80,16 @@ class query: if wrapcache.get(train_no): print(ticket.QUERY_IN_BLACK_LIST.format(train_no)) continue - if ticket_num != "有" and self.ticke_peoples_num < ticket_num: - # 小于乘车人数则无视此次乘车机会, 以后可以扩展为有票优先提交 - continue + 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) return { "secretStr": secretStr, @@ -93,6 +102,7 @@ class query: "leftTicket": leftTicket, "train_location": train_location, "code": ticket.SUCCESS_CODE, + "is_more_ticket_num": is_more_ticket_num, "status": True, } else: diff --git a/inter/SubmitOrderRequest.py b/inter/SubmitOrderRequest.py index decac11..b9fe601 100644 --- a/inter/SubmitOrderRequest.py +++ b/inter/SubmitOrderRequest.py @@ -50,7 +50,6 @@ class submitOrderRequest: 预定的请求参数,注意参数顺序 注意这里为了防止secretStr被urllib.parse过度编码,在这里进行一次解码 否则调用HttpTester类的post方法将会将secretStr编码成为无效码,造成提交预定请求失败 - :param self: :param secretStr: 提交车次加密 :return: """