Пример #1
0
    def run(self):
        status = self.pre_check()
        if not status:
            return

        Log.v("正在查询车次余票信息")
        count = 1

        while True:
            self.maintain_mode()
            self.heart_beat_mode()
            dates = DispatcherTool.query_travel_dates
            if Config.basic_config.use_station_group:
                station_groups = [(v.from_station, v.to_station)
                                  for v in Config.basic_config.station_groups]
            else:
                station_groups = list(
                    product(Config.basic_config.from_stations,
                            Config.basic_config.to_stations))
            query_params = list(product(dates, station_groups))

            for query_params in query_params:
                Log.v("查询第 {0} 次".format(count))
                n = datetime.datetime.now()
                data = DispatcherTool.run(query_params)
                count += 1
                self.submit_order(data)
                DispatcherTool.output_delta_time(n)
                if self.order_id or self.unfinished_order:
                    break
            if self.order_id or self.unfinished_order:
                break
        self.notice_user()
Пример #2
0
 def _get_queue_count(self):
     form_data = {
         'train_date': datetime.datetime.strptime(
             self.ticket_passenger_info['queryLeftTicketRequestDTO']['train_date'], '%Y%m%d').strftime(
             '%b %a %d %Y 00:00:00 GMT+0800') + ' (中国标准时间)',
         'train_no': self.ticket_passenger_info['queryLeftTicketRequestDTO']['train_no'],
         'stationTrainCode': self.train.stationTrainCode.value,
         'seatType': self.seat_type.sys_code,
         'fromStationTelecode': self.train.from_station_code.value,
         'toStationTelecode': self.train.to_station_code.value,
         'leftTicket': self.ticket_passenger_info['leftTicketStr'],
         'purpose_codes': self.ticket_passenger_info['purpose_codes'],
         'train_location': self.ticket_passenger_info['train_location'],
         '_json_att': '',
         'REPEAT_SUBMIT_TOKEN': self.token
     }
     Log.v("正在获取排队信息以及余票信息中...")
     json_response = send_requests(LOGIN_SESSION, self.URLS['getQueueCount'], data=form_data)
     status, msg = submit_response_checker(json_response, ["status"], True, "获取余票信息成功")
     if status:
         self.left_tickets = json_response['data']['ticket']
         Log.v("票数剩余{0}张, 排队人数为{1}人".format(
             self.left_tickets,
             json_response['data']['count']
         ))
     else:
         BlackTrains.add_train(self.train)
     return status, msg
Пример #3
0
 def login(self):
     if not LOGIN_SESSION.cookies.get("RAIL_EXPIRATION") or \
        not LOGIN_SESSION.cookies.get("RAIL_DEVICEID"):
         status, msg = self._init()
         if not status:
             return status, msg
     # status, msg = self._get_device_fingerprint()
     # if not status:
     #     Log.v("设备ID获取失败")
     #     return status, msg
     # self._init2()
     captcha = Captcha("normal")
     status, msg = captcha.verify()
     if not status:
         Log.v("验证码校验失败")
         return status, msg
     payload = {
         'username': Config.train_account.user,
         'password': Config.train_account.pwd,
         'appid': 'otn',
         'answer': captcha.results
     }
     json_response = send_requests(LOGIN_SESSION, self.URLS['login'], data=payload)
     result, msg = json_status(json_response, [], '0')
     if not result:
         return (False, json_response.get("result_message", None)) \
             if isinstance(json_response, dict) else (False, '登录接口提交返回数据出现问题')
     self._passportredirect()
     result, msg, apptk = self._uamtk()
     if not result:
         Log.v(msg)
         return False, msg
     status, msg = self._uamauthclient(apptk)
     return status, msg
Пример #4
0
 def verifyhandle_freeapi(self):
     Log.v("使用免费api进行验证码识别")
     img_base64 = base64.b64encode(self.generator_image()).decode()
     r = requests.post(FREE_CAPTCHA_URL, json={"base64": img_base64})
     try:
         check = r.json()["data"]["check"]
     except (KeyError, JSONDecodeError):
         return False, "免费打码接口返回出现问题"
     v = requests.post(FREE_CAPTCHA_CHECK_URL,
                       json={
                           "=": "",
                           "check": check,
                           "img_buf": img_base64,
                           "logon": 1,
                           "type": "D"
                       },
                       headers=FREE_CAPTCHA_HEADERS)
     try:
         data = ast.literal_eval(v.json()["res"])
     except KeyError:
         return False, "免费打码接口返回出现问题"
     except SyntaxError:
         return False, "免费打码接口返回出现问题"
     if type(data[0]) == int:
         self.results = ','.join(map(str, list(data)))
     else:
         self.results = ','.join(map(str, list(chain(*data))))
     return self.check(self.results)
Пример #5
0
 def heart_beat_mode(self):
     if Config.auto_code_enable:
         status, msg = self.online_checker()
         Log.v(msg)
         if not status:
             Log.e("心跳登录失败,继续重试中,建议手动检查原因再尝试重启")
             self.online_checker_now()
Пример #6
0
 def _uamtk(self):
     json_data = send_requests(LOGIN_SESSION, self.URLS["uamtk"], data={'appid': 'otn'})
     Log.d(json_data)
     result, msg = json_status(json_data, ["result_message", "newapptk"])
     if not result:
         return result, msg, None
     else:
         return result, msg, json_data["newapptk"]
Пример #7
0
 def maintain_mode(self):
     if self.check_maintain():
         Log.v("12306系统每天 23:00 - 6:00 之间 维护中, 程序暂时停止运行")
         maintain_time = self.delta_maintain_time()
         Log.v("{0}小时 {1}分钟 {2}秒之后重新启动".format(
             maintain_time.seconds // 3600,
             (maintain_time.seconds // 60) % 60,
             maintain_time.seconds % 3600 % 60))
         time.sleep(self.delta_maintain_time().total_seconds())
Пример #8
0
 def filter_black_trains(self):
     result = []
     for v in self.result:
         flag = BlackTrains.check(v[1])
         if flag:
             Log.v("{0} 车次已经在小黑屋".format(v[1].stationTrainCode.value))
         else:
             result.append(copy.copy(v))
     return result
Пример #9
0
 def _uamauthclient(self, apptk):
     json_response = send_requests(LOGIN_SESSION,
                                   self.URLS['uamauthclient'],
                                   data={'tk': apptk})
     status, msg = json_status(json_response,
                               ["username", "result_message"])
     if status:
         Log.v("欢迎 {0} 登录".format(json_response["username"]))
     return status, msg
Пример #10
0
 def _check_order_status_queue(self):
     params = {
         'orderSequence_no': self.order_id,
         '_json_att': '',
         'REPEAT_SUBMIT_TOKEN': self.token,
     }
     Log.v("检查已提交的订单的状态中...")
     json_response = send_requests(LOGIN_SESSION, self.URLS['resultOrderForQueue'], params=params)
     status, msg = submit_response_checker(json_response, ["status", "data.submitStatus"], True, "订单已经成功提交")
     return status, msg
Пример #11
0
 def pre_check(self):
     if Config.cdn_enable:
         CdnStorage.load_exists()
     if not self.login():
         return False
     p_status = self.query_passengers()
     if not p_status:
         return False
     if not Config.auto_code_enable:
         Log.v("未开启自动打码功能, 不检测用户登录状态")
     return True
Пример #12
0
    def run(self, travel_date):
        Log.v("当前查询日期为 {}".format(travel_date))
        q = Query(travel_date)
        data = q.filter()
        if not data:
            Log.v("日期 {0} 满足条件的车次暂无余票, 正在重新查询".format(travel_date))

        for v in data:
            print("\t\t\t当前座位席别 {}".format(v[0].name))
            q.pretty_output(v[1])
        return data
Пример #13
0
 def getcaptcha():
     while True:
         try:
             data = get_captcha_image(
                 LOGIN_SESSION, LOGIN_URL_MAPPING["normal"]["captcha"])
             break
         except ResponseCodeError:
             Log.v("获取验证码信息失败,重试获取验证码中...")
             continue
     img_binary = base64.b64decode(data["image"])
     return img_binary
Пример #14
0
 def generator_image(self):
     while True:
         data = self.getcaptcha()
         try:
             img = Image.open(BytesIO(data))
             img.close()
             break
         except OSError:
             Log.e("获取验证码图片失败, 重试获取")
             continue
     return data
Пример #15
0
 def run(self):
     Log.v("您已开启cdn加速")
     Log.v("正在检查cdn列表可用状态....(大概将会花费10分钟左右)")
     self.pool.map(self.verify, self.raw_cdn_list)
     self.status = True
     Log.v("共获取{0}个可用的cdn".format(len(self.result)))
     Log.v("各个cdn的等级情况如下(level等级越低证明, cdn的连接更快):")
     level_result = [v.level for v in self.result]
     level_types = set(level_result)
     for v in level_types:
         Log.v("level {0} 共有 {1} 个".format(v, level_result.count(v)))
Пример #16
0
 def run(self):
     while self.retry_time:
         for v in FAST_PIPELINE:
             status, msg = getattr(self, v)()
             if not status:
                 self.retry_time -= 1
                 break
         else:
             Log.v("提交订单成功")
             return True
     Log.v("提交订单失败")
     return False
Пример #17
0
    def run(self, query_data):
        Log.v("当前查询日期为 **{0}** 出发地 **{1}** 目的地 **{2}**".format(
            query_data[0], query_data[1][0], query_data[1][1]))
        q = Query(query_data[0], query_data[1][0], query_data[1][1])
        data = q.filter()
        if not data:
            Log.v("日期 **{0}** 出发地 **{1}** 目的地 **{2}** 满足条件的车次暂无余票, 正在重新查询".
                  format(query_data[0], query_data[1][0], query_data[1][1]))

        for v in data:
            print("\t\t\t当前座位席别 {}".format(v[0].name))
            q.pretty_output(v[1])
        return data
Пример #18
0
 def filter(self):
     # 先过滤席位
     self.filter_by_seat()
     # 过滤小黑屋的车次
     self.result = self.filter_black_trains()
     if Config.basic_config.manual_trainnum_enable:
         self.result = self.filter_train_num()
     else:
         self.result = self.filter_train_time()
         self.result = self.filter_train_type()
     if self.result:
         Log.v("查找到符合配置的车次信息: {0}".format(','.join(
             [v[1].stationTrainCode.value for v in self.result])))
     return self.result
Пример #19
0
 def verifyhandle_hand(self):
     img = Image.open(BytesIO(self.generator_image()))
     img.show()
     Log.v("""
         -----------------
         | 0 | 1 | 2 | 3 |
         -----------------
         | 4 | 5 | 6 | 7 |
         ----------------- """)
     results = input("输入验证码索引(见上图,以','分割): ")
     img.close()
     trans = self.trans_captcha_results(results)
     self.results = trans
     return self.check(trans)
Пример #20
0
 def verifyhandle_ruokuai(self):
     c = RClient()
     data = c.rk_create(self.generator_image())
     if "Result" in data:
         trans = self.trans_captcha_results(','.join(
             [str(int(v) - 1) for v in data["Result"]]))
         self.results = trans
         return self.check(trans)
     else:
         if "Error" in data and data["Error"]:
             Log.e(
                 "打码平台错误: {0}, 请登录打码平台查看-http://www.ruokuai.com/client/index?6726"
                 .format(data["Error"]))
             return False, "若快打码平台错误"
Пример #21
0
 def online_checker(self):
     # 两分钟检测一次
     flag = OnlineCheckerTool.should_check_online(datetime.datetime.now())
     if flag:
         status, msg = OnlineCheckerTool.checker()
         OnlineCheckerTool.update_check_time()
         if not status:
             Log.v("用户登录失效, 正在为您重试登录")
             login_status = self.login()
             if not login_status:
                 return False, "重试登录失败"
         else:
             return status, msg
     else:
         status, msg = True, "用户状态检测:未到检测时间"
     return status, msg
Пример #22
0
 def _check_order_info(self):
     form_data = {
         'cancel_flag': self.ticket_passenger_info['orderRequestDTO']['cancel_flag'] or '2',
         'bed_level_order_num': self.ticket_passenger_info['orderRequestDTO']['bed_level_order_num'] \
                                or '000000000000000000000000000000',
         'passengerTicketStr': build_passenger_ticket_string(self.seat_type, self.passenger_data),
         'oldPassengerStr': build_oldpassenger_ticket_string(self.passenger_data),
         'tour_flag': self.ticket_passenger_info['tour_flag'] or 'dc',
         'randCode': '',
         'whatsSelect': '1',
         '_json_att': '',
         'REPEAT_SUBMIT_TOKEN': self.token,
     }
     Log.v("正在提交检查订单状态请求")
     json_response = send_requests(LOGIN_SESSION, self.URLS['checkOrderInfo'], data=form_data)
     status, msg = submit_response_checker(json_response, ["status", "data.submitStatus"], True, "校验订单成功")
     return status, msg
Пример #23
0
 def notice_user(self):
     if self.order_id:
         Log.v("车票信息:")
         for order_ticket in self.order_tickets:
             print(order_ticket)
             # 抢票成功发邮件信息
             NoticeTool.notice(
                 msg_type=2,
                 **{
                     "order_no":
                     self.order_id,
                     "ticket_info":
                     "</br>".join([v.to_html() for v in self.order_tickets])
                 })
     else:
         Log.v("您有未完成订单, 请及时处理后再运行程序")
         NoticeTool.notice(msg_type=3)
Пример #24
0
    def check(self, results):
        form_data = {
            'randCode': results,
            'rand': 'sjrand',
        }

        json_response = send_requests(
            LOGIN_SESSION,
            LOGIN_URL_MAPPING["other"]["captchaCheck"],
            data=form_data)
        Log.v('other login captcha verify: %s' % json_response)

        def verify(response):
            return response['status'] and self.success_code == response[
                'data']['result']

        v = verify(json_response)
        return v, "Error" if not v else v
Пример #25
0
 def login(self):
     count = 0
     while self.retry_login_time >= count:
         login_instance = NormalLogin()
         Log.v("正在为您登录")
         status, msg = login_instance.login()
         if not status:
             count += 1
             Log.e(msg)
             Log.v("登录失败, 重试{0}次".format(count)) if self.retry_login_time >= count else ""
             continue
         else:
             Log.v("登录成功")
             break
     if self.retry_login_time < count:
         Log.v("重试次数已经超过设置")
         return False
     return True
Пример #26
0
 def check_current_mode(self):
     if (not Config.presale_enable) or self.pre_sale_end:
         return False
     else:
         now = datetime.datetime.now()
         open_times = list(
             map(format_time, Config.presale_config.start_times))
         f = lambda x: x - now <= self.delta_stop_time and now - x <= self.delta_continue_time
         result = any(filter(f, open_times))
         if result:
             Log.v("当前处于预售模式,不再处理正常模式下的日期查询")
             return True
         check_result = list(
             filter(lambda x: now > x + self.delta_continue_time,
                    open_times))
         if check_result and all(check_result):
             self.pre_sale_end = True
             return False
     return False
Пример #27
0
 def _confirm_single_or_go_for_queue(self):
     form_data = {
         'passengerTicketStr':
         build_passenger_ticket_string(self.seat_type, self.passenger_data),
         'oldPassengerStr':
         build_oldpassenger_ticket_string(self.passenger_data),
         'randCode':
         '',
         'purpose_codes':
         self.ticket_passenger_info['purpose_codes'],
         'key_check_isChange':
         self.ticket_passenger_info['key_check_isChange'],
         'leftTicketStr':
         self.ticket_passenger_info['leftTicketStr'],
         'train_location':
         self.ticket_passenger_info['train_location'],
         'choose_seats':
         '',  # 暂时未加选座
         'seatDetailType':
         '000',
         'whatsSelect':
         '1',
         'roomType':
         '00',
         'dwAll':
         'N',
         '_json_att':
         '',
         'REPEAT_SUBMIT_TOKEN':
         self.token,
     }
     Log.v("正在为你请求排队提交订单")
     json_response = send_requests(LOGIN_SESSION,
                                   self.URLS['confirmForQueue'],
                                   data=form_data)
     status, msg = submit_response_checker(json_response,
                                           ["status", "data.submitStatus"],
                                           True, "请求排队成功")
     if not status:
         BlackTrains.add_train(self.train)
     return status, msg
Пример #28
0
 def _wait_for_order_id(self):
     # 排队逻辑
     t = datetime.datetime.now()
     # 排队10分钟
     delta = datetime.timedelta(minutes=10)
     while not self.order_id:
         loop_time = datetime.datetime.now()
         status, msg = self._query_order_wait_time()
         Log.v(msg)
         s, data = find_by_phrase(msg)
         if s:
             self.break_submit, self.break_msg = False, data["msg"]
             return self.break_submit, self.break_msg
         # 5s 获取排队信息
         time.sleep(5)
         if self.order_id:
             return True, "OK"
         if loop_time > t + delta:
             BlackTrains.add_train(self.train)
             return False, "提交超时"
     return False, "排队失败"
Пример #29
0
 def _query_order_wait_time(self):
     params = {
         'random': '%10d' % (time.time() * 1000),
         'tourFlag': self.ticket_passenger_info['tour_flag'] or 'dc',
         '_json_att': '',
         'REPEAT_SUBMIT_TOKEN': self.token
     }
     Log.v("获取订单排队信息...")
     json_response = send_requests(LOGIN_SESSION, self.URLS['queryOrderWaitTime'], params=params)
     status, msg = submit_response_checker(json_response, ["status"], True, "排队请求成功")
     if status:
         self.wait_time = json_response['data']['waitTime']
         self.order_id = json_response['data']['orderId']
         people_count = json_response["data"]["waitCount"]
         msg += " 排队等待时间预计还剩 {0} ms, 排队人数还剩 {1} 人".format(
             self.wait_time, people_count)
         if not self.order_id:
             msg += "\t 订单暂未生成"
         if "msg" in json_response["data"]:
             msg += "\t {0}".format(json_response["data"]["msg"])
     return status, msg
Пример #30
0
 def rk_create(self, im_string, timeout=60):
     """
     im: 图片字节
     im_type: 题目类型
     """
     params = {
         'typeid': 6113,
         'timeout': timeout,
     }
     params.update(self.base_params)
     files = {'image': ('a.jpg', im_string)}
     while True:
         try:
             r = requests.post('http://api.ruokuai.com/create.json',
                               data=params,
                               files=files,
                               headers=self.headers)
             #
             Log.v("使用若快进行验证码识别")
             data = r.json()
             break
         except requests.RequestException:
             Log.w("提交若快打码请求出现问题, 正在重试中...")
             continue
     Log.d(data)
     return data