diff --git a/README.md b/README.md index db58ead..0e43309 100755 --- a/README.md +++ b/README.md @@ -79,8 +79,9 @@ - 测试下单接口是否可用,有两个下单接口,随便用哪个都ok - 如果下载验证码过期或者下载失败的问题,应该是12306封ip的策略,多重试几次,12306现在封服务器(阿里云和腾讯云)ip比较严重,尽量不要放在服务器里面 - 感谢一下小伙伴对本项目提供的帮助 - - @ sun7127@126.com - - @才 + - @sun7127@126.com + - @ 才 + - @MonsterTan - 以及所有为此项目提供pr的同学 - [更新日志](Update.md) diff --git a/Update.md b/Update.md index 3cfceb1..9369a5a 100644 --- a/Update.md +++ b/Update.md @@ -134,3 +134,6 @@ - mac和linux服务器自动对点 - 增加预售踩点查询下单,经测试,误差在0.004s +- 2019.01.12更新 + - 增加对python3语法的支持 + - 删除校验时间很多机器不兼容的问题(win10会阻拦对时功能,导致大面积报错),如果是预售,为了不耽误宝贵的时间,请手动对时 diff --git a/agency/cdn_utils.py b/agency/cdn_utils.py index 77698eb..f3c8188 100755 --- a/agency/cdn_utils.py +++ b/agency/cdn_utils.py @@ -76,4 +76,4 @@ class CDNProxy: if __name__ == '__main__': cdn = CDNProxy() - cdn.open_cdn_file() + print(cdn.open_cdn_file()) diff --git a/config/AutoSynchroTime.py b/config/AutoSynchroTime.py index bd8d846..4b41946 100644 --- a/config/AutoSynchroTime.py +++ b/config/AutoSynchroTime.py @@ -15,21 +15,21 @@ def autoSynchroTime(): hosts = ['ntp1.aliyun.com', 'ntp2.aliyun.com', 'ntp3.aliyun.com', 'ntp4.aliyun.com', 'cn.pool.ntp.org'] - print(u"正在同步时间,请耐心等待30秒左右") + print(u"正在同步时间,请耐心等待30秒左右,如果下面有错误发送,可以忽略!!") print(u"系统当前时间{}".format(str(datetime.datetime.now())[:22])) system = platform.system() if system == "Windows": # windows 同步时间未测试过,参考地址:https://www.jianshu.com/p/92ec15da6cc3 for host in hosts: - os.system('w32tm /register') - os.system('net start w32time') - os.system('w32tm /config /manualpeerlist:"{}" /syncfromflags:manual /reliable:yes /update'.format(host)) - os.system('ping -n 3 127.0.0.1 >nul') - sin = os.system('w32tm /resync') + os.popen('w32tm /register') + os.popen('net start w32time') + os.popen('w32tm /config /manualpeerlist:"{}" /syncfromflags:manual /reliable:yes /update'.format(host)) + os.popen('ping -n 3 127.0.0.1 >nul') + sin = os.popen('w32tm /resync') if sin is 0: break else: # mac同步地址,如果ntpdate未安装,brew install ntpdate linux 安装 yum install -y ntpdate for host in hosts: - sin = os.system('ntpdate {}'.format(host)) + sin = os.popen('ntpdate {}'.format(host)) if sin is 0: break print(u"同步后时间:{}".format(str(datetime.datetime.now())[:22])) diff --git a/config/urlConf.py b/config/urlConf.py index 2963815..8365767 100755 --- a/config/urlConf.py +++ b/config/urlConf.py @@ -11,7 +11,7 @@ urls = { "Host": "kyfw.12306.cn", "Content-Type": 1, "re_try": 10, - "re_time": 0.1, + "re_time": 1, "s_time": 0.1, "is_logger": True, "is_json": True, @@ -23,7 +23,7 @@ urls = { "Host": "kyfw.12306.cn", "Content-Type": 1, "re_try": 10, - "re_time": 0.1, + "re_time": 1, "s_time": 0.1, "is_logger": True, "is_json": True, @@ -36,7 +36,7 @@ urls = { "Host": "kyfw.12306.cn", "Content-Type": 1, "re_try": 10, - "re_time": 0.1, + "re_time": 1, "s_time": 0.1, "is_logger": False, "is_json": False, @@ -49,7 +49,7 @@ urls = { "Host": "kyfw.12306.cn", "Content-Type": 1, "re_try": 10, - "re_time": 0.1, + "re_time": 1, "s_time": 0.1, "is_logger": False, "is_json": False, @@ -62,7 +62,7 @@ urls = { "Host": "kyfw.12306.cn", "Content-Type": 1, "re_try": 10, - "re_time": 0.1, + "re_time": 1, "s_time": 0.1, "is_logger": True, "is_json": True, @@ -73,7 +73,7 @@ urls = { "Referer": "https://kyfw.12306.cn/otn/index/init", "Host": "kyfw.12306.cn", "re_try": 1, - "re_time": 0.1, + "re_time": 1, "s_time": 0.1, "is_logger": False, "is_json": False, @@ -84,7 +84,7 @@ urls = { "Referer": "https://kyfw.12306.cn/otn/index/init", "Host": "kyfw.12306.cn", "re_try": 1, - "re_time": 0.1, + "re_time": 1, "s_time": 0.1, "is_logger": False, "is_test_cdn": True, @@ -96,7 +96,7 @@ urls = { "Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin", "Host": "kyfw.12306.cn", "re_try": 10, - "re_time": 0.1, + "re_time": 1, "s_time": 0.01, "is_logger": False, "is_json": False, @@ -107,7 +107,7 @@ urls = { "Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin", "Host": "kyfw.12306.cn", "re_try": 10, - "re_time": 0.1, + "re_time": 1, "s_time": 0.1, "is_logger": True, "is_json": True, @@ -119,7 +119,7 @@ urls = { "Host": "kyfw.12306.cn", "Content-Type": 1, "re_try": 10, - "re_time": 0.1, + "re_time": 1, "s_time": 0.1, "is_logger": True, "is_json": True, @@ -337,6 +337,18 @@ urls = { "is_logger": True, "is_json": True, }, + "loginAysnSuggest": { # 快速订单排队 + "req_url": "/otn/login/loginAysnSuggest", + "req_type": "post", + "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", + "Content-Type": 1, + "Host": "kyfw.12306.cn", + "re_try": 10, + "re_time": 0.01, + "s_time": 0.1, + "is_logger": True, + "is_json": True, + }, "cdn_host": { "req_url": "http://ping.chinaz.com/kyfw.12306.cn", "req_type": "post" diff --git a/damatuCode/ruokuai.py b/damatuCode/ruokuai.py index 5948790..09509e7 100755 --- a/damatuCode/ruokuai.py +++ b/damatuCode/ruokuai.py @@ -7,7 +7,10 @@ class RClient(object): def __init__(self, username, password): self.username = username - self.password = md5(password).hexdigest() + try: + self.password = md5(password).hexdigest() + except TypeError: + self.password = md5(password.encode('utf-8')).hexdigest() self.soft_id = '96061' self.soft_key = '6facb9da7bb645ad9c4a229464b2cf89' self.base_params = { diff --git a/init/select_ticket_info.py b/init/select_ticket_info.py index f9aa0a3..b8226e9 100755 --- a/init/select_ticket_info.py +++ b/init/select_ticket_info.py @@ -70,7 +70,10 @@ class select: to_station = ticket_info_config["set"]["to_station"] station_dates = ticket_info_config["set"]["station_dates"] set_names = ticket_info_config["set"]["set_type"] - set_type = [seat_conf[x.encode("utf-8")] for x in ticket_info_config["set"]["set_type"]] + try: + set_type = [seat_conf[x.encode("utf-8")] for x in ticket_info_config["set"]["set_type"]] + except KeyError: + set_type = [seat_conf[x] for x in ticket_info_config["set"]["set_type"]] is_more_ticket = ticket_info_config["set"]["is_more_ticket"] ticke_peoples = ticket_info_config["set"]["ticke_peoples"] station_trains = ticket_info_config["set"]["station_trains"] @@ -134,8 +137,12 @@ class select: for i in range(0, len(info)): n_info = info[i].split('|') station_name[n_info[1]] = n_info[2] - from_station = station_name[from_station.encode("utf8")] - to_station = station_name[to_station.encode("utf8")] + try: + from_station = station_name[from_station.encode("utf8")] + to_station = station_name[to_station.encode("utf8")] + except KeyError: + from_station = station_name[from_station] + to_station = station_name[to_station] return from_station, to_station def call_login(self, auth=False): @@ -182,130 +189,127 @@ class select: raise ticketConfigException(u"cdn列表为空,请先加载cdn") def main(self): - autoSynchroTime() # 同步时间 - self.cdn_certification() - l = liftTicketInit(self) - l.reqLiftTicketInit() - self.call_login() - check_user = checkUser(self) - t = threading.Thread(target=check_user.sendCheckUser) - t.setDaemon(True) - t.start() - from_station, to_station = self.station_table(self.from_station, self.to_station) - num = 0 - while 1: - try: - num += 1 - now = datetime.datetime.now() # 感谢群里大佬提供整点代码 - configCommon.checkSleepTime(self) # 晚上到点休眠 - if self.order_model is 1: - sleep_time_s = 0.5 - sleep_time_t = 0.6 - # 测试了一下有微妙级的误差,应该不影响,测试结果:2019-01-02 22:30:00.004555,预售还是会受到前一次刷新的时间影响,暂时没想到好的解决方案 - while not now.strftime("%H:%M:%S") == self.open_time: - now = datetime.datetime.now() - if now.strftime("%H:%M:%S") > self.open_time: - break - time.sleep(0.0001) - else: - sleep_time_s = 0.5 - sleep_time_t = 3 - q = query(session=self, - from_station=from_station, - to_station=to_station, - from_station_h=self.from_station, - to_station_h=self.to_station, - _station_seat=self._station_seat, - station_trains=self.station_trains, - station_dates=self.station_dates, - ticke_peoples_num=len(self.ticke_peoples), - ) - queryResult = q.sendQuery() - # 查询接口 - if queryResult.get("status", False): - train_no = queryResult.get("train_no", "") - train_date = queryResult.get("train_date", "") - stationTrainCode = queryResult.get("stationTrainCode", "") - secretStr = queryResult.get("secretStr", "") - seat = queryResult.get("seat", "") - 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)) + # autoSynchroTime() # 同步时间 + try: + self.cdn_certification() + l = liftTicketInit(self) + l.reqLiftTicketInit() + self.call_login() + check_user = checkUser(self) + t = threading.Thread(target=check_user.sendCheckUser) + t.setDaemon(True) + t.start() + from_station, to_station = self.station_table(self.from_station, self.to_station) + num = 0 + s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples) + s.sendGetPassengerDTOs() + while 1: + num += 1 + now = datetime.datetime.now() # 感谢群里大佬提供整点代码 + configCommon.checkSleepTime(self) # 晚上到点休眠 + if self.order_model is 1: + sleep_time_s = 0.5 + sleep_time_t = 0.6 + # 测试了一下有微妙级的误差,应该不影响,测试结果:2019-01-02 22:30:00.004555,预售还是会受到前一次刷新的时间影响,暂时没想到好的解决方案 + while not now.strftime("%H:%M:%S") == self.open_time: + now = datetime.datetime.now() + if now.strftime("%H:%M:%S") > self.open_time: + break + time.sleep(0.0001) else: - # 获取联系人 - s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples, - set_type=seat_conf_2[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, - secretStr=secretStr, - train_date=train_date, - passengerTicketStr=self.passengerTicketStrList, - oldPassengerStr=self.oldPassengerStr, - train_no=train_no, - stationTrainCode=stationTrainCode, - leftTicket=leftTicket, - set_type=self.set_type, - query_from_station_name=query_from_station_name, - query_to_station_name=query_to_station_name, - ) - a.sendAutoSubmitOrderRequest() - elif self.order_type == 2: # 普通下单 - sor = submitOrderRequest(self, secretStr, from_station, to_station, train_no, self.set_type, - self.passengerTicketStrList, self.oldPassengerStr, train_date, - self.ticke_peoples) - sor.sendSubmitOrderRequest() - else: - random_time = round(random.uniform(sleep_time_s, sleep_time_t), 2) - print(u"正在第{0}次查询 随机停留时长:{6} 乘车日期: {1} 车次:{2} 查询无票 cdn轮询IP:{4}当前cdn总数:{5} 总耗时:{3}ms".format(num, - ",".join( - self.station_dates), - ",".join( - self.station_trains), - ( - datetime.datetime.now() - now).microseconds / 1000, - queryResult.get( - "cdn", - None), - len( - self.cdn_list), - random_time)) - time.sleep(random_time) - except PassengerUserException as e: - print(e) - break - except ticketConfigException as e: - print(e) - break - except ticketIsExitsException as e: - print(e) - break - except ticketNumOutException as e: - print(e) - break - except UserPasswordException as e: - print(e) - break - except ValueError as e: - if e == "No JSON object could be decoded": - print(u"12306接口无响应,正在重试") - else: - print(e) - except KeyError as e: - print(e) - except TypeError as e: - print(u"12306接口无响应,正在重试 {0}".format(e)) - except socket.error as e: + sleep_time_s = 0.5 + sleep_time_t = 3 + q = query(session=self, + from_station=from_station, + to_station=to_station, + from_station_h=self.from_station, + to_station_h=self.to_station, + _station_seat=self._station_seat, + station_trains=self.station_trains, + station_dates=self.station_dates, + ticke_peoples_num=len(self.ticke_peoples), + ) + queryResult = q.sendQuery() + # 查询接口 + if queryResult.get("status", False): + train_no = queryResult.get("train_no", "") + train_date = queryResult.get("train_date", "") + stationTrainCode = queryResult.get("stationTrainCode", "") + secretStr = queryResult.get("secretStr", "") + seat = queryResult.get("seat", "") + 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: + # 获取联系人 + s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples, + set_type=seat_conf_2[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, + secretStr=secretStr, + train_date=train_date, + passengerTicketStr=self.passengerTicketStrList, + oldPassengerStr=self.oldPassengerStr, + train_no=train_no, + stationTrainCode=stationTrainCode, + leftTicket=leftTicket, + set_type=self.set_type, + query_from_station_name=query_from_station_name, + query_to_station_name=query_to_station_name, + ) + a.sendAutoSubmitOrderRequest() + elif self.order_type == 2: # 普通下单 + sor = submitOrderRequest(self, secretStr, from_station, to_station, train_no, self.set_type, + self.passengerTicketStrList, self.oldPassengerStr, train_date, + self.ticke_peoples) + sor.sendSubmitOrderRequest() + else: + random_time = round(random.uniform(sleep_time_s, sleep_time_t), 2) + print(u"正在第{0}次查询 随机停留时长:{6} 乘车日期: {1} 车次:{2} 查询无票 cdn轮询IP:{4}当前cdn总数:{5} 总耗时:{3}ms".format(num, + ",".join( + self.station_dates), + ",".join( + self.station_trains), + ( + datetime.datetime.now() - now).microseconds / 1000, + queryResult.get( + "cdn", + None), + len( + self.cdn_list), + random_time)) + time.sleep(random_time) + except PassengerUserException as e: + print(e) + except ticketConfigException as e: + print(e) + except ticketIsExitsException as e: + print(e) + except ticketNumOutException as e: + print(e) + except UserPasswordException as e: + print(e) + except ValueError as e: + if e == "No JSON object could be decoded": + print(u"12306接口无响应,正在重试") + else: print(e) + except KeyError as e: + print(e) + except TypeError as e: + print(u"12306接口无响应,正在重试 {0}".format(e)) + except socket.error as e: + print(e) if __name__ == '__main__': diff --git a/inter/AutoSubmitOrderRequest.py b/inter/AutoSubmitOrderRequest.py index 5cc576e..92bdacf 100644 --- a/inter/AutoSubmitOrderRequest.py +++ b/inter/AutoSubmitOrderRequest.py @@ -25,7 +25,10 @@ class autoSubmitOrderRequest: leftTicket, set_type,): self.set_type = set_type - self.secretStr = urllib.unquote(secretStr) + try: + self.secretStr = urllib.unquote(secretStr) + except AttributeError: + self.secretStr = urllib.parse.unquote(secretStr) self.train_date = train_date self.query_from_station_name = query_from_station_name self.query_to_station_name = query_to_station_name diff --git a/inter/GetPassengerDTOs.py b/inter/GetPassengerDTOs.py index ac7573e..82d4f95 100644 --- a/inter/GetPassengerDTOs.py +++ b/inter/GetPassengerDTOs.py @@ -1,4 +1,6 @@ # coding=utf-8 +import json + from config.TicketEnmu import ticket from myException.PassengerUserException import PassengerUserException import wrapcache @@ -14,19 +16,21 @@ class getPassengerDTOs: 获取乘客信息 :return: """ - def __init__(self, session, ticket_peoples, set_type, is_more_ticket_num): + def __init__(self, session, ticket_peoples=None, set_type=None, is_more_ticket_num=None): """ :param session: 登录实例 :param ticket_peoples: 乘客 :param set_type: 坐席 """ + if ticket_peoples is None: + ticket_peoples = [] self.session = session 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 def sendGetPassengerDTOs(self): - getPassengerDTOsResult = self.session.httpClint.send(self.session.urls["get_passengerDTOs"], {}) + getPassengerDTOsResult = self.session.httpClint.send(self.session.urls["get_passengerDTOs"], json.dumps({"_json_att": ""})) if getPassengerDTOsResult.get("data", False) and getPassengerDTOsResult["data"].get("normal_passengers", False): normal_passengers = getPassengerDTOsResult['data']['normal_passengers'] _normal_passenger = [normal_passengers[i] for i in range(len(normal_passengers)) if @@ -38,8 +42,10 @@ class getPassengerDTOs: elif getPassengerDTOsResult.get('messages', False): print(getPassengerDTOsResult.get('messages', False)) else: - print(getPassengerDTOsResult) - raise PassengerUserException(ticket.DTO_NOT_FOUND) + print(u"警告:您的账号可能买票有问题,获取不到联系人,请测试是否能正常下单,在捡漏或者购票!!!") + print(u"警告:您的账号可能买票有问题,获取不到联系人,请测试是否能正常下单,在捡漏或者购票!!!") + print(u"警告:您的账号可能买票有问题,获取不到联系人,请测试是否能正常下单,在捡漏或者购票!!!") + # raise PassengerUserException(ticket.DTO_NOT_FOUND) def getPassengerTicketStr(self, set_type): """ @@ -57,7 +63,6 @@ class getPassengerDTOs: '软座': 2, '软卧': 4, '硬卧': 3, - '动卧': 1, } return str(passengerTicketStr[set_type.replace(' ', '')]) diff --git a/inter/GetQueueCount.py b/inter/GetQueueCount.py index 95d7ada..86d5ed3 100644 --- a/inter/GetQueueCount.py +++ b/inter/GetQueueCount.py @@ -1,5 +1,6 @@ # coding=utf-8 import datetime +import sys import time from collections import OrderedDict import wrapcache @@ -46,7 +47,10 @@ class getQueueCount: :return: """ - new_train_date = filter(None, str(time.asctime(time.strptime(self.station_dates, "%Y-%m-%d"))).split(" ")) + if sys.version_info.major is 2: + new_train_date = filter(None, str(time.asctime(time.strptime(self.station_dates, "%Y-%m-%d"))).split(" ")) + else: + new_train_date = list(filter(None, str(time.asctime(time.strptime(self.station_dates, "%Y-%m-%d"))).split(" "))) data = OrderedDict() data['train_date'] = "{0} {1} 0{2} {3} 00:00:00 GMT+0800 (中国标准时间)".format( new_train_date[0], diff --git a/inter/GetQueueCountAsync.py b/inter/GetQueueCountAsync.py index ab02b24..e7753b2 100644 --- a/inter/GetQueueCountAsync.py +++ b/inter/GetQueueCountAsync.py @@ -1,5 +1,6 @@ # coding=utf-8 import datetime +import sys import time from collections import OrderedDict @@ -56,7 +57,10 @@ class getQueueCountAsync: - _json_att 没啥卵用,还是带上吧 :return: """ - new_train_date = filter(None, str(time.asctime(time.strptime(self.station_dates, "%Y-%m-%d"))).split(" ")) + if sys.version_info.major is 2: + new_train_date = filter(None, str(time.asctime(time.strptime(self.station_dates, "%Y-%m-%d"))).split(" ")) + else: + new_train_date = list(filter(None, str(time.asctime(time.strptime(self.station_dates, "%Y-%m-%d"))).split(" "))) data = OrderedDict() data['train_date'] = "{0} {1} {2} {3} 00:00:00 GMT+0800 (中国标准时间)".format( new_train_date[0], diff --git a/inter/Query.py b/inter/Query.py index ecfeace..436c567 100644 --- a/inter/Query.py +++ b/inter/Query.py @@ -103,7 +103,7 @@ class query: if result: for i in value['result']: ticket_info = i.split('|') - if ticket_info[11] == "Y" and ticket_info[1].encode("utf8") == "预订": # 筛选未在开始时间内的车次 + if ticket_info[11] == "Y" and ticket_info[1] == "预订": # 筛选未在开始时间内的车次 for j in self._station_seat: is_ticket_pass = ticket_info[j] if is_ticket_pass != '' and is_ticket_pass != '无' and is_ticket_pass != '*' and self.check_is_need_train( diff --git a/inter/SubmitOrderRequest.py b/inter/SubmitOrderRequest.py index e5b0623..cb422dc 100644 --- a/inter/SubmitOrderRequest.py +++ b/inter/SubmitOrderRequest.py @@ -19,7 +19,10 @@ class submitOrderRequest: def __init__(self, session, secretStr, from_station, to_station, train_no, set_type, passengerTicketStrList, oldPassengerStr, train_date, ticke_peoples): self.session = session - self.secretStr = secretStr + try: + self.secretStr = urllib.unquote(secretStr) + except AttributeError: + self.secretStr = urllib.parse.unquote(secretStr) self.from_station = from_station self.to_station = to_station self.to_station = to_station @@ -34,7 +37,7 @@ class submitOrderRequest: """ :return: """ - data = [('secretStr', urllib.unquote(self.secretStr)), # 字符串加密 + data = [('secretStr', self.secretStr), # 字符串加密 ('train_date', self.train_date), # 出发时间 ('back_train_date', time()), # 返程时间 ('tour_flag', 'dc'), # 旅途类型