Exemple #1
0
def send_push_bear(msg):
    """
    pushBear微信通知
    :param msg: 通知内容 content
    :return:
    """
    if TickerConfig.PUSHBEAR_CONF[
            "is_pushbear"] and TickerConfig.PUSHBEAR_CONF["send_key"].strip(
            ) != "":
        try:
            send_push_bear_urls = urls.get("Pushbear")
            data = {
                "sendkey": TickerConfig.PUSHBEAR_CONF["send_key"].strip(),
                "text": "购票成功通知",
                "desp": msg
            }
            http_client = HTTPClient(0)
            send_push_bea_rsp = http_client.send(send_push_bear_urls,
                                                 data=data)
            if send_push_bea_rsp.get("code") is 0:
                print(u"已下发 pushbear 微信通知, 请查收")
            else:
                print(send_push_bea_rsp)
        except Exception as e:
            print(u"pushbear 配置有误 {}".format(e))
    else:
        pass
Exemple #2
0
def sendPushBear(msg):
    """
    pushBear微信通知
    :param str: 通知内容 content
    :return:
    """
    conf = _get_yaml()
    if conf["pushbear_conf"][
            "is_pushbear"] and conf["pushbear_conf"]["send_key"].strip() != "":
        try:
            sendPushBearUrls = urls.get("Pushbear")
            data = {
                "sendkey": conf["pushbear_conf"]["send_key"].strip(),
                "text":
                "易行购票成功通知,{}".format(time.strftime("%Y-%m-%d %H:%M:%S")),
                "desp": msg
            }
            httpClint = HTTPClient(0)
            sendPushBeaRsp = httpClint.send(sendPushBearUrls, data=data)
            if sendPushBeaRsp.get("code") is 0:
                print(u"已下发 pushbear 微信通知, 请查收")
            else:
                print(sendPushBeaRsp)
        except Exception as e:
            print(u"pushbear 配置有误 {}".format(e))
    else:
        pass
Exemple #3
0
def getRandCode(is_auto_code, auto_code_type, result):
    """
    识别验证码
    :return: 坐标
    """
    try:
        if is_auto_code:
            if auto_code_type == 1:
                print(u"打码兔已关闭, 如需使用自动识别,请使用如果平台 auto_code_type == 2")
                return
            elif auto_code_type == 2:
                Result = verify(result)
                return codexy(Ofset=Result, is_raw_input=False)
            elif auto_code_type == 3:
                print("您已设置使用云打码,但是服务器资源有限,请尽快改为本地打码")
                http = HTTPClient(0)
                Result = http.send(urls.get("autoVerifyImage"),
                                   {"imageFile": result})
                if Result and Result.get("code") is 0:
                    return codexy(Ofset=Result.get("data"), is_raw_input=False)
        else:
            img = Image.open('./tkcode.png')
            img.show()
            return codexy()
    except Exception as e:
        print(e)
Exemple #4
0
 def __init__(
     self,
     session,
     from_station,
     to_station,
     from_station_h,
     to_station_h,
     _station_seat,
     station_trains,
     ticke_peoples_num,
     station_dates=None,
 ):
     self.session = session
     self.httpClint = HTTPClient()
     self.urls = urlConf.urls
     self.from_station = from_station
     self.to_station = to_station
     self.from_station_h = from_station_h
     self.to_station_h = to_station_h
     self.station_trains = station_trains
     self._station_seat = _station_seat if isinstance(
         _station_seat, list) else list(_station_seat)
     self.station_dates = station_dates if isinstance(
         station_dates, list) else list(station_dates)
     self.ticket_black_list = dict()
     self.ticke_peoples_num = ticke_peoples_num
     # by time
     self.is_by_time = session.is_by_time
     self.train_types = session.train_types
     self.departure_time = session.departure_time
     self.arrival_time = session.arrival_time
     self.take_time = session.take_time
Exemple #5
0
def sendPushBear(msg):
    """
    pushBear微信通知
    :param str: 通知内容 content
    :return:
    """
    conf = _get_yaml()
    user = _get_yaml()["set"]["12306account"][0]["user"]
    if conf["pushbear_conf"][
            "is_pushbear"] and conf["pushbear_conf"]["send_key"].strip() != "":
        try:
            sendPushBearUrls = urls.get("Pushbear")
            data = {
                "sendkey": conf["pushbear_conf"]["send_key"].strip(),
                "text": user + "购票成功通知",
                "desp": msg
            }
            httpClint = HTTPClient(0)
            sendPushBeaRsp = httpClint.send(sendPushBearUrls, data=data)
            if sendPushBeaRsp.get("code") is 0:
                print(u"已下发 pushbear 微信通知, 请查收")
            else:
                print(sendPushBeaRsp)
        except Exception as e:
            print(u"pushbear 配置有误 {}".format(e))
    else:
        pass
def sendPushBear(msg):
    """
	pushBear微信通知
	:param str:通知内容 content
	:return:
	"""
    # print()
    if configMap["pushbear_conf"]["is_pushbear"] and configMap[
            "pushbear_conf"]["send_key"].strip() != "":
        # if 1!=2:
        try:
            sendPushBearUrls = urlConf.urls["Pushbear"]
            print(sendPushBearUrls)
            data = {
                "send_key": configMap["pushbear_conf"]["send_key"].strip(),
                "text": "列车正晚点信息",
                "desp": msg
            }
            #以下方法测试老是报pushbear配置有误
            HTTPClient1 = HTTPClient(0)
            sendPushBearRSP = HTTPClient1.send(sendPushBearUrls, data=data)
            # print(sendPushBearRSP)
            # if sendPushBearRSP["errno"] is 0:
            if sendPushBearRSP.get("errno") is 0:
                print(u"已下发 pushbear 微信通知,请查收")
            else:
                print(sendPushBearRSP)
        except Exception as e:
            print(u"pushbear配置有误{}".format(e))
        else:
            pass
        finally:
            pass
    else:
        pass
Exemple #7
0
 def __init__(
     self,
     select_obj,
     from_station,
     to_station,
     from_station_h,
     to_station_h,
     _station_seat,
     station_trains,
     ticke_peoples_num,
     station_dates=None,
 ):
     self.session = select_obj
     self.httpClient = HTTPClient(TickerConfig.IS_PROXY)
     self.httpClient.set_cookies(self.session.cookies)
     self.urls = urlConf.urls
     self.from_station = from_station
     self.to_station = to_station
     self.from_station_h = from_station_h
     self.to_station_h = to_station_h
     self.station_trains = station_trains
     self._station_seat = _station_seat if isinstance(
         _station_seat, list) else list(_station_seat)
     self.station_dates = station_dates if isinstance(
         station_dates, list) else list(station_dates)
     self.ticket_black_list = dict()
     self.ticke_peoples_num = ticke_peoples_num
Exemple #8
0
 def cdn_req(self, cdn):
     for i in range(len(cdn)-1):
         http = HTTPClient()
         urls = self.confUrl["loginInit"]
         start_time = datetime.datetime.now()
         http.cdn = cdn[i].replace("\n", "")
         rep = http.send(urls)
         if rep and "message" not in rep and (datetime.datetime.now() - start_time).microseconds / 1000 < 300:
             self.cdn_list.append(cdn[i].replace("\n", ""))
     print(u"所有cdn解析完成...")
 def cdn_req(self, cdn):
     for i in range(len(cdn)-1):
         http = HTTPClient()
         urls = self.confUrl["loginInit"]
         start_time = datetime.datetime.now()
         http.cdn = cdn[i].replace("\n", "")
         rep = http.send(urls)
         if rep and "message" not in rep and (datetime.datetime.now() - start_time).microseconds / 1000 < 200:
             self.cdn_list.append(cdn[i].replace("\n", ""))
     print(u"所有cdn解析完成...")
Exemple #10
0
 def run(self):
     for cdn in self.cdns:
         http = HTTPClient(0)
         url = urls["loginInitCdn"]
         http._cdn = cdn.replace("\n", "")
         start_time = datetime.datetime.now()
         rep = http.send(url)
         if rep and "message" not in rep and (datetime.datetime.now(
         ) - start_time).microseconds / 1000 < 1000:
             if cdn.replace("\n", "") not in cdn_list:  # 如果有重复的cdn,则放弃加入
                 print(f"加入cdn: {cdn}")
                 cdn_list.append(cdn.replace("\n", ""))
Exemple #11
0
 def cdn_req(self, cdn):
     for i in range(len(cdn) - 1):
         http = HTTPClient(0)
         urls = self.urls["loginInitCdn"]
         http._cdn = cdn[i].replace("\n", "")
         start_time = datetime.datetime.now()
         rep = http.send(urls)
         if rep and "message" not in rep and (datetime.datetime.now() - start_time).microseconds / 1000 < 500:
             if cdn[i].replace("\n", "") not in self.cdn_list:  # 如果有重复的cdn,则放弃加入
                 # print(u"加入cdn {0}".format(cdn[i].replace("\n", "")))
                 self.cdn_list.append(cdn[i].replace("\n", ""))
     print(u"所有cdn解析完成...")
 def __init__(self):
     self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.expect_refresh_interval, self.ticket_black_list_time = self.get_ticket_info(
     )
     self.order_request_params = {}  # 订单提交时的参数
     self.ticketInfoForPassengerForm = {}  # 初始化当前页面参数
     self.current_seats = {}  # 席别信息
     self.token = ""
     self.set_type = ""
     self.user_info = ""
     self.secretStr = ""
     self.ticket_black_list = dict()
     self.is_check_user = dict()
     self.httpClint = HTTPClient()
     self.confUrl = urlConf.urls
Exemple #13
0
def sendServerChan(msg):

    try:
        sendPushBearUrls = urls.get("ServerChan")
        data = {"text": "自定义购票成功通知测试版本", "desp": msg}
        httpClint = HTTPClient(0)
        sendPushBeaRsp = httpClint.send(sendPushBearUrls, data=data)
        if sendPushBeaRsp.get("code") is 0:
            print(u"已下发 serverChan 微信通知, 请查收")
        else:
            print(sendPushBeaRsp)
    except Exception as e:
        print(u"serverChan 配置有误 {}".format(e))
    pass
Exemple #14
0
 def __init__(self, session, station_dates=None):
     self.httpClint = HTTPClient()
     self.urls = urlConf.urls
     self.qiangpiao = True
     self.session = session
     if station_dates is None:
         station_dates = (datetime.date.today() +
                          datetime.timedelta(2)).strftime('%Y-%m-%d')
     # print station_dates
     self.station_dates = station_dates if isinstance(
         station_dates, list) else [station_dates]
     self.ticket_black_list = dict()
     self.train_info_dict = self.get_train_info(train_info_path)
     self.station_info_dict, self.re_station_info_dict = self.get_station_info(
         station_info_path)
     self.start_station, self.end_station = self.get_station2station_file(
         '../data/station2station.info')
     self.station_time = self.get_station2station_spendtime_duration(
         '../data/station2station.spendtime.duration')
Exemple #15
0
 def __init__(self, session=None, is_auto_code=False, auto_code_type=1):
     if session is None:
         self.session = self
     else:
         self.session = session
     self.randCode = ""
     self.is_auto_code = is_auto_code
     self.auto_code_type = auto_code_type
     self.urls = urls
     self.httpClint = HTTPClient()
Exemple #16
0
 def __init__(self):
     self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.ticket_black_list_time = self.get_ticket_info()
     self.is_aotu_code = _get_yaml()["is_aotu_code"]
     self.aotu_code_type = _get_yaml()["aotu_code_type"]
     self.is_cdn = _get_yaml()["is_cdn"]
     self.order_request_params = {}  # 订单提交时的参数
     self.ticketInfoForPassengerForm = {}  # 初始化当前页面参数
     self.current_seats = {}  # 席别信息
     self.token = ""
     self.set_type = ""
     self.user_info = ""
     self.secretStr = ""
     self.ticket_black_list = dict()
     self.is_check_user = dict()
     self.httpClint = HTTPClient()
     self.confUrl = urlConf.urls
     self.login = GoLogin(self.httpClint, self.confUrl, self.is_aotu_code, self.aotu_code_type)
     self.is_download_img = False
     self.randCode = ""
     self.cdn_list = []
Exemple #17
0
 def __init__(self):
     self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, \
     self.ticke_peoples, self.station_trains, self.ticket_black_list_time, \
     self.order_type = self.get_ticket_info()
     self.is_auto_code = _get_yaml()["is_auto_code"]
     self.auto_code_type = _get_yaml()["auto_code_type"]
     self.is_cdn = _get_yaml()["is_cdn"]
     self.httpClint = HTTPClient()
     self.urls = urlConf.urls
     self.login = GoLogin(self, self.is_auto_code, self.auto_code_type)
     self.cdn_list = []
     self.passengerTicketStrList = ""
     self.oldPassengerStr = ""
 def __init__(self):
     self.get_ticket_info()
     self._station_seat = [seat_conf[x] for x in TickerConfig.SET_TYPE]
     self.auto_code_type = 2
     self.httpClint = HTTPClient(TickerConfig.IS_PROXY)
     self.urls = urlConf.urls
     self.login = GoLogin(self, TickerConfig.IS_AUTO_CODE, self.auto_code_type)
     self.cdn_list = []
     self.queryUrl = "leftTicket/queryT"
     self.passengerTicketStrList = ""
     self.passengerTicketStrByAfterLate = ""
     self.oldPassengerStr = ""
     self.set_type = ""
def send_server_chan(msg):
    """
    pushBear微信通知
    :param msg: 通知内容 content
    :return:
    """
    if (TickerConfig.SERVER_CHAN_CONF["is_server_chan"]
            and TickerConfig.SERVER_CHAN_CONF["secret"].strip() != ""):
        try:
            secret = TickerConfig.SERVER_CHAN_CONF["secret"].strip()
            send_server_chan_urls = urls.get("ServerChan")
            send_server_chan_urls["req_url"] += f'{secret}.send'

            params = {"text": "购票成功通知", "desp": msg}
            http_client = HTTPClient(0)
            send_server_chan_rsp = http_client.send(send_server_chan_urls,
                                                    params=params)
            if send_server_chan_rsp.get("errno") == 0:
                print(u"已下发 Server酱 微信通知, 请查收")
            else:
                print(send_server_chan_rsp)
        except Exception as e:
            print(u"Server酱 配置有误 {}".format(e))
Exemple #20
0
 def __init__(self):
     self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, \
     self.ticke_peoples, self.station_trains, self.ticket_black_list_time, \
     self.order_type, self.is_by_time, self.train_types, self.departure_time, \
     self.arrival_time, self.take_time, self.order_model, self.open_time, self.is_proxy = self.get_ticket_info()
     self.is_auto_code = _get_yaml()["is_auto_code"]
     self.auto_code_type = _get_yaml()["auto_code_type"]
     self.is_cdn = _get_yaml()["is_cdn"]
     self.httpClint = HTTPClient(self.is_proxy)
     self.urls = urlConf.urls
     self.login = GoLogin(self, self.is_auto_code, self.auto_code_type)
     self.cdn_list = []
     self.queryUrl = "leftTicket/queryZ"
     self.passengerTicketStrList = ""
     self.oldPassengerStr = ""
     self.set_type = ""
 def __init__(self):
     self.cdn_list = open_cdn_file("filter_cdn_list")
     self.get_ticket_info()
     self._station_seat = [seat_conf[x] for x in TickerConfig.SET_TYPE]
     self.auto_code_type = TickerConfig.AUTO_CODE_TYPE
     self.httpClint = HTTPClient(TickerConfig.IS_PROXY, self.cdn_list)
     self.httpClint.cdn = self.cdn_list[random.randint(0, 4)]
     self.urls = urlConf.urls
     self.login = GoLogin(self, TickerConfig.IS_AUTO_CODE, self.auto_code_type)
     self.cookies = ""
     self.queryUrl = "leftTicket/queryO"
     self.passengerTicketStrList = ""
     self.passengerTicketStrByAfterLate = ""
     self.oldPassengerStr = ""
     self.set_type = ""
     self.flag = True
Exemple #22
0
 def __init__(self, qiangpiao_info=None):
     if qiangpiao_info is None:
         self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, \
         self.ticke_peoples, self.station_trains, self.ticket_black_list_time, \
         self.order_type = self.get_ticket_info()
     else:
         pass
     self.is_auto_code = _get_yaml()["is_auto_code"]
     self.auto_code_type = _get_yaml()["auto_code_type"]
     self.is_cdn = _get_yaml()["is_cdn"]
     self.httpClint = HTTPClient()
     self.urls = urlConf.urls
     self.login = GoLogin(self, self.is_auto_code, self.auto_code_type)
     self.cdn_list = []
     self.passengerTicketStrList = ""
     self.oldPassengerStr = ""
     self.station_name_map = self.station_table(
         '../config/station_name.format')
Exemple #23
0
 def __init__(self, session, from_station, to_station, from_station_h, to_station_h, _station_seat, station_trains,
              ticke_peoples_num, station_dates=None, ):
     self.session = session
     self.httpClint = HTTPClient(session.is_proxy)
     self.urls = urlConf.urls
     self.from_station = from_station
     self.to_station = to_station
     self.from_station_h = from_station_h
     self.to_station_h = to_station_h
     self.station_trains = station_trains
     self._station_seat = _station_seat if isinstance(_station_seat, list) else list(_station_seat)
     self.station_dates = station_dates if isinstance(station_dates, list) else list(station_dates)
     self.ticket_black_list = dict()
     self.ticke_peoples_num = ticke_peoples_num
     # by time
     self.is_by_time = session.is_by_time
     self.train_types = session.train_types
     self.departure_time = session.departure_time
     self.arrival_time = session.arrival_time
     self.take_time = session.take_time
Exemple #24
0
 def __init__(self):
     self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.ticket_black_list_time = self.get_ticket_info()
     self.is_aotu_code = _get_yaml()["is_aotu_code"]
     self.aotu_code_type = _get_yaml()["aotu_code_type"]
     self.is_cdn = _get_yaml()["is_cdn"]
     self.order_request_params = {}  # 订单提交时的参数
     self.ticketInfoForPassengerForm = {}  # 初始化当前页面参数
     self.current_seats = {}  # 席别信息
     self.token = ""
     self.set_type = ""
     self.user_info = ""
     self.secretStr = ""
     self.ticket_black_list = dict()
     self.is_check_user = dict()
     self.httpClint = HTTPClient()
     self.confUrl = urlConf.urls
     self.login = GoLogin(self.httpClint, self.confUrl, self.is_aotu_code, self.aotu_code_type)
     self.is_download_img = False
     self.randCode = ""
     self.cdn_list = []
     self.buy_ticket_time = ""
Exemple #25
0
class Query:
    """
    查询接口
    """
    def __init__(
        self,
        select_obj,
        from_station,
        to_station,
        from_station_h,
        to_station_h,
        _station_seat,
        station_trains,
        ticke_peoples_num,
        station_dates=None,
    ):
        self.session = select_obj
        self.httpClient = HTTPClient(TickerConfig.IS_PROXY)
        self.httpClient.set_cookies(self.session.cookies)
        self.urls = urlConf.urls
        self.from_station = from_station
        self.to_station = to_station
        self.from_station_h = from_station_h
        self.to_station_h = to_station_h
        self.station_trains = station_trains
        self._station_seat = _station_seat if isinstance(
            _station_seat, list) else list(_station_seat)
        self.station_dates = station_dates if isinstance(
            station_dates, list) else list(station_dates)
        self.ticket_black_list = dict()
        self.ticke_peoples_num = ticke_peoples_num

    def station_seat(self, index):
        """
        获取车票对应坐席
        :return:
        """
        seat = {
            '商务座': 32,
            '一等座': 31,
            '二等座': 30,
            '特等座': 25,
            '软卧': 23,
            '硬卧': 28,
            '硬座': 29,
            '无座': 26,
            '动卧': 33,
        }
        return seat[index]

    def check_is_need_train(self, ticket_info):
        """
        判断车次是否为想要的车次,如果ticket_info为空,那么就不校验车次,直接返回True
        :param ticket_info:
        :return:
        """
        if self.station_dates and self.station_trains:
            return ticket_info[3] in self.station_trains
        else:
            return True

    def send_query(self):
        """
        查询
        :return:
        """
        if TickerConfig.IS_CDN == 1 and self.session.cdn_list:
            self.httpClient.cdn = self.session.cdn_list[random.randint(
                4,
                len(self.session.cdn_list) - 1)]
        for station_date in self.station_dates:
            select_url = copy.copy(self.urls["select_url"])
            select_url["req_url"] = select_url["req_url"].format(
                station_date, self.from_station, self.to_station,
                self.session.queryUrl)
            station_ticket = self.httpClient.send(select_url)
            value = station_ticket.get("data", "")
            if not value:
                print(
                    u'{0}-{1} 车次坐席查询为空,查询url: https://kyfw.12306.cn{2}, 可以手动查询是否有票'
                    .format(self.from_station_h, self.to_station_h,
                            select_url["req_url"]))
            else:
                result = value.get('result', [])
                if result:
                    for i in value['result']:
                        ticket_info = i.split('|')
                        if self.session.flag:
                            print(
                                f"车次:{ticket_info[3]} 出发站:{self.from_station_h} 到达站:{self.to_station_h} 历时:{ticket_info[10]}"
                                f" 商务/特等座:{ticket_info[32] or '--'}"
                                f" 一等座:{ticket_info[31] or '--'}"
                                f" 二等座:{ticket_info[30] or '--'}"
                                f" 动卧:{ticket_info[33] or '--'}"
                                f" 硬卧:{ticket_info[28] or '--'}"
                                f" 软座:{ticket_info[23] or '--'}"
                                f" 硬座:{ticket_info[29] or '--'}"
                                f" 无座:{ticket_info[26] or '--'}"
                                f" {ticket_info[1] or '--'}")
                        if ticket_info[1] == "预订" and self.check_is_need_train(
                                ticket_info):  # 筛选未在开始时间内的车次
                            for j in self._station_seat:
                                is_ticket_pass = ticket_info[j]
                                if ticket_info[11] == "Y":
                                    if is_ticket_pass != '' and is_ticket_pass != '无' and is_ticket_pass != '*':  # 过滤有效目标车次
                                        secret_str = ticket_info[0]
                                        train_no = ticket_info[2]
                                        query_from_station_name = ticket_info[
                                            6]
                                        query_to_station_name = ticket_info[7]
                                        train_location = ticket_info[15]
                                        station_train_code = ticket_info[3]
                                        left_ticket = ticket_info[12]
                                        start_time = ticket_info[8]
                                        arrival_time = ticket_info[9]
                                        distance_time = ticket_info[10]
                                        print(start_time, arrival_time,
                                              distance_time)
                                        seat = j
                                        try:
                                            ticket_num = int(ticket_info[j])
                                        except ValueError:
                                            ticket_num = "有"
                                        print(
                                            u'车次: {0} 始发车站: {1} 终点站: {2} {3}: {4}'
                                            .format(ticket_info[3],
                                                    self.from_station_h,
                                                    self.to_station_h,
                                                    seat_conf_2[j],
                                                    ticket_num))
                                        if seat_conf_2[
                                                j] == "无座" and ticket_info[3][
                                                    0] in ["G", "D", "C"]:
                                            seat = 30  # GD开头的无座直接强制改为二等座车次
                                        if wrapcache.get(train_no):
                                            print(
                                                Ticket.QUERY_IN_BLACK_LIST.
                                                format(train_no))
                                            continue
                                        else:
                                            if ticket_num != "有" and self.ticke_peoples_num > ticket_num:
                                                if TickerConfig.IS_MORE_TICKET:
                                                    print(
                                                        u"余票数小于乘车人数,当前余票数: {}, 删减人车人数到: {}"
                                                        .format(
                                                            ticket_num,
                                                            ticket_num))
                                                    is_more_ticket_num = ticket_num
                                                else:
                                                    print(
                                                        u"余票数小于乘车人数,当前设置不提交,放弃此次提交机会"
                                                    )
                                                    continue
                                            else:
                                                print(u"设置乘车人数为: {}".format(
                                                    self.ticke_peoples_num))
                                                is_more_ticket_num = self.ticke_peoples_num
                                            print(Ticket.QUERY_C)
                                            return {
                                                "secretStr": secret_str,
                                                "train_no": train_no,
                                                "stationTrainCode":
                                                station_train_code,
                                                "train_date": station_date,
                                                "query_from_station_name":
                                                query_from_station_name,
                                                "query_to_station_name":
                                                query_to_station_name,
                                                "seat": seat,
                                                "leftTicket": left_ticket,
                                                "train_location":
                                                train_location,
                                                "code": Ticket.SUCCESS_CODE,
                                                "is_more_ticket_num":
                                                is_more_ticket_num,
                                                "cdn": self.httpClient.cdn,
                                                "status": True,
                                            }
                                elif is_ticket_pass == '无' and ticket_info[
                                        37] == "1" and TickerConfig.TICKET_TYPE is 2:
                                    """
                                    is_ticket_pass如果有别的显示,但是可以候补,可以提issues提出来,附上query log,我将添加上
                                    判断车次是否可以候补
                                    目前的候补机制是只要一有候补位置,立马提交候补
                                    """
                                    # 如果最后一位为1,则是可以候补的,不知道这些正确嘛?
                                    nate = list(ticket_info[38])
                                    if wrapcache.get(f"hb{ticket_info[2]}"):
                                        continue
                                    for set_type in TickerConfig.SET_TYPE:
                                        if TickerConfig.PASSENGER_TICKER_STR[
                                                set_type] not in nate:
                                            if ticket_info[3][0] in [
                                                    "G", "D", "C"
                                            ] and set_type in [
                                                    "一等座", "特等座", "二等座", "商务座",
                                                    "无座"
                                            ]:
                                                return {
                                                    "secretList":
                                                    ticket_info[0],
                                                    "seat": [set_type],
                                                    "train_no": ticket_info[2],
                                                    "status": True,
                                                    "cdn": self.httpClient.cdn,
                                                }
                                            elif ticket_info[3][0] in [
                                                    "T", "Z", "K"
                                            ] and set_type in [
                                                    "硬卧", "硬座", "无座", "软座",
                                                    "软卧"
                                            ]:
                                                return {
                                                    "secretList":
                                                    ticket_info[0],
                                                    "seat": [set_type],
                                                    "train_no": ticket_info[2],
                                                    "status": True,
                                                    "cdn": self.httpClient.cdn,
                                                }
                else:
                    print(u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket))
        self.session.flag = False
        return {
            "code": Ticket.FAIL_CODE,
            "status": False,
            "cdn": self.httpClient.cdn,
        }
Exemple #26
0
class query:
    """
    查询接口
    """

    def __init__(self, session, from_station, to_station, from_station_h, to_station_h, _station_seat, station_trains,
                 ticke_peoples_num, station_dates=None, ):
        self.session = session
        self.httpClint = HTTPClient(session.is_proxy)
        self.urls = urlConf.urls
        self.from_station = from_station
        self.to_station = to_station
        self.from_station_h = from_station_h
        self.to_station_h = to_station_h
        self.station_trains = station_trains
        self._station_seat = _station_seat if isinstance(_station_seat, list) else list(_station_seat)
        self.station_dates = station_dates if isinstance(station_dates, list) else list(station_dates)
        self.ticket_black_list = dict()
        self.ticke_peoples_num = ticke_peoples_num
        # by time
        self.is_by_time = session.is_by_time
        self.train_types = session.train_types
        self.departure_time = session.departure_time
        self.arrival_time = session.arrival_time
        self.take_time = session.take_time

    @classmethod
    def station_seat(self, index):
        """
        获取车票对应坐席
        :return:
        """
        seat = {'商务座': 32,
                '一等座': 31,
                '二等座': 30,
                '特等座': 25,
                '软卧': 23,
                '硬卧': 28,
                '硬座': 29,
                '无座': 26,
                '动卧': 33,
                }
        return seat[index]

    def check_time_interval(self, ticket_info):
        return self.departure_time <= time_to_minutes(ticket_info[8]) and \
               time_to_minutes(ticket_info[9]) <= self.arrival_time and \
               time_to_minutes(ticket_info[10]) <= self.take_time

    def check_train_types(self, train):
        train_type = train[0]
        if train_type != "G" and train_type != "D": train_type = "O"
        if train_type in self.train_types:
            return True
        else:
            return False

    def check_is_need_train(self, ticket_info):
        if self.is_by_time:
            return self.check_train_types(ticket_info[3]) and self.check_time_interval(ticket_info)
        else:
            return ticket_info[3] in self.station_trains

    def sendQuery(self):
        """
        查询
        :return:
        """
        if self.session.is_cdn == 1:
            if self.session.cdn_list:
                self.httpClint.cdn = self.session.cdn_list[random.randint(0, len(self.session.cdn_list) - 1)]
        for station_date in self.station_dates:
            select_url = copy.copy(self.urls["select_url"])
            select_url["req_url"] = select_url["req_url"].format(station_date, self.from_station, self.to_station,
                                                                 self.session.queryUrl)
            station_ticket = self.httpClint.send(select_url)
            if station_ticket.get("c_url", ""):
                print(u"设置当前查询url为: {}".format(station_ticket.get("c_url", "")))
                self.session.queryUrl = station_ticket.get("c_url", "")  # 重设查询接口
                continue
            value = station_ticket.get("data", "")
            if not value:
                print (u'{0}-{1} 车次坐席查询为空,ip网络异常,查询url: https://kyfw.12306.cn{2}, 可以手动查询是否有票'.format(self.from_station_h,
                                                                                               self.to_station_h,
                                                                                               select_url["req_url"]))
            else:
                result = value.get('result', [])
                if result:
                    for i in value['result']:
                        ticket_info = i.split('|')
                        if ticket_info[11] == "Y" and ticket_info[1].encode("utf8") == "预订":  # 筛选未在开始时间内的车次
                            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(
                                        ticket_info):  # 过滤有效目标车次
                                    secretStr = ticket_info[0]
                                    train_no = ticket_info[2]
                                    query_from_station_name = ticket_info[6]
                                    query_to_station_name = ticket_info[7]
                                    train_location = ticket_info[15]
                                    stationTrainCode = ticket_info[3]
                                    leftTicket = ticket_info[12]
                                    start_time = ticket_info[8]
                                    arrival_time = ticket_info[9]
                                    distance_time = ticket_info[10]
                                    print(start_time, arrival_time, distance_time)
                                    seat = j
                                    try:
                                        ticket_num = int(ticket_info[j])
                                    except ValueError:
                                        ticket_num = "有"
                                    print (u'车次: {0} 始发车站: {1} 终点站: {2} {3}: {4}'.format(ticket_info[3],
                                                                                         self.from_station_h,
                                                                                         self.to_station_h,
                                                                                         seat_conf_2[j],
                                                                                         ticket_num))
                                    if wrapcache.get(train_no):
                                        print(ticket.QUERY_IN_BLACK_LIST.format(train_no))
                                        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:
                                                print(u"余票数小于乘车人数,当前设置不提交,放弃此次提交机会")
                                                continue
                                        else:
                                            print(u"设置乘车人数为: {}".format(self.ticke_peoples_num))
                                            is_more_ticket_num = self.ticke_peoples_num
                                        print (ticket.QUERY_C)
                                        return {
                                            "secretStr": secretStr,
                                            "train_no": train_no,
                                            "stationTrainCode": stationTrainCode,
                                            "train_date": station_date,
                                            "query_from_station_name": query_from_station_name,
                                            "query_to_station_name": query_to_station_name,
                                            "seat": seat,
                                            "leftTicket": leftTicket,
                                            "train_location": train_location,
                                            "code": ticket.SUCCESS_CODE,
                                            "is_more_ticket_num": is_more_ticket_num,
                                            "cdn": self.httpClint.cdn,
                                            "status": True,
                                        }
                else:
                    print(u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket))
        return {"code": ticket.FAIL_CODE, "status": False, "cdn": self.httpClint.cdn,}
Exemple #27
0
class select:
    def __init__(self):
        self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.ticket_black_list_time = self.get_ticket_info()
        self.is_aotu_code = _get_yaml()["is_aotu_code"]
        self.aotu_code_type = _get_yaml()["aotu_code_type"]
        self.order_request_params = {}  # 订单提交时的参数
        self.ticketInfoForPassengerForm = {}  # 初始化当前页面参数
        self.current_seats = {}  # 席别信息
        self.token = ""
        self.set_type = ""
        self.user_info = ""
        self.secretStr = ""
        self.ticket_black_list = dict()
        self.is_check_user = dict()
        self.httpClint = HTTPClient()
        self.confUrl = urlConf.urls
        self.login = GoLogin(self.httpClint, self.confUrl, self.is_aotu_code, self.aotu_code_type)

    def get_ticket_info(self):
        """
        获取配置信息
        :return:
        """
        ticket_info_config = _get_yaml()
        from_station = ticket_info_config["set"]["from_station"].encode("utf8")
        to_station = ticket_info_config["set"]["to_station"].encode("utf8")
        station_dates = ticket_info_config["set"]["station_dates"]
        set_type = ticket_info_config["set"]["set_type"]
        is_more_ticket = ticket_info_config["set"]["is_more_ticket"]
        ticke_peoples = ticket_info_config["set"]["ticke_peoples"]
        select_refresh_interval = ticket_info_config["select_refresh_interval"]
        station_trains = ticket_info_config["set"]["station_trains"]
        ticket_black_list_time = ticket_info_config["ticket_black_list_time"]
        print "*"*20
        print "当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n刷新间隔:{6}\n候选购买车次:{7}\n僵尸票关小黑屋时长:{8}\n".format\
                                                                                      (
                                                                                      from_station,
                                                                                      to_station,
                                                                                      station_dates,
                                                                                      ",".join(set_type),
                                                                                      is_more_ticket,
                                                                                      ",".join(ticke_peoples),
                                                                                      select_refresh_interval,
                                                                                      ",".join(station_trains),
                                                                                      ticket_black_list_time,
            )
        print "*"*20
        return from_station, to_station, station_dates, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, ticket_black_list_time

    def get_order_request_params(self):
        return self.order_request_params

    def get_ticketInfoForPassengerForm(self):
        return self.ticketInfoForPassengerForm

    def get_current_seats(self):
        return self.current_seats

    def get_token(self):
        return self.token

    def get_set_type(self):
        return self.set_type

    def conversion_int(self, str):
        return int(str)

    def station_seat(self, index):
        """
        获取车票对应坐席
        :param seat_type:
        :return:
        """
        seat = {'商务座': 32,
                '一等座': 31,
                '二等座': 30,
                '特等座': 25,
                '软卧': 23,
                '硬卧': 28,
                '硬座': 29,
                '无座': 26,
                }
        return seat[index]

    def station_table(self, from_station, to_station):
        """
        读取车站信息
        :param station:
        :return:
        """
        result = open('station_name.txt')
        info = result.read().split('=')[1].strip("'").split('@')
        del info[0]
        station_name = {}
        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")]
        return from_station, to_station

    def time(self):
        """
        获取日期
        :return:
        """
        today = datetime.date.today()
        tomorrow = today+datetime.timedelta(1)
        return tomorrow.strftime('%Y-%m-%d')

    def getRepeatSubmitToken(self):
        """
        获取提交车票请求token
        :return: token
        """
        initdc_url = self.confUrl["initdc_url"]["req_url"]
        initdc_result = self.httpClint.send(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=(\{.+\})?')
        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 getPassengerDTOs(self):
        """
        获取乘客信息
        :return: 
        """
        get_passengerDTOs = self.confUrl["get_passengerDTOs"]["req_url"]
        get_data = {
            '_json_att': None,
            'REPEAT_SUBMIT_TOKEN': self.token
        }
        jsonData = self.httpClint.send(get_passengerDTOs, get_data)
        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]
            return _normal_passenger if _normal_passenger else [normal_passengers[0]]  # 如果配置乘车人没有在账号,则默认返回第一个用户
        else:
            if 'data' in jsonData and 'exMsg' in jsonData['data'] and jsonData['data']['exMsg']:
                print(jsonData['data']['exMsg'])
            elif 'messages' in jsonData and jsonData['messages']:
                print(jsonData['messages'][0])
            else:
                print("未查找到常用联系人")
                raise PassengerUserException("未查找到常用联系人,请先添加联系人在试试")

    def submitOrderRequestFunc(self, from_station, to_station, station_date=None):
        select_url = self.confUrl["select_url"]["req_url"].format(
            station_date, from_station, to_station)
        station_ticket = self.httpClint.send(select_url, is_logger=False)
        return json.loads(station_ticket)

    def submitOrderRequestImplement(self, from_station, to_station,):
        """
        提交车次信息
        车次对应字典
        {32: '商务座 ',
            31: '一等座 ',
            30: '二等座 ',
            25: '特等座 ',
            23: '软卧 ',
            28: '硬卧 ',
            29: '硬座 ',
            26: '无座 '
        } 参照station_seat()方法
        :return:
        """
        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:
                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].encode("utf8") == "预订":  # 筛选未在开始时间内的车次
                            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 ('正在尝试提交订票...')
                                        # self.submitOrderRequestFunc(from_station, to_station, self.time())
                                        self.submit_station()
                                        self.getPassengerTicketStr(self._station_seat[j].encode("utf8"))
                                        self.getRepeatSubmitToken()
                                        if not self.user_info:  # 修改每次都调用用户接口导致用户接口不能用
                                            self.user_info = self.getPassengerDTOs()
                                        if self.checkOrderInfo(train_no, self._station_seat[j].encode("utf8")):
                                                break
                                else:
                                    pass
                        else:
                            pass
                else:
                    print "车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)

    def check_user(self):
        """
        检查用户是否达到订票条件
        :return:
        """
        check_user_url = self.confUrl["check_user_url"]["req_url"]
        data = {"_json_att": ""}
        check_user = self.httpClint.send(check_user_url, data)

        check_user_flag = check_user['data']['flag']
        if check_user_flag is True:
            self.is_check_user["user_time"] = datetime.datetime.now()
        else:
            if check_user['messages']:
                print ('用户检查失败:%s,可能未登录,可能session已经失效' % check_user['messages'][0])
                print ('正在尝试重新登录')
                self.call_login()
                self.is_check_user["user_time"] = datetime.datetime.now()
            else:
                print ('用户检查失败: %s,可能未登录,可能session已经失效' % check_user)
                print ('正在尝试重新登录')
                self.call_login()
                self.is_check_user["user_time"] = datetime.datetime.now()


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

        submit_station_url = self.confUrl["submit_station_url"]["req_url"]
        data = [('secretStr', urllib.unquote(self.secretStr)),  # 字符串加密
                ('train_date', self.time()),  # 出发时间
                ('back_train_date', self.time()),  # 返程时间
                ('tour_flag', 'dc'),  # 旅途类型
                ('purpose_codes', 'ADULT'),  # 成人票还是学生票
                ('query_from_station_name', self.from_station),  # 起始车站
                ('query_to_station_name', self.to_station),  # 终点车站
                ]
        submitResult = self.httpClint.send(submit_station_url, data)
        if 'data' in submitResult and submitResult['data']:
            if submitResult['data'] == 'N':
                print ('出票成功')
            else:
                print ('出票失败')
        elif 'messages' in submitResult and submitResult['messages']:
            raise ticketIsExitsException(submitResult['messages'][0])

    def getPassengerTicketStr(self, set_type):
        """
        获取getPassengerTicketStr 提交对应的代号码
        :param str: 坐席
        :return: 
        """
        passengerTicketStr = {
            '一等座': 'M',
            '特等座': 'P',
            '二等座': 'O',
            '商务座': 9,
            '硬座': 1,
            '无座': 1,
            '软卧': 4,
            '硬卧': 3,
        }
        self.set_type = str(passengerTicketStr[set_type.replace(' ', '')])

    def ticket_type(self):
        """订单票的类型,目前只考虑成人票,此方法暂时搁置,做备案"""
        ticket_type = {'adult': "1", 'child': "2", 'student': "3", 'disability': "4"}
        return ticket_type

    def getPassengerTicketStrListAndOldPassengerStr(self):
        """
        获取提交车次人内容格式
        passengerTicketStr	O,0,1,文贤平,1,43052419950223XXXX,15618715583,N_O,0,1,梁敏,1,43052719920118XXXX,,N
        oldPassengerStr	文贤平,1,43052719920118XXXX,1_梁敏,1,43052719920118XXXX,1_
        :return:
        """
        passengerTicketStrList = []
        oldPassengerStr = []
        if not self.user_info:
            raise PassengerUserException("联系人不在列表中,请查证后添加")
        if len(self.user_info) is 1:
            passengerTicketStrList.append(
                '0,' + self.user_info[0]['passenger_type'] + "," + 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]['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'] + '_')
        else:
            for i in range(len(self.user_info)):
                passengerTicketStrList.append(
                    '0,' + self.user_info[i]['passenger_type'] + "," + self.user_info[i][
                        "passenger_name"] + "," + self.user_info[i]['passenger_id_type_code'] + "," + self.user_info[i][
                        'passenger_id_no'] + "," + self.user_info[i]['mobile_no'] + ',N_' + self.set_type)
                oldPassengerStr.append(
                    self.user_info[i]['passenger_name'] + "," + self.user_info[i]['passenger_id_type_code'] + "," +
                    self.user_info[i]['passenger_id_no'] + "," + self.user_info[i]['passenger_type'] + '_')
        return passengerTicketStrList, oldPassengerStr

    def checkOrderInfo(self, train_no, set_type):
        """
        检查支付订单,需要提交REPEAT_SUBMIT_TOKEN
        passengerTicketStr : 座位编号,0,票类型,乘客名,证件类型,证件号,手机号码,保存常用联系人(Y或N)
        oldPassengersStr: 乘客名,证件类型,证件号,乘客类型
        :return: 
        """
        passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr()
        checkOrderInfoUrl = self.confUrl["checkOrderInfoUrl"]["req_url"]
        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 = self.httpClint.send(checkOrderInfoUrl, data)
        if 'data' in checkOrderInfo:
            if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo["data"]["ifShowPassCode"] == "Y":
                is_need_code = True
                if self.getQueueCount(train_no, set_type, is_need_code):
                    return True
            if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo['data']['submitStatus'] is True:
                    print ('车票提交通过,正在尝试排队')
                    is_need_code = False
                    if self.getQueueCount(train_no, set_type, is_need_code):
                        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])

    def getQueueCount(self, train_no, set_type, is_need_code):
        """
        # 模拟查询当前的列车排队人数的方法
        # 返回信息组成的提示字符串
        :param token:
        :return:
        """
        l_time = time.localtime(time.time())
        new_train_date = time.strftime("%a %b %d %Y", l_time)
        getQueueCountUrl = self.confUrl["getQueueCountUrl"]["req_url"]
        data = {
            'train_date': str(new_train_date) + " 00:00:00 GMT+0800 (中国标准时间)",
            'train_no': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_no'],
            'stationTrainCode':	self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['station_train_code'],
            'seatType':	self.set_type,
            'fromStationTelecode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['from_station'],
            'toStationTelecode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['to_station'],
            'leftTicket': self.get_ticketInfoForPassengerForm()['leftTicketStr'],
            'purpose_codes': self.get_ticketInfoForPassengerForm()['purpose_codes'],
            'train_location': self.get_ticketInfoForPassengerForm()['train_location'],
            'REPEAT_SUBMIT_TOKEN': self.get_token(),
        }
        getQueueCountResult = self.httpClint.send(getQueueCountUrl, data)
        if "status" in getQueueCountResult and getQueueCountResult["status"] is True:
            if "countT" in getQueueCountResult["data"]:
                ticket = getQueueCountResult["data"]["ticket"]
                ticket_split = sum(map(self.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.user_info):
                        print("当前余票数小于乘车人数,放弃订票")
                    else:
                        print("排队成功, 当前余票还剩余: {0} 张".format(ticket_split))
                        if self.checkQueueOrder(is_need_code):
                            return True
                else:
                    print("当前排队人数:" + str(countT) + "当前余票还剩余:{0} 张,继续排队中".format(ticket_split))
            else:
                print("排队发现未知错误{0},将此列车 {1}加入小黑屋".format(getQueueCountResult, train_no))
                self.ticket_black_list[train_no] = datetime.datetime.now()
        elif "messages" in getQueueCountResult and getQueueCountResult["messages"]:
            print("排队异常,错误信息:{0}, 将此列车 {1}加入小黑屋".format(getQueueCountResult["messages"][0], train_no))
            self.ticket_black_list[train_no] = datetime.datetime.now()
        else:
            if "validateMessages" in getQueueCountResult and getQueueCountResult["validateMessages"]:
                print(str(getQueueCountResult["validateMessages"]))
                self.ticket_black_list[train_no] = datetime.datetime.now()
            else:
                print("未知错误 {0}".format("".join(getQueueCountResult)))

    def checkQueueOrder(self, is_node_code=False):
        """
        模拟提交订单是确认按钮,参数获取方法还是get_ticketInfoForPassengerForm 中获取
        :return: 
        """

        passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr()
        checkQueueOrderUrl = self.confUrl["checkQueueOrderUrl"]["req_url"]
        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("正在使用自动识别验证码功能")
                    checkRandCodeAnsyn = self.confUrl["checkRandCodeAnsyn"]["req_url"]
                    codeImgByOrder = self.confUrl["codeImgByOrder"]["req_url"]
                    randCode = self.login.readImg(codeImgByOrder)
                    randData = {
                        "randCode": randCode,
                        "rand": "randp",
                        "_json_att": None,
                        "REPEAT_SUBMIT_TOKEN": self.get_token()
                    }
                    fresult = self.httpClint.send(checkRandCodeAnsyn, randData)  # 校验验证码是否正确
                    checkcode = fresult['data']['msg']
                    if checkcode == 'TRUE':
                        print("验证码通过,正在提交订单")
                        data['randCode'] = randCode
                        break
                    else:
                        print ("验证码有误, 接口返回{0} 第{1}次尝试重试".format(fresult, i))
                else:
                    print("不需要验证码")
                    break
            checkQueueOrderResult = self.httpClint.send(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 queryOrderWaitTime(self):
        """
        排队获取订单等待信息,每隔3秒请求一次,最高请求次数为20次!
        :return: 
        """
        num = 1
        while True:
            _random = int(round(time.time() * 1000))
            num += 1
            if num > 30:
                print("超出排队时间,自动放弃,正在重新刷票")
                order_id = self.queryMyOrderNoComplete()  # 排队失败,自动取消排队订单
                if order_id:
                    self.cancelNoCompleteMyOrder(order_id)
                break
            try:
                data = {"random": _random, "tourFlag": "dc"}
                queryOrderWaitTimeUrl = self.confUrl["queryOrderWaitTimeUrl"]["req_url"]
                queryOrderWaitTimeResult = self.httpClint.send(queryOrderWaitTimeUrl, data)
            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+1))
            else:
                print("排队中")
            time.sleep(2)

        else:
            print(ticketNumOutException("订单提交失败!,正在重新刷票"))

    def queryMyOrderNoComplete(self):
        """
        获取订单列表信息
        :return:
        """
        self.initNoComplete()
        queryMyOrderNoCompleteUrl = self.confUrl["queryMyOrderNoCompleteUrl"]["req_url"]
        data = {"_json_att": ""}
        try:
            queryMyOrderNoCompleteResult = self.httpClint.send(queryMyOrderNoCompleteUrl, data)
        except ValueError:
            queryMyOrderNoCompleteResult = {}
        if queryMyOrderNoCompleteResult:
            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"]:
                    print(queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]["message"])
                    raise ticketNumOutException(queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]["message"])
            else:
                if "message" in queryMyOrderNoCompleteResult and queryMyOrderNoCompleteResult["message"]:
                    print queryMyOrderNoCompleteResult["message"]
                    return False
                else:
                    return False
        else:
            print("接口 {} 无响应".format(queryMyOrderNoCompleteUrl))

    def initNoComplete(self):
        """
        获取订单前需要进入订单列表页,获取订单列表页session
        :return:
        """
        self.httpClint.set_cookies(acw_tc="AQAAAEnFJnekLwwAtGHjZZCr79B6dpXk", current_captcha_type="Z")
        initNoCompleteUrl = self.confUrl["initNoCompleteUrl"]["req_url"]
        data = {"_json_att": ""}
        self.httpClint.send(initNoCompleteUrl, data)

    def cancelNoCompleteMyOrder(self, sequence_no):
        """
        取消订单
        :param sequence_no: 订单编号
        :return:
        """
        cancelNoCompleteMyOrderUrl = self.confUrl["cancelNoCompleteMyOrder"]["req_url"]
        cancelNoCompleteMyOrderData = {
            "sequence_no": sequence_no,
            "cancel_flag": "cancel_order",
            "_json_att": ""
        }
        cancelNoCompleteMyOrderResult = self.httpClint.send(cancelNoCompleteMyOrderUrl, cancelNoCompleteMyOrderData)
        if "data" in cancelNoCompleteMyOrderResult and "existError" in cancelNoCompleteMyOrderResult["data"] and cancelNoCompleteMyOrderResult["data"]["existError"] == "N":
            print("排队超时,已为您自动取消订单,订单编号: {0}".format(sequence_no))
            time.sleep(2)
            return True
        else:
            print("排队超时,取消订单失败, 订单号{0}".format(sequence_no))

    # def call_submit_ticket(self, function_name=None):
    #     """
    #     订票失败回调方法,默认执行submitOrderRequest()
    #     此方法暂不使用
    #     :param function_name:
    #     :return:
    #     """
    #     if function_name:
    #         self.function_name()
    #     else:
    #         self.submitOrderRequest()

    def call_login(self, auth=False):
        """
        登录回调方法
        :return:
        """
        if auth:
            return self.login.auth()
        else:
            self.login.go_login()

    def main(self):
        self.call_login()
        from_station, to_station = self.station_table(self.from_station, self.to_station)
        self.check_user()
        time.sleep(0.1)
        num = 1
        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:
                    # 5分钟检查一次用户是否登录
                    self.check_user()
                time.sleep(self.select_refresh_interval)
                if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00":
                    print "12306休息时间,本程序自动停止,明天早上6点将自动运行"
                    time.sleep(60 * 60 * 7)
                    self.call_login()
                start_time = datetime.datetime.now()
                self.submitOrderRequestImplement(from_station, to_station)
                print "正在第{0}次查询  乘车日期: {1}  车次{2} 查询无票  代理设置 无  总耗时{3}ms".format(num, ",".join(self.station_dates), ",".join(self.station_trains), (datetime.datetime.now()-start_time).microseconds/1000)
            except PassengerUserException as e:
                print e.message
                break
            except ticketConfigException as e:
                print e.message
                break
            except ticketIsExitsException as e:
                print e.message
                break
            except ticketNumOutException as e:
                print e.message
                break
            except UserPasswordException as e:
                print e.message
                break
            except ValueError as e:
                if e.message == "No JSON object could be decoded":
                    print("12306接口无响应,正在重试")
                else:
                    print(e.message)
            except KeyError as e:
                print(e.message)
            except TypeError as e:
                print("12306接口无响应,正在重试 {0}".format(e.message))
            except socket.error as e:
                print(e.message)
Exemple #28
0
class query:
    """
    查询接口
    """
    def __init__(
        self,
        session,
        from_station,
        to_station,
        from_station_h,
        to_station_h,
        _station_seat,
        station_trains,
        ticke_peoples_num,
        station_dates=None,
    ):
        self.session = session
        self.httpClint = HTTPClient(TickerConfig.IS_PROXY)
        self.urls = urlConf.urls
        self.from_station = from_station
        self.to_station = to_station
        self.from_station_h = from_station_h
        self.to_station_h = to_station_h
        self.station_trains = station_trains
        self._station_seat = _station_seat if isinstance(
            _station_seat, list) else list(_station_seat)
        self.station_dates = station_dates if isinstance(
            station_dates, list) else list(station_dates)
        self.ticket_black_list = dict()
        self.ticke_peoples_num = ticke_peoples_num

    def station_seat(self, index):
        """
        获取车票对应坐席
        :return:
        """
        seat = {
            '商务座': 32,
            '一等座': 31,
            '二等座': 30,
            '特等座': 25,
            '软卧': 23,
            '硬卧': 28,
            '硬座': 29,
            '无座': 26,
            '动卧': 33,
        }
        return seat[index]

    def check_is_need_train(self, ticket_info):
        return ticket_info[3] in self.station_trains

    def sendQuery(self):
        """
        查询
        :return:
        """
        if TickerConfig.IS_CDN == 1:
            if self.session.cdn_list:
                self.httpClint.cdn = self.session.cdn_list[random.randint(
                    0,
                    len(self.session.cdn_list) - 1)]
        for station_date in self.station_dates:
            select_url = copy.copy(self.urls["select_url"])
            select_url["req_url"] = select_url["req_url"].format(
                station_date, self.from_station, self.to_station,
                self.session.queryUrl)
            station_ticket = self.httpClint.send(select_url)
            if station_ticket.get("c_url", ""):
                print(u"设置当前查询url为: {}".format(station_ticket.get("c_url",
                                                                  "")))
                self.session.queryUrl = station_ticket.get("c_url",
                                                           "")  # 重设查询接口
                continue
            value = station_ticket.get("data", "")
            if not value:
                print(
                    u'{0}-{1} 车次坐席查询为空,查询url: https://kyfw.12306.cn{2}, 可以手动查询是否有票'
                    .format(self.from_station_h, self.to_station_h,
                            select_url["req_url"]))
            else:
                result = value.get('result', [])
                if result:
                    for i in value['result']:
                        ticket_info = i.split('|')
                        # if TickerConfig.TICKET_TYPE is 2 and self.check_is_need_train(ticket_info):
                        #     # 如果最后一位为1,则是可以候补的,不知道这些正确嘛?
                        #     if ticket_info[-2] == "1":
                        #         nate = list(ticket_info[-1])
                        #         for set_type in TickerConfig.SET_TYPE:
                        #             if TickerConfig.PASSENGER_TICKER_STR(set_type) not in nate:
                        #                 continue
                        #         print("当前订单可以候补,尝试提交候补订单")
                        #         return {
                        #             "secretStr":  ticket_info[0],
                        #             "seat": TickerConfig.SET_TYPE,
                        #             "status": True,
                        #         }
                        # elif TickerConfig.TICKET_TYPE is 1:
                        if ticket_info[1] == "预订" and self.check_is_need_train(
                                ticket_info):  # 筛选未在开始时间内的车次
                            for j in self._station_seat:
                                is_ticket_pass = ticket_info[j]
                                if ticket_info[11] == "Y":
                                    if is_ticket_pass != '' and is_ticket_pass != '无' and is_ticket_pass != '*':  # 过滤有效目标车次
                                        secretStr = ticket_info[0]
                                        train_no = ticket_info[2]
                                        query_from_station_name = ticket_info[
                                            6]
                                        query_to_station_name = ticket_info[7]
                                        train_location = ticket_info[15]
                                        stationTrainCode = ticket_info[3]
                                        leftTicket = ticket_info[12]
                                        start_time = ticket_info[8]
                                        arrival_time = ticket_info[9]
                                        distance_time = ticket_info[10]
                                        print(start_time, arrival_time,
                                              distance_time)
                                        seat = j
                                        try:
                                            ticket_num = int(ticket_info[j])
                                        except ValueError:
                                            ticket_num = "有"
                                        print(
                                            u'车次: {0} 始发车站: {1} 终点站: {2} {3}: {4}'
                                            .format(ticket_info[3],
                                                    self.from_station_h,
                                                    self.to_station_h,
                                                    seat_conf_2[j],
                                                    ticket_num))
                                        if wrapcache.get(train_no):
                                            print(
                                                ticket.QUERY_IN_BLACK_LIST.
                                                format(train_no))
                                            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:
                                                    print(
                                                        u"余票数小于乘车人数,当前设置不提交,放弃此次提交机会"
                                                    )
                                                    continue
                                            else:
                                                print(u"设置乘车人数为: {}".format(
                                                    self.ticke_peoples_num))
                                                is_more_ticket_num = self.ticke_peoples_num
                                            print(ticket.QUERY_C)
                                            return {
                                                "secretStr": secretStr,
                                                "train_no": train_no,
                                                "stationTrainCode":
                                                stationTrainCode,
                                                "train_date": station_date,
                                                "query_from_station_name":
                                                query_from_station_name,
                                                "query_to_station_name":
                                                query_to_station_name,
                                                "seat": seat,
                                                "leftTicket": leftTicket,
                                                "train_location":
                                                train_location,
                                                "code": ticket.SUCCESS_CODE,
                                                "is_more_ticket_num":
                                                is_more_ticket_num,
                                                "cdn": self.httpClint.cdn,
                                                "status": True,
                                            }
                                elif is_ticket_pass == '无' and ticket_info[
                                        -2] == "1" and TickerConfig.TICKET_TYPE is 2:
                                    """
                                    is_ticket_pass如果有别的显示,但是可以候补,可以提issues提出来,附上query log,我将添加上
                                    判断车次是否可以候补
                                    目前的候补机制是只要一有候补位置,立马提交候补
                                    """
                                    # 如果最后一位为1,则是可以候补的,不知道这些正确嘛?
                                    nate = list(ticket_info[-1])
                                    for set_type in TickerConfig.SET_TYPE:
                                        if TickerConfig.PASSENGER_TICKER_STR[
                                                set_type] not in nate:
                                            print(
                                                f"当前订单可以候补,候补位置为: {set_type}, 尝试提交候补订单"
                                            )
                                            return {
                                                "secretList": ticket_info[0],
                                                "seat": [set_type],
                                                "status": True,
                                            }
                else:
                    print(u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket))
        return {
            "code": ticket.FAIL_CODE,
            "status": False,
            "cdn": self.httpClint.cdn,
        }
Exemple #29
0
class query:
    """
    查询接口
    """
    def __init__(
        self,
        session,
        from_station,
        to_station,
        from_station_h,
        to_station_h,
        _station_seat,
        station_trains,
        ticke_peoples_num,
        station_dates=None,
    ):
        self.session = session
        self.httpClint = HTTPClient()
        self.urls = urlConf.urls
        self.from_station = from_station
        self.to_station = to_station
        self.from_station_h = from_station_h
        self.to_station_h = to_station_h
        self.station_trains = station_trains
        self._station_seat = _station_seat if isinstance(
            _station_seat, list) else list(_station_seat)
        self.station_dates = station_dates if isinstance(
            station_dates, list) else list(station_dates)
        self.ticket_black_list = dict()
        self.ticke_peoples_num = ticke_peoples_num

    def station_seat(self, index):
        """
        获取车票对应坐席
        :return:
        """
        seat = {
            '商务座': 32,
            '一等座': 31,
            '二等座': 30,
            '特等座': 25,
            '软卧': 23,
            '硬卧': 28,
            '硬座': 29,
            '无座': 26,
        }
        return seat[index]

    def sendQuery(self):
        """
        查询
        :return:
        """
        for station_date in self.station_dates:
            select_url = copy.copy(self.urls["select_url"])
            select_url["req_url"] = select_url["req_url"].format(
                station_date, self.from_station, self.to_station)
            station_ticket = self.httpClint.send(select_url)
            value = station_ticket.get("data", "")
            if not value:
                print(u'{0}-{1} 车次坐席查询为空'.format(self.from_station_h,
                                                 self.to_station_h))
            else:
                result = value.get('result', [])
                if result:
                    for i in value['result']:
                        ticket_info = i.split('|')
                        if ticket_info[11] == "Y" and ticket_info[1].encode(
                                "utf8") == "预订":  # 筛选未在开始时间内的车次
                            for j in xrange(len(self._station_seat)):
                                is_ticket_pass = ticket_info[self.station_seat(
                                    self._station_seat[j].encode("utf8"))]
                                if is_ticket_pass != '' and is_ticket_pass != '无' and ticket_info[
                                        3] in self.station_trains and is_ticket_pass != '*':  # 过滤有效目标车次
                                    secretStr = ticket_info[0]
                                    train_no = ticket_info[2]
                                    query_from_station_name = ticket_info[6]
                                    query_to_station_name = ticket_info[7]
                                    train_location = ticket_info[15]
                                    stationTrainCode = ticket_info[3]
                                    leftTicket = ticket_info[12]
                                    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,
                                            self._station_seat[j].encode(
                                                "utf8"), ticket_num))
                                    if wrapcache.get(train_no):
                                        print(
                                            ticket.QUERY_IN_BLACK_LIST.format(
                                                train_no))
                                        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:
                                                print(
                                                    u"余票数小于乘车人数,当前设置不提交,放弃此次提交机会"
                                                )
                                                continue
                                        else:
                                            print(u"设置乘车人数为: {}".format(
                                                self.ticke_peoples_num))
                                            is_more_ticket_num = self.ticke_peoples_num
                                        print(ticket.QUERY_C)
                                        return {
                                            "secretStr": secretStr,
                                            "train_no": train_no,
                                            "stationTrainCode":
                                            stationTrainCode,
                                            "train_date": station_date,
                                            "query_from_station_name":
                                            query_from_station_name,
                                            "query_to_station_name":
                                            query_to_station_name,
                                            "seat": seat,
                                            "leftTicket": leftTicket,
                                            "train_location": train_location,
                                            "code": ticket.SUCCESS_CODE,
                                            "is_more_ticket_num":
                                            is_more_ticket_num,
                                            "status": True,
                                        }
                else:
                    print(u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket))
        return {"code": ticket.FAIL_CODE, "status": False}
Exemple #30
0
class QueryTecket:
    """
    查询接口
    """
    def __init__(self, session, station_dates=None):
        self.httpClint = HTTPClient()
        self.urls = urlConf.urls
        self.qiangpiao = True
        self.session = session
        if station_dates is None:
            station_dates = (datetime.date.today() +
                             datetime.timedelta(2)).strftime('%Y-%m-%d')
        # print station_dates
        self.station_dates = station_dates if isinstance(
            station_dates, list) else [station_dates]
        self.ticket_black_list = dict()
        self.train_info_dict = self.get_train_info(train_info_path)
        self.station_info_dict, self.re_station_info_dict = self.get_station_info(
            station_info_path)
        self.start_station, self.end_station = self.get_station2station_file(
            '../data/station2station.info')
        self.station_time = self.get_station2station_spendtime_duration(
            '../data/station2station.spendtime.duration')

    def get_station2station_spendtime_duration(self, filename):
        station_time = {}
        with open(filename) as fp:
            for line in fp:
                fields = line.strip().decode('utf8').split('\t')
                if len(fields) != 2:
                    continue
                station_time[fields[0]] = json.loads(fields[1])
        return station_time

    def get_station2station_file(self, filename):
        start_station = {}
        end_station = {}
        with open(filename) as fp:
            for line in fp:
                fields = line.strip().decode('utf8').split('\t')
                if len(fields) != 3:
                    continue
                start_name = fields[0]
                end_name = fields[1]
                if start_name not in start_station:
                    start_station[start_name] = set()
                if end_name not in end_station:
                    end_station[end_name] = set()
                start_station[start_name].add(end_name)
                end_station[end_name].add(start_name)
        return start_station, end_station

    def get_train_info(self, filename):
        """读取火车车次信息,包括经过站,时间等
        """
        train_info_dict = {}
        with open(filename) as fp:
            for line in fp:
                line_arr = line.decode('utf8').strip().split('\t')
                if len(line_arr) != 7:
                    continue
                train_name = line_arr[2].strip()
                train_info = json.loads(line_arr[-1])
                train_info_dict[train_name] = train_info
        return train_info_dict

    def get_station_info(self, filename):
        """读取火车站次信息,包括站次名,站次简称
        """
        station_info_dict = {}
        re_station_info_dict = {}
        with open(filename) as fp:
            for line in fp:
                line_arr = line.decode('utf8').strip().split('\t')
                if len(line_arr) != 5:
                    continue
                station_name = line_arr[1].strip()
                staion_info = line_arr[2]
                station_info_dict[station_name] = staion_info
                re_station_info_dict[staion_info] = station_name
        return station_info_dict, re_station_info_dict

    def get_train_station(self, train_num):
        """获取车次沿路经过车站
        """
        train_info = self.train_info_dict[train_num]
        train_station = [info['station_name'] for info in train_info]
        return train_station

    def get_ticket_status(self, train_num, station_1, station_2):
        """获取车次指定站点间状态
        """
        pass

    def get_trains_station_index(self,
                                 station,
                                 trains_station,
                                 station_alias=[]):
        """获取车次经过的某个站点的索引,主要考虑到会出先,北京,北京南,这种情况
        """
        suffex = [u'南', u'东', u'西', u'北']
        if station in trains_station:
            return trains_station.index(station)

        for station in station_alias:
            if station in trains_station:
                return trains_station.index(station)

        if not (any(i == station[-1] for i in suffex) and len(station) > 2):
            for i in suffex:
                if station + i in trains_station:
                    return trains_station.index(station + i)
        else:
            if station[:-1] in trains_station:
                return trains_station.index(station[:-1])
            for i in suffex:
                if station[:-1] + i in trains_station:
                    return trains_station.index(station[:-1] + i)
        return -1

    def get_trains_status(self,
                          station_1,
                          station_2,
                          train_no_list=[],
                          span=False):
        """指定车次状态查询,支持越站查询
        """
        ret_list = []
        station_tuple = []
        station_tuple.append([station_1, station_2])
        span_list = []
        span_list.append([0, 0, 100])
        if len(train_no_list) > 0:
            start_alias, end_alias = self.get_online_alias(
                station_1, station_2)
        for i, train_no in enumerate(train_no_list):
            station_list = self.get_train_station(train_no)
            try:
                if span:
                    index_1 = self.get_trains_station_index(
                        station_1, station_list, start_alias)
                    index_2 = self.get_trains_station_index(
                        station_2, station_list, end_alias)
                    span_num = index_2 - index_1
                    for i in range(max(0, index_1 - 3), index_1 + 1):
                        for j in range(index_1 + 1, index_2 + 4):
                            if i == index_1 and j == index_2:
                                continue
                            station_tuple.append(
                                [station_list[i], station_list[j]])
                            span_list.append(
                                [index_1 - i, index_2 - j, span_num])
            except Exception as ex:
                logging.error('station_1: %s, station_2: %s' %
                              (station_1, station_2))
                logging.error(traceback.format_exc())

        for i, station in enumerate(station_tuple):
            time.sleep(0.5)
            ticke_status_list = self.sendQuery(station[0], station[1],
                                               train_no_list)

            for j, ticke_status in enumerate(ticke_status_list):
                if span_list[i][0] > 0:
                    ticke_status_list[j][
                        1] = '【' + ticke_status[1] + '】<--多买' + str(
                            span_list[i][0]) + '站--' + station_1
                if span_list[i][1] > span_list[i][2] / 2:
                    ticke_status_list[j][2] = station_1 + '买' + str(
                        span_list[i][2] - span_list[i][1]
                    ) + '站-->【' + ticke_status[2] + '】-->' + station_2
                elif span_list[i][1] > 0:
                    ticke_status_list[j][
                        2] = '【' + ticke_status[2] + '】<--少买' + str(
                            span_list[i][1]) + '站--' + station_2
                elif span_list[i][1] != 0:
                    ticke_status_list[j][2] = station_2 + '--多买' + str(
                        abs(span_list[i][1])) + '站-->【' + ticke_status[2] + '】'

                if '【' not in ticke_status_list[j][1]:
                    ticke_status_list[j][1] = '【' + ticke_status[1] + '】'
                if '【' not in ticke_status_list[j][2]:
                    ticke_status_list[j][2] = '【' + ticke_status[2] + '】'

            ret_list.append(ticke_status_list)
            # print json.dumps(ticke_json, ensure_ascii=False)
        return ret_list

    def get_station2station_status(self,
                                   station_1,
                                   station_2,
                                   start_time='',
                                   end_time=''):
        """直接查询站点间车次信息
        """
        pass

    def station_seat(self, index):
        """
        获取车票对应坐席
        :return:
        """
        seat = {
            '商务座': 32,
            '一等座': 31,
            '二等座': 30,
            '特等座': 25,
            '软卧': 23,
            '硬卧': 28,
            '硬座': 29,
            '无座': 26,
        }
        return seat[index]

    def sendQuery(
        self,
        from_station,
        to_station,
        train_no_list=None,
    ):
        """
        查询
        :return:
        """
        from_station_en = self.station_info_dict[from_station]
        to_station_en = self.station_info_dict[to_station]
        ret_list = []
        for station_date in self.station_dates:
            print station_date
            select_url = copy.copy(self.urls["select_url"])
            select_url["req_url"] = select_url["req_url"].format(
                station_date, from_station_en, to_station_en)
            station_ticket = self.httpClint.send(select_url)
            value = station_ticket.get("data", "")
            if not value:
                logging.info(u'{0}-{1} 车次坐席查询为空'.format(
                    from_station, to_station))
            else:
                result = value.get('result', [])
                if result == []:
                    return ret_list
                for i in result:
                    ticket_info = i.split('|')
                    if (ticket_info[11] != u"Y" or ticket_info[1] != u"预订"
                        ) and u'无' not in i:  # 筛选未在开始时间内的车次
                        logging.info(
                            u"车次配置信息: %s --> %s 时间: %s 有误,或者返回数据异常,请检查: %s " %
                            (from_station, to_station, station_date,
                             json.dumps(ticket_info, ensure_ascii=False)))
                        continue
                    if (ticket_info[11] != u"Y" or ticket_info[1] != u"预订"
                        ) and u'无' in i and not self.qiangpiao:
                        continue
                    # for j in xrange(len(self._station_seat)):
                    tmp_list = []
                    secretStr = ticket_info[0]
                    train_no = ticket_info[3]
                    if train_no_list is not None and len(
                            train_no_list
                    ) > 0 and train_no not in train_no_list:
                        continue
                    train_from_station = ticket_info[6]
                    train_to_station = ticket_info[7]
                    start_time = ticket_info[8]
                    end_time = ticket_info[9]
                    duration_time = ticket_info[10]
                    date_time = ticket_info[13]
                    seat_not = ticket_info[26]
                    seat_ying = ticket_info[29]
                    yingwo = ticket_info[28]
                    ruanwo = ticket_info[23]
                    gaoji_ruanwo = ticket_info[21]
                    seat_2 = ticket_info[30]
                    seat_1 = ticket_info[31]
                    seat_0 = ticket_info[32]
                    dongwo = ticket_info[33]

                    tmp_list.append(ticket_info[3])
                    tmp_list.append(
                        self.re_station_info_dict[ticket_info[6].strip()])
                    tmp_list.append(
                        self.re_station_info_dict[ticket_info[7].strip()])
                    tmp_list.append(ticket_info[8])
                    tmp_list.append(ticket_info[9])
                    tmp_list.append(ticket_info[10])
                    # tmp_list.append(ticket_info[13])
                    # tmp_list.append(station_date)
                    tmp_list.append(ticket_info[26])
                    tmp_list.append(ticket_info[29])
                    tmp_list.append(ticket_info[28])
                    tmp_list.append(ticket_info[23])
                    tmp_list.append(ticket_info[21])
                    tmp_list.append(ticket_info[30])
                    tmp_list.append(ticket_info[31])
                    tmp_list.append(ticket_info[32])
                    tmp_list.append(ticket_info[33])
                    if ticket_info[11] != u"Y" or ticket_info[1] != u"预订":
                        tmp_list.append(u'抢票')
                    else:
                        tmp_list.append(u'预定')
                    ret_list.append(tmp_list)

        for ticket_info in ret_list:
            # ticket_info = i.split('|')
            for i, info in enumerate(ticket_info):
                if info == '':
                    info = u'--'
                    ticket_info[i] = info
        return ret_list

    def get_alias_station(self, s1_name):
        """徐州|徐州东|徐州南|徐州西|徐州北 都是徐州
        """
        if not isinstance(s1_name, unicode):
            s1_name = s1_name.deocde('utf8')
        s1_name_list = [s1_name]
        d = [u'东', u'南', u'西', u'北']
        if s1_name[-1] not in d or len(s1_name) < 3:
            for i in d:
                s1_name_list.append(s1_name + i)
        elif len(s1_name) > 2:
            s1_name_list.append(s1_name[:-1])
            index = d.index(s1_name[-1])
            for i in d:
                if i == d[index]:
                    continue
                s1_name_list.append(s1_name[:-1] + i)
        return list(set(s1_name_list))

    def is_good_schedule(self, station1, station2):
        """获取station1, station2耗时
        """
        ret = {
            "max_spendtime_str": "100:59",
            "min_spendtime_str": "100:59",
            "max_tainnum": "",
            "max_spendtime": 60 * 24 * 100,
            "min_trainnum": "",
            "min_spendtime": 60 * 24 * 100
        }
        key = station1 + '_' + station2
        if key in self.station_time:
            ret = self.station_time[key]
        return ret

    def get_station2station(self,
                            s1_name_list,
                            s2_name_list,
                            space=0,
                            topk=20):
        """获取station1到station2之间换乘可能经过的车站
           span 换乘几次
           topk 花费时间最少的k个换乘车站
        """
        # print "|".join(s1_name_list)
        # print '|'.join(s2_name_list)
        ret_list = []
        station_set = set()
        for i in s1_name_list:
            for j in s2_name_list:
                s1_name = i
                s2_name = j
                # print i, j
                # spendtime = is_good_schedule(s1_name, s2_name)['max_spendtime']
                space_0_json = self.is_good_schedule(s1_name, s2_name)
                spendtime = space_0_json['max_spendtime']
                space_0_json['start_station'] = s1_name
                space_0_json['end_station'] = s2_name
                # print json.dumps(is_good_schedule(s1_name, s2_name), ensure_ascii=False)
                if space == 0 and space_0_json['max_spendtime'] < 144000:
                    ret_list.append(space_0_json)
                if space == 1:
                    try:
                        start = self.start_station[s1_name]
                        end = self.end_station[s2_name]
                    except Exception as ex:
                        continue
                    trains_name = start & end
                    if len(trains_name) < 0:
                        continue
                    for t in trains_name:
                        if t in station_set or t in s1_name_list or t in s2_name_list:
                            continue
                        station_set.add(t)
                        if len(t) > 2 and t[
                                -1] in u'东南西北' and t[:-1] in trains_name:
                            continue
                        station_set.add(t)
                        if t + u'南' in station_set or t + u'北' in station_set or t + u'西' in station_set or \
                                t + u'东' in station_set:
                            station_set.add(t + u'南')
                            station_set.add(t + u'北')
                            station_set.add(t + u'西')
                            station_set.add(t + u'东')
                            continue

                        spendtime_1 = self.is_good_schedule(s1_name,
                                                            t)['min_spendtime']
                        spendtime_2 = self.is_good_schedule(
                            t, s2_name)['min_spendtime']
                        all_spendtime = spendtime_1 + spendtime_2
                        all_spendtime_str = str(
                            all_spendtime / 60) + ':' + str(all_spendtime % 60)
                        if all_spendtime > 2 * spendtime or all_spendtime > 50 * 60 * 24:
                            continue
                        ret_list.append({
                            'station_name': [t],
                            'min_spendtime': all_spendtime,
                            'min_spendtime_str': all_spendtime_str,
                            "start_station": i,
                            'end_station': j
                        })
                if space == 2:
                    try:
                        start = self.start_station[s1_name]
                        end = self.end_station[s2_name]
                    except Exception as ex:
                        # print 'exception:', s1_name, s2_name
                        continue
                    for station in start:
                        dis_1 = self.is_good_schedule(s1_name, station)
                        dis_1_spendtime = dis_1['min_spendtime']
                        start2 = self.start_station[station]
                        trains_name = start2 & end
                        if len(trains_name) < 1:
                            continue
                        for train in trains_name:
                            dis_2 = self.is_good_schedule(station, train)
                            dis_2_spendtime = dis_2['min_spendtime']
                            dis_3 = self.is_good_schedule(train, s2_name)
                            dis_3_spendtime = dis_3['min_spendtime']
                            all_spendtime = dis_1_spendtime + dis_2_spendtime + dis_3_spendtime
                            all_spendtime_str = str(
                                all_spendtime / 60) + ':' + str(
                                    all_spendtime % 60)
                            if all_spendtime > 2 * spendtime or all_spendtime > 50 * 60 * 24:
                                continue
                            ret_list.append({
                                'station_name': [station, train],
                                'min_spendtime': all_spendtime,
                                'min_spendtime_str': all_spendtime_str,
                                "start_station": i,
                                'end_station': j
                            })
        ret_list = sorted(ret_list, key=lambda x: x['min_spendtime'])[:topk]
        return ret_list

    def get_online_alias(self, s1, s2):
        """在线获取可能的站次别名
        """
        ret = self.get_trains_status(s1, s2)
        start_alias = set()
        end_alias = set()
        start_alias.add(s1)
        end_alias.add(s2)
        for i, info in enumerate(ret[0]):
            name_1 = info[1].replace('【', '').replace('】', '').strip()
            name_2 = info[2].replace('【', '').replace('】', '').strip()
            start_alias.add(name_1)
            end_alias.add(name_2)
        return start_alias, end_alias

    def fill_trains(self, first_ret, end_ret):
        """为了展示,填充长度不一致的数据
        """
        if len(first_ret[0]) > len(end_ret[0]):
            lens = len(first_ret[0][0])
            fill = [[' '] * lens] * int(
                math.fabs(len(first_ret[0]) - len(end_ret[0])))
            end_ret[0].extend(fill)
        elif len(first_ret[0]) < len(end_ret[0]):
            lens = len(end_ret[0][0])
            fill = [[' '] * lens] * int(
                math.fabs(len(first_ret[0]) - len(end_ret[0])))
            first_ret[0].extend(fill)

        return first_ret, end_ret

    def train_transfer_status(self, s1, s2, transfer_num=0, topk=10):
        """
        :param s1: station1 name
        :param s2: station2 name
        :param transfer_num: transfer span  0<=span<=2
        :param topk: 展示换乘时间最少的topk个站
        :return: 可换乘的topk个之间站点余票
        """
        ret = []
        if transfer_num == 0:
            ret = self.get_trains_status(s1, s2)
        elif transfer_num == 1:
            self.qiangpiao = False
            start_alias, end_alias = self.get_online_alias(s1, s2)
            ret_station_list = self.get_station2station(start_alias,
                                                        end_alias,
                                                        space=1,
                                                        topk=topk)
            for i, en in enumerate(ret_station_list):
                start_station = en['start_station']
                end_station = en['end_station']
                station_name = en['station_name'][0]
                first_ret = self.get_trains_status(start_station, station_name)
                end_ret = self.get_trains_status(station_name, end_station)
                first_ret, end_ret = self.fill_trains(first_ret, end_ret)
                if len(first_ret[0]) == 0 or len(end_ret[0]) == 0:
                    continue
                ret.append((first_ret, end_ret))
                # break
        return ret, transfer_num
Exemple #31
0
class query:
    """
    查询接口
    """
    def __init__(
        self,
        session,
        from_station,
        to_station,
        from_station_h,
        to_station_h,
        _station_seat,
        station_trains,
        ticke_peoples_num,
        station_dates=None,
    ):
        self.session = session
        self.httpClint = HTTPClient()
        self.urls = urlConf.urls
        self.from_station = from_station
        self.to_station = to_station
        self.from_station_h = from_station_h
        self.to_station_h = to_station_h
        self.station_trains = station_trains
        self._station_seat = _station_seat if isinstance(
            _station_seat, list) else list(_station_seat)
        self.station_dates = station_dates if isinstance(
            station_dates, list) else list(station_dates)
        self.ticket_black_list = dict()
        self.ticke_peoples_num = ticke_peoples_num
        # by time
        self.is_by_time = session.is_by_time
        self.train_types = session.train_types
        self.departure_time = session.departure_time
        self.arrival_time = session.arrival_time
        self.take_time = session.take_time

    @classmethod
    def station_seat(self, index):
        """
        获取车票对应坐席
        :return:
        """
        seat = {
            '商务座': 32,
            '一等座': 31,
            '二等座': 30,
            '特等座': 25,
            '软卧': 23,
            '硬卧': 28,
            '硬座': 29,
            '无座': 26,
        }
        return seat[index]

    def check_time_interval(self, ticket_info):
        return self.departure_time <= time_to_minutes(ticket_info[8]) and \
               time_to_minutes(ticket_info[9]) <= self.arrival_time and \
               time_to_minutes(ticket_info[10]) <= self.take_time

    def check_train_types(self, train):
        train_type = train[0]
        if train_type != "G" and train_type != "D": train_type = "O"
        if train_type in self.train_types:
            return True
        else:
            return False

    def check_is_need_train(self, ticket_info):
        if self.is_by_time:
            return self.check_train_types(
                ticket_info[3]) and self.check_time_interval(ticket_info)
        else:
            return ticket_info[3] in self.station_trains

    def sendQuery(self):
        """
        查询
        :return:
        """
        if self.session.is_cdn == 1:
            if self.session.cdn_list:
                self.httpClint.cdn = self.session.cdn_list[random.randint(
                    0,
                    len(self.session.cdn_list) - 1)]
        for station_date in self.station_dates:
            select_url = copy.copy(self.urls["select_url"])
            select_url["req_url"] = select_url["req_url"].format(
                station_date, self.from_station, self.to_station,
                self.session.queryUrl)
            station_ticket = self.httpClint.send(select_url)
            if station_ticket.get("c_url", ""):
                print(station_ticket.get("c_url", ""))
                self.session.queryUrl = station_ticket.get("c_url",
                                                           "")  # 重设查询接口
                continue
            value = station_ticket.get("data", "")
            if not value:
                print(
                    u'{0}-{1} 车次坐席查询为空, 查询url: https://kyfw.12306.cn{2}, 可以手动查询是否有票'
                    .format(self.from_station_h, self.to_station_h,
                            select_url["req_url"]))
            else:
                result = value.get('result', [])
                if result:
                    for i in value['result']:
                        ticket_info = i.split('|')
                        if ticket_info[11] == "Y" and ticket_info[1].encode(
                                "utf8") == "预订":  # 筛选未在开始时间内的车次
                            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(
                                        ticket_info):  # 过滤有效目标车次
                                    secretStr = ticket_info[0]
                                    train_no = ticket_info[2]
                                    query_from_station_name = ticket_info[6]
                                    query_to_station_name = ticket_info[7]
                                    train_location = ticket_info[15]
                                    stationTrainCode = ticket_info[3]
                                    leftTicket = ticket_info[12]
                                    start_time = ticket_info[8]
                                    arrival_time = ticket_info[9]
                                    distance_time = ticket_info[10]
                                    print start_time, arrival_time, distance_time
                                    seat = j
                                    try:
                                        ticket_num = int(ticket_info[j])
                                    except ValueError:
                                        ticket_num = "有"
                                    print(
                                        u'车次: {0} 始发车站: {1} 终点站: {2} {3}: {4}'.
                                        format(ticket_info[3],
                                               self.from_station_h,
                                               self.to_station_h,
                                               seat_conf_2[j], ticket_num))
                                    if wrapcache.get(train_no):
                                        print(
                                            ticket.QUERY_IN_BLACK_LIST.format(
                                                train_no))
                                        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:
                                                print(
                                                    u"余票数小于乘车人数,当前设置不提交,放弃此次提交机会"
                                                )
                                                continue
                                        else:
                                            print(u"设置乘车人数为: {}".format(
                                                self.ticke_peoples_num))
                                            is_more_ticket_num = self.ticke_peoples_num
                                        print(ticket.QUERY_C)
                                        return {
                                            "secretStr": secretStr,
                                            "train_no": train_no,
                                            "stationTrainCode":
                                            stationTrainCode,
                                            "train_date": station_date,
                                            "query_from_station_name":
                                            query_from_station_name,
                                            "query_to_station_name":
                                            query_to_station_name,
                                            "seat": seat,
                                            "leftTicket": leftTicket,
                                            "train_location": train_location,
                                            "code": ticket.SUCCESS_CODE,
                                            "is_more_ticket_num":
                                            is_more_ticket_num,
                                            "cdn": self.httpClint.cdn,
                                            "status": True,
                                        }
                else:
                    print u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)
        return {"code": ticket.FAIL_CODE, "status": False}
Exemple #32
0
class select:
    def __init__(self):
        self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.ticket_black_list_time = self.get_ticket_info()
        self.is_aotu_code = _get_yaml()["is_aotu_code"]
        self.aotu_code_type = _get_yaml()["aotu_code_type"]
        self.is_cdn = _get_yaml()["is_cdn"]
        self.order_request_params = {}  # 订单提交时的参数
        self.ticketInfoForPassengerForm = {}  # 初始化当前页面参数
        self.current_seats = {}  # 席别信息
        self.token = ""
        self.set_type = ""
        self.user_info = ""
        self.secretStr = ""
        self.ticket_black_list = dict()
        self.is_check_user = dict()
        self.httpClint = HTTPClient()
        self.confUrl = urlConf.urls
        self.login = GoLogin(self.httpClint, self.confUrl, self.is_aotu_code, self.aotu_code_type)
        self.is_download_img = False
        self.randCode = ""
        self.cdn_list = []
        self.buy_ticket_time = ""

    def get_ticket_info(self):
        """
        获取配置信息
        :return:
        """
        ticket_info_config = _get_yaml()
        from_station = ticket_info_config["set"]["from_station"].encode("utf8")
        to_station = ticket_info_config["set"]["to_station"].encode("utf8")
        station_dates = ticket_info_config["set"]["station_dates"]
        set_type = ticket_info_config["set"]["set_type"]
        is_more_ticket = ticket_info_config["set"]["is_more_ticket"]
        ticke_peoples = ticket_info_config["set"]["ticke_peoples"]
        select_refresh_interval = ticket_info_config["select_refresh_interval"]
        station_trains = ticket_info_config["set"]["station_trains"]
        ticket_black_list_time = ticket_info_config["ticket_black_list_time"]
        print u"*"*20
        print u"12306刷票小助手,最后更新于2018.2.28,请勿作为商业用途,交流群号:286271084"
        print u"如果有好的margin,请联系作者,表示非常感激\n"
        print u"当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n刷新间隔:{6}s(如果想随机刷新,请自行修改)\n候选购买车次:{7}\n僵尸票关小黑屋时长:{8}\n".format\
                                                                                      (
                                                                                      from_station,
                                                                                      to_station,
                                                                                      station_dates,
                                                                                      ",".join(set_type),
                                                                                      is_more_ticket,
                                                                                      ",".join(ticke_peoples),
                                                                                      select_refresh_interval,
                                                                                      ",".join(station_trains),
                                                                                      ticket_black_list_time,
            )
        print u"*"*20
        return from_station, to_station, station_dates, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, ticket_black_list_time

    def get_order_request_params(self):
        return self.order_request_params

    def get_ticketInfoForPassengerForm(self):
        return self.ticketInfoForPassengerForm

    def get_current_seats(self):
        return self.current_seats

    def get_token(self):
        return self.token

    def get_set_type(self):
        return self.set_type

    def conversion_int(self, str):
        return int(str)

    def station_seat(self, index):
        """
        获取车票对应坐席
        :param seat_type:
        :return:
        """
        seat = {'商务座': 32,
                '一等座': 31,
                '二等座': 30,
                '特等座': 25,
                '软卧': 23,
                '硬卧': 28,
                '硬座': 29,
                '无座': 26,
                }
        return seat[index]

    def station_table(self, from_station, to_station):
        """
        读取车站信息
        :param station:
        :return:
        """
        result = open('station_name.txt')
        info = result.read().split('=')[1].strip("'").split('@')
        del info[0]
        station_name = {}
        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")]
        return from_station, to_station

    def time(self):
        """
        获取日期
        :return:
        """
        today = datetime.date.today()
        # tomorrow = today+datetime.timedelta(1)
        return today.strftime('%Y-%m-%d')

    def callReadImg(self, code_url):
        """
        下载验证码
        :param code_url: 验证码url
        :return:
        """
        self.login.readImg(code_url=code_url)
        self.is_aotu_code = True

    def callRandCode(self):
        """
        识别验证码
        :return:
        """
        while True:
            if self.is_aotu_code:
                self.randCode = self.login.getRandCode()
                self.is_aotu_code = False

    def getRepeatSubmitToken(self):
        """
        获取提交车票请求token
        :return: token
        """
        initdc_url = self.confUrl["initdc_url"]
        initdc_result = self.httpClint.send(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=(\{.+\})?')
        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 GetJS(self):
        getJSUrl = self.confUrl["GetJS"]
        self.httpClint.send(getJSUrl)
        odxmfwgUrl = self.confUrl["odxmfwg"]
        self.httpClint.send(odxmfwgUrl)

    def getPassengerDTOs(self):
        """
        获取乘客信息
        :return: 
        """
        get_passengerDTOs = self.confUrl["get_passengerDTOs"]
        get_data = {
            '_json_att': None,
            'REPEAT_SUBMIT_TOKEN': self.token
        }
        jsonData = self.httpClint.send(get_passengerDTOs, get_data)
        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]
            return _normal_passenger if _normal_passenger else [normal_passengers[0]]  # 如果配置乘车人没有在账号,则默认返回第一个用户
        else:
            if 'data' in jsonData and 'exMsg' in jsonData['data'] and jsonData['data']['exMsg']:
                print(jsonData['data']['exMsg'])
            elif 'messages' in jsonData and jsonData['messages']:
                print(jsonData['messages'][0])
            else:
                print(u"未查找到常用联系人")
                raise PassengerUserException(u"未查找到常用联系人,请先添加联系人在试试")

    def submitOrderRequestFunc(self, from_station, to_station, station_date=None):
        self.confUrl["select_url"]["req_url"] = self.confUrl["select_url"]["req_url"].format(
            station_date, from_station, to_station)
        station_ticket = self.httpClint.send(self.confUrl["select_url"])
        return json.loads(station_ticket)

    def submitOrderRequestImplement(self, from_station, to_station,):
        """
        提交车次信息
        车次对应字典
        {32: '商务座 ',
            31: '一等座 ',
            30: '二等座 ',
            25: '特等座 ',
            23: '软卧 ',
            28: '硬卧 ',
            29: '硬座 ',
            26: '无座 '
        } 参照station_seat()方法
        :return:
        """
        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:
                print (u'{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].encode("utf8") == "预订":  # 筛选未在开始时间内的车次
                            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 (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):
                                        print(u"该车次{} 正在被关小黑屋,跳过此车次".format(train_no))
                                        break
                                    else:
                                        print (u'正在尝试提交订票...')
                                        self.buy_ticket_time = datetime.datetime.now()
                                        # self.submitOrderRequestFunc(from_station, to_station, self.time())
                                        self.submit_station()
                                        self.getPassengerTicketStr(self._station_seat[j].encode("utf8"))
                                        self.getRepeatSubmitToken()
                                        if not self.user_info:  # 修改每次都调用用户接口导致用户接口不能用
                                            self.user_info = self.getPassengerDTOs()
                                        codeImgByOrder = self.confUrl["codeImgByOrder"]
                                        self.login.readImg(codeImgByOrder)
                                        if self.checkOrderInfo(train_no, self._station_seat[j].encode("utf8")):
                                            break
                                else:
                                    pass
                        else:
                            pass
                    # time.sleep(self.expect_refresh_interval)
                else:
                    print u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)

    def check_user(self):
        """
        检查用户是否达到订票条件
        :return:
        """
        check_user_url = self.confUrl["check_user_url"]
        data = {"_json_att": ""}
        check_user = self.httpClint.send(check_user_url, data)
        check_user_flag = check_user['data']['flag']
        if check_user_flag is True:
            self.is_check_user["user_time"] = datetime.datetime.now()
        else:
            if check_user['messages']:
                print (u'用户检查失败:%s,可能未登录,可能session已经失效' % check_user['messages'][0])
                print (u'正在尝试重新登录')
                self.call_login()
                self.is_check_user["user_time"] = datetime.datetime.now()
            else:
                print (u'用户检查失败: %s,可能未登录,可能session已经失效' % check_user)
                print (u'正在尝试重新登录')
                self.call_login()
                self.is_check_user["user_time"] = datetime.datetime.now()

    def submit_station(self):
        """
        提交车次
        预定的请求参数,注意参数顺序
        注意这里为了防止secretStr被urllib.parse过度编码,在这里进行一次解码
        否则调用HttpTester类的post方法将会将secretStr编码成为无效码,造成提交预定请求失败
        :param self:
        :param secretStr: 提交车次加密
        :return:
        """
        submit_station_url = self.confUrl["submit_station_url"]
        data = [('secretStr', urllib.unquote(self.secretStr)),  # 字符串加密
                ('train_date', self.station_dates[0]),  # 出发时间
                ('back_train_date', self.time()),  # 返程时间
                ('tour_flag', 'dc'),  # 旅途类型
                ('purpose_codes', 'ADULT'),  # 成人票还是学生票
                ('query_from_station_name', self.from_station),  # 起始车站
                ('query_to_station_name', self.to_station),  # 终点车站
                ]
        submitResult = self.httpClint.send(submit_station_url, data)
        if 'data' in submitResult and submitResult['data']:
            if submitResult['data'] == 'N':
                print (u'出票成功')
            else:
                print (u'出票失败')
        elif 'messages' in submitResult and submitResult['messages']:
            raise ticketIsExitsException(submitResult['messages'][0])

    def getPassengerTicketStr(self, set_type):
        """
        获取getPassengerTicketStr 提交对应的代号码
        :param str: 坐席
        :return: 
        """
        passengerTicketStr = {
            '一等座': 'M',
            '特等座': 'P',
            '二等座': 'O',
            '商务座': 9,
            '硬座': 1,
            '无座': 1,
            '软卧': 4,
            '硬卧': 3,
        }
        self.set_type = str(passengerTicketStr[set_type.replace(' ', '')])

    def ticket_type(self):
        """订单票的类型,目前只考虑成人票,此方法暂时搁置,做备案"""
        ticket_type = {'adult': "1", 'child': "2", 'student': "3", 'disability': "4"}
        return ticket_type

    def getPassengerTicketStrListAndOldPassengerStr(self):
        """
        获取提交车次人内容格式
        passengerTicketStr	O,0,1,文贤平,1,43052419950223XXXX,15618715583,N_O,0,1,梁敏,1,43052719920118XXXX,,N
        oldPassengerStr	文贤平,1,43052719920118XXXX,1_梁敏,1,43052719920118XXXX,1_
        :return:
        """
        passengerTicketStrList = []
        oldPassengerStr = []
        if not self.user_info:
            raise PassengerUserException(u"联系人不在列表中,请查证后添加")
        if len(self.user_info) is 1:
            passengerTicketStrList.append(
                '0,' + self.user_info[0]['passenger_type'] + "," + 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]['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'] + '_')
        else:
            for i in range(len(self.user_info)):
                passengerTicketStrList.append(
                    '0,' + self.user_info[i]['passenger_type'] + "," + self.user_info[i][
                        "passenger_name"] + "," + self.user_info[i]['passenger_id_type_code'] + "," + self.user_info[i][
                        'passenger_id_no'] + "," + self.user_info[i]['mobile_no'] + ',N_' + self.set_type)
                oldPassengerStr.append(
                    self.user_info[i]['passenger_name'] + "," + self.user_info[i]['passenger_id_type_code'] + "," +
                    self.user_info[i]['passenger_id_no'] + "," + self.user_info[i]['passenger_type'] + '_')
        return passengerTicketStrList, oldPassengerStr

    def checkOrderInfo(self, train_no, set_type):
        """
        检查支付订单,需要提交REPEAT_SUBMIT_TOKEN
        passengerTicketStr : 座位编号,0,票类型,乘客名,证件类型,证件号,手机号码,保存常用联系人(Y或N)
        oldPassengersStr: 乘客名,证件类型,证件号,乘客类型
        :return: 
        """
        passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr()
        checkOrderInfoUrl = self.confUrl["checkOrderInfoUrl"]
        data = collections.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 = self.httpClint.send(checkOrderInfoUrl, data)
        if 'data' in checkOrderInfo:
            if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo["data"]["ifShowPassCode"] == "Y":
                is_need_code = True
                if self.getQueueCount(train_no, set_type, is_need_code):
                    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):
                        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])

    def getQueueCount(self, train_no, set_type, is_need_code):
        """
        # 模拟查询当前的列车排队人数的方法
        # 返回信息组成的提示字符串
        :param token:
        :return:
        """
        l_time = time.localtime(time.time())
        new_train_date = time.strftime("%a %b %d %Y", l_time)
        getQueueCountUrl = self.confUrl["getQueueCountUrl"]
        data = collections.OrderedDict()
        data['train_date'] = str(new_train_date) + " 00:00:00 GMT+0800 (中国标准时间)",
        data['train_no'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_no'],
        data['stationTrainCode'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['station_train_code'],
        data['seatType'] = self.set_type,
        data['fromStationTelecode'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['from_station'],
        data['toStationTelecode'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['to_station'],
        data['leftTicket'] = 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(),
        getQueueCountResult = self.httpClint.send(getQueueCountUrl, data)
        if "status" in getQueueCountResult and getQueueCountResult["status"] is True:
            if "countT" in getQueueCountResult["data"]:
                ticket = getQueueCountResult["data"]["ticket"]
                ticket_split = sum(map(self.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.user_info):
                        print(u"当前余票数小于乘车人数,放弃订票")
                    else:
                        print(u"排队成功, 当前余票还剩余: {0} 张".format(ticket_split))
                        if self.checkQueueOrder(is_need_code):
                            return True
                else:
                    print(u"当前排队人数: {1} 当前余票还剩余:{0} 张,继续排队中".format(ticket_split, countT))
            else:
                print(u"排队发现未知错误{0},将此列车 {1}加入小黑屋".format(getQueueCountResult, train_no))
                self.ticket_black_list[train_no] = datetime.datetime.now()
        elif "messages" in getQueueCountResult and getQueueCountResult["messages"]:
            print(u"排队异常,错误信息:{0}, 将此列车 {1}加入小黑屋".format(getQueueCountResult["messages"][0], train_no))
            self.ticket_black_list[train_no] = datetime.datetime.now()
        else:
            if "validateMessages" in getQueueCountResult and getQueueCountResult["validateMessages"]:
                print(str(getQueueCountResult["validateMessages"]))
                self.ticket_black_list[train_no] = datetime.datetime.now()
            else:
                print(u"未知错误 {0}".format("".join(getQueueCountResult)))

    def checkRandCodeAnsyn(self, randCode):
        """
        识别验证码
        :return: 识别结果
        """
        checkRandCodeAnsyn = self.confUrl["checkRandCodeAnsyn"]
        randData = {
            "randCode": randCode,
            "rand": "randp",
            "_json_att": None,
            "REPEAT_SUBMIT_TOKEN": self.get_token()
        }
        fresult = self.httpClint.send(checkRandCodeAnsyn, randData)  # 校验验证码是否正确
        return fresult['data']['msg']

    def checkQueueOrder(self, is_node_code=False):
        """
        模拟提交订单是确认按钮,参数获取方法还是get_ticketInfoForPassengerForm 中获取
        :return: 
        """

        passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr()
        checkQueueOrderUrl = self.confUrl["checkQueueOrderUrl"]
        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": "",
            "randCode": "",
            "choose_seats": "",
            "REPEAT_SUBMIT_TOKEN": self.get_token(),
        }
        try:
            if is_node_code:
                print(u"正在使用自动识别验证码功能")
                for i in range(3):
                    randCode = self.login.getRandCode()
                    checkcode = self.checkRandCodeAnsyn(randCode)
                    if checkcode == 'TRUE':
                        print(u"验证码通过,正在提交订单")
                        data['randCode'] = randCode
                        break
                    else:
                        print (u"验证码有误, {0}次尝试重试".format(i+1))
                print(u"验证码超过限定次数3次,放弃此次订票机会!")
            else:
                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)
            checkQueueOrderResult = self.httpClint.send(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(u"提交订单成功!")
                    self.queryOrderWaitTime()
                else:
                    if 'errMsg' in c_data and c_data['errMsg']:
                        print(u"提交订单失败,{0}".format(c_data['errMsg']))
                    else:
                        print(c_data)
                        print(u'订票失败!很抱歉,请重试提交预订功能!')
            elif "messages" in checkQueueOrderResult and checkQueueOrderResult["messages"]:
                print(u"提交订单失败,错误信息: " + checkQueueOrderResult["messages"])
            else:
                print(u"提交订单中,请耐心等待:" + checkQueueOrderResult["message"])
        except ValueError:
            print(u"接口 {} 无响应".format(checkQueueOrderUrl))

    def queryOrderWaitTime(self):
        """
        排队获取订单等待信息,每隔3秒请求一次,最高请求次数为20次!
        :return: 
        """
        num = 1
        while True:
            _random = int(round(time.time() * 1000))
            num += 1
            if num > 30:
                print(u"超出排队时间,自动放弃,正在重新刷票")
                order_id = self.queryMyOrderNoComplete()  # 排队失败,自动取消排队订单
                if order_id:
                    self.cancelNoCompleteMyOrder(order_id)
                break
            try:
                data = {"random": _random, "tourFlag": "dc"}
                queryOrderWaitTimeUrl = self.confUrl["queryOrderWaitTimeUrl"]
                queryOrderWaitTimeResult = self.httpClint.send(queryOrderWaitTimeUrl, data)
            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(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"]:
                        print(u"排队等待时间预计还剩 {0} ms".format(0-queryOrderWaitTimeResult["data"]["waitTime"]))
                    else:
                        print ("正在等待中")
                elif "messages" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["messages"]:
                    print(u"排队等待失败: " + queryOrderWaitTimeResult["messages"])
                else:
                    print(u"第{}次排队中,请耐心等待".format(num+1))
            else:
                print(u"排队中")
            time.sleep(2)

        else:
            print(ticketNumOutException(u"订单提交失败!,正在重新刷票"))

    def queryMyOrderNoComplete(self):
        """
        获取订单列表信息
        :return:
        """
        self.initNoComplete()
        queryMyOrderNoCompleteUrl = self.confUrl["queryMyOrderNoCompleteUrl"]
        data = {"_json_att": ""}
        try:
            queryMyOrderNoCompleteResult = self.httpClint.send(queryMyOrderNoCompleteUrl, data)
        except ValueError:
            queryMyOrderNoCompleteResult = {}
        if queryMyOrderNoCompleteResult:
            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"]:
                    print(queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]["message"])
                    raise ticketNumOutException(queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]["message"])
            else:
                if "message" in queryMyOrderNoCompleteResult and queryMyOrderNoCompleteResult["message"]:
                    print queryMyOrderNoCompleteResult["message"]
                    return False
                else:
                    return False
        else:
            print(u"接口 {} 无响应".format(queryMyOrderNoCompleteUrl))

    def initNoComplete(self):
        """
        获取订单前需要进入订单列表页,获取订单列表页session
        :return:
        """
        self.httpClint.set_cookies(acw_tc="AQAAAEnFJnekLwwAtGHjZZCr79B6dpXk", current_captcha_type="Z")
        initNoCompleteUrl = self.confUrl["initNoCompleteUrl"]
        data = {"_json_att": ""}
        self.httpClint.send(initNoCompleteUrl, data)

    def cancelNoCompleteMyOrder(self, sequence_no):
        """
        取消订单
        :param sequence_no: 订单编号
        :return:
        """
        cancelNoCompleteMyOrderUrl = self.confUrl["cancelNoCompleteMyOrder"]
        cancelNoCompleteMyOrderData = {
            "sequence_no": sequence_no,
            "cancel_flag": "cancel_order",
            "_json_att": ""
        }
        cancelNoCompleteMyOrderResult = self.httpClint.send(cancelNoCompleteMyOrderUrl, cancelNoCompleteMyOrderData)
        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
        else:
            print(u"排队超时,取消订单失败, 订单号{0}".format(sequence_no))

    def set_cdn(self):
        """
        设置cdn
        :return:
        """
        if self.is_cdn == 1:
            while True:
                if self.cdn_list:
                    self.httpClint.cdn = self.cdn_list[random.randint(0, len(self.cdn_list)-1)]
                    break
                else:
                    pass

    def call_login(self, auth=False):
        """
        登录回调方法
        :return:
        """
        if auth:
            return self.login.auth()
        else:
            self.login.go_login()

    def cdn_req(self, cdn):
        for i in range(len(cdn)-1):
            http = HTTPClient()
            urls = self.confUrl["loginInit"]
            start_time = datetime.datetime.now()
            http.cdn = cdn[i].replace("\n", "")
            rep = http.send(urls)
            if rep and "message" not in rep and (datetime.datetime.now() - start_time).microseconds / 1000 < 200:
                self.cdn_list.append(cdn[i].replace("\n", ""))
        print(u"所有cdn解析完成...")

    def cdn_certification(self):
        """
        cdn 认证
        :return:
        """
        if self.is_cdn == 1:
            CDN = CDNProxy()
            all_cdn = CDN.all_cdn()
            if all_cdn:
                print(u"开启cdn查询")
                print(u"本次待筛选cdn总数为{}".format(len(all_cdn)))
                t = threading.Thread(target=self.cdn_req, args=(all_cdn,))
                t.start()
            else:
                raise ticketConfigException(u"cdn列表为空,请先加载cdn")
        else:
            pass

    def main(self):
        self.cdn_certification()
        self.set_cdn()
        self.call_login()
        from_station, to_station = self.station_table(self.from_station, self.to_station)
        self.check_user()
        time.sleep(0.1)
        num = 1
        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:
                    # 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":
                    print(u"12306休息时间,本程序自动停止,明天早上6点将自动运行")
                    while 1:
                        time.sleep(1)
                        if time.strftime('%H:%M:%S', time.localtime(time.time())) > "06:00:00":
                            print(u"休息时间已过,重新开启检票功能")
                            self.call_login()
                            break
                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,
                                                                                                 len(self.cdn_list))
                self.set_cdn()
            except PassengerUserException as e:
                print e.message
                break
            except ticketConfigException as e:
                print e.message
                break
            except ticketIsExitsException as e:
                print e.message
                break
            except ticketNumOutException as e:
                print e.message
                break
            except UserPasswordException as e:
                print e.message
                break
            except ValueError as e:
                if e.message == "No JSON object could be decoded":
                    print(u"12306接口无响应,正在重试")
                else:
                    print(e.message)
            except KeyError as e:
                print(e.message)
            except TypeError as e:
                print(u"12306接口无响应,正在重试 {0}".format(e.message))
            except socket.error as e:
                print(e.message)
# coding=utf-8
from config.urlConf import urls
from myUrllib.httpUtils import HTTPClient

httpClint = HTTPClient()


def getPassCodeNewOrderAndLogin(session, imgType):
    """
    下载验证码
    :param session:
    :param imgType: 下载验证码类型,login=登录验证码,其余为订单验证码
    :return:
    """
    if imgType == "login":
        codeImgUrl = urls["getCodeImg"]
        print codeImgUrl
        # codeImgUrl = session.urls["getCodeImg"]
    else:
        # codeImgUrl = session.urls["codeImgByOrder"]
        codeImgUrl = urls["codeImgByOrder"]
    print(u"下载验证码...")
    img_path = '../flask_app/static/images/login/tkcode.png'
    # result = session.httpClint.send(codeImgUrl)
    print codeImgUrl
    result = session.httpClint.send(codeImgUrl)
    try:
        print(u"下载验证码成功")
        open(img_path, 'wb').write(result)
    except OSError:
        print(u"验证码下载失败,可能ip被封,确认请手动请求: {0}".format(codeImgUrl))