def start(self): """ 处理单个任务 根据日期循环查询, 展示处理时间 :param job: :return: """ while True and self.is_alive: app_available_check() QueryLog.print_job_start(self.job_name) for station in self.stations: self.refresh_station(station) for date in self.left_dates: self.left_date = date response = self.query_by_date(date) self.handle_response(response) QueryLog.add_query_time_log( time=response.elapsed.total_seconds(), is_cdn=self.is_cdn) if not self.is_alive: return self.safe_stay() if is_main_thread(): QueryLog.flush(sep='\t\t', publish=False) if not Config().QUERY_JOB_THREAD_ENABLED: QueryLog.add_quick_log('').flush(publish=False) break else: QueryLog.add_log('\n').flush(sep='\t\t', publish=False) if Const.IS_TEST: return
def update_query_jobs(self, auto=False): self.query_jobs = Config().QUERY_JOBS if auto: QueryLog.add_quick_log(QueryLog.MESSAGE_JOBS_DID_CHANGED).flush() self.refresh_jobs() if not Config().is_slave(): jobs_do(self.jobs, 'check_passengers')
def handle_seats(self, allow_seats, ticket_info): for seat in allow_seats: # 检查座位是否有票 self.set_seat(seat) ticket_of_seat = ticket_info[self.current_seat] if not self.is_has_ticket_by_seat(ticket_of_seat): # 座位是否有效 continue QueryLog.print_ticket_seat_available( left_date=self.get_info_of_left_date(), train_number=self.get_info_of_train_number(), seat_type=seat, rest_num=ticket_of_seat) if not self.is_member_number_valid(ticket_of_seat): # 乘车人数是否有效 if self.allow_less_member: self.member_num_take = int(ticket_of_seat) QueryLog.print_ticket_num_less_than_specified( ticket_of_seat, self) else: QueryLog.add_quick_log( QueryLog. MESSAGE_GIVE_UP_CHANCE_CAUSE_TICKET_NUM_LESS_THAN_SPECIFIED ).flush() continue if Const.IS_TEST: return # 检查完成 开始提交订单 QueryLog.print_ticket_available( left_date=self.get_info_of_left_date(), train_number=self.get_info_of_train_number(), rest_num=ticket_of_seat) self.check_passengers() order = Order(user=self.get_user(), query=self) order.order()
def check_passengers(self): if not self.passengers: QueryLog.add_quick_log(QueryLog.MESSAGE_CHECK_PASSENGERS.format(self.job_name)).flush() passengers = User.get_passenger_for_members(self.members, self.account_key) if passengers: self.set_passengers(passengers) else: # 退出当前查询任务 self.destroy() return True
def destroy(self): """ 退出任务 :return: """ from py12306.query.query import Query self.is_alive = False QueryLog.add_quick_log(QueryLog.MESSAGE_QUERY_JOB_BEING_DESTROY.format(self.job_name)).flush() # sys.exit(1) # 无法退出线程... # 手动移出jobs 防止单线程死循环 index = Query().jobs.index(self) Query().jobs.pop(index)
def get_query_api_type(cls): import re self = cls() if self.api_type: return self.api_type response = self.session.get(API_QUERY_INIT_PAGE) if response.status_code == 200: res = re.search(r'var CLeftTicketUrl = \'(.*)\';', response.text) try: self.api_type = res.group(1) except IndexError: pass if not self.api_type: QueryLog.add_quick_log('查询地址获取失败, 正在重新获取...').flush() sleep(1) return cls.get_query_api_type()
def judge_date_legal(self, date): date_now = datetime.datetime.now() date_query = datetime.datetime.strptime(str(date), "%Y-%m-%d") diff = (date_query - date_now).days if date_now.day == date_query.day: diff = 0 if diff < 0: msg = '乘车日期错误,比当前时间还早!!' QueryLog.add_quick_log(msg).flush(publish=False) raise RuntimeError(msg) elif diff > self.max_buy_time: msg = '乘车日期错误,超出一个月预售期!!' QueryLog.add_quick_log(msg).flush(publish=False) raise RuntimeError(msg) else: pass
def start(self): """ 处理单个任务 根据日期循环查询 展示处理时间 :param job: :return: """ QueryLog.print_job_start() for date in self.left_dates: self.left_date = date response = self.query_by_date(date) self.handle_response(response) self.safe_stay() if is_main_thread(): QueryLog.flush(sep='\t\t') if is_main_thread(): QueryLog.add_quick_log('').flush() else: QueryLog.add_log('\n').flush(sep='\t\t')
def handle_seats(self, allow_seats, ticket_info): for seat in allow_seats: # 检查座位是否有票 self.set_seat(seat) ticket_of_seat = ticket_info[self.current_seat] if not self.is_has_ticket_by_seat(ticket_of_seat): # 座位是否有效 continue QueryLog.print_ticket_seat_available(left_date=self.get_info_of_left_date(), train_number=self.get_info_of_train_number(), seat_type=seat, rest_num=ticket_of_seat) if not self.is_member_number_valid(ticket_of_seat): # 乘车人数是否有效 if self.allow_less_member: self.member_num_take = int(ticket_of_seat) QueryLog.print_ticket_num_less_than_specified(ticket_of_seat, self) else: QueryLog.add_quick_log( QueryLog.MESSAGE_GIVE_UP_CHANCE_CAUSE_TICKET_NUM_LESS_THAN_SPECIFIED).flush() continue if Const.IS_TEST: return # 检查完成 开始提交订单 QueryLog.print_ticket_available(left_date=self.get_info_of_left_date(), train_number=self.get_info_of_train_number(), rest_num=ticket_of_seat) if User.is_empty(): QueryLog.add_quick_log(QueryLog.MESSAGE_USER_IS_EMPTY_WHEN_DO_ORDER.format(self.retry_time)) return stay_second(self.retry_time) order_result = False user = self.get_user() if not user: QueryLog.add_quick_log(QueryLog.MESSAGE_ORDER_USER_IS_EMPTY.format(self.retry_time)) return stay_second(self.retry_time) lock_id = Cluster.KEY_LOCK_DO_ORDER + '_' + user.key if Config().is_cluster_enabled(): if self.cluster.get_lock(lock_id, Cluster.lock_do_order_time, {'node': self.cluster.node_name}): # 获得下单锁 order_result = self.do_order(user) if not order_result: # 下单失败,解锁 self.cluster.release_lock(lock_id) else: QueryLog.add_quick_log( QueryLog.MESSAGE_SKIP_ORDER.format(self.cluster.get_lock_info(lock_id).get('node'), user.user_name)) stay_second(self.retry_time) # 防止过多重复 else: order_result = self.do_order(user) # 任务已成功 通知集群停止任务 if order_result: Event().job_destroy({'name': self.job_name})
def check_passengers(self): if not self.passengers: QueryLog.add_quick_log(QueryLog.MESSAGE_CHECK_PASSENGERS).flush() self.set_passengers( User.get_passenger_for_members(self.members, self.account_key)) return True
def update_query_jobs(self, auto=False): self.query_jobs = Config().QUERY_JOBS if auto: QueryLog.add_quick_log(QueryLog.MESSAGE_JOBS_DID_CHANGED).flush() self.refresh_jobs()