增加 cdn 查询
This commit is contained in:
2220
data/cdn.txt
Normal file
2220
data/cdn.txt
Normal file
File diff suppressed because it is too large
Load Diff
2
main.py
2
main.py
@@ -2,6 +2,7 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from py12306.app import *
|
from py12306.app import *
|
||||||
|
from py12306.helpers.cdn import Cdn
|
||||||
from py12306.log.common_log import CommonLog
|
from py12306.log.common_log import CommonLog
|
||||||
from py12306.query.query import Query
|
from py12306.query.query import Query
|
||||||
from py12306.user.user import User
|
from py12306.user.user import User
|
||||||
@@ -20,6 +21,7 @@ def main():
|
|||||||
|
|
||||||
####### 运行任务
|
####### 运行任务
|
||||||
Web.run()
|
Web.run()
|
||||||
|
Cdn.run()
|
||||||
User.run()
|
User.run()
|
||||||
Query.run()
|
Query.run()
|
||||||
if not Const.IS_TEST:
|
if not Const.IS_TEST:
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ class Cluster():
|
|||||||
KEY_USER_LAST_HEARTBEAT = KEY_PREFIX + 'user_last_heartbeat'
|
KEY_USER_LAST_HEARTBEAT = KEY_PREFIX + 'user_last_heartbeat'
|
||||||
KEY_NODES_ALIVE = KEY_PREFIX + 'nodes_alive'
|
KEY_NODES_ALIVE = KEY_PREFIX + 'nodes_alive'
|
||||||
|
|
||||||
|
KEY_CDN_AVAILABLE_ITEMS = KEY_PREFIX + 'cdn_available_items'
|
||||||
|
KEY_CDN_LAST_CHECK_AT = KEY_PREFIX + 'cdn_last_check_at'
|
||||||
|
|
||||||
# 锁
|
# 锁
|
||||||
KEY_LOCK_INIT_USER = KEY_PREFIX + 'lock_init_user' # 暂未使用
|
KEY_LOCK_INIT_USER = KEY_PREFIX + 'lock_init_user' # 暂未使用
|
||||||
KEY_LOCK_DO_ORDER = KEY_PREFIX + 'lock_do_order' # 订单锁
|
KEY_LOCK_DO_ORDER = KEY_PREFIX + 'lock_do_order' # 订单锁
|
||||||
|
|||||||
@@ -82,6 +82,11 @@ class Config:
|
|||||||
WEB_PORT = 8080
|
WEB_PORT = 8080
|
||||||
WEB_ENTER_HTML_PATH = PROJECT_DIR + 'py12306/web/static/index.html'
|
WEB_ENTER_HTML_PATH = PROJECT_DIR + 'py12306/web/static/index.html'
|
||||||
|
|
||||||
|
# CDN
|
||||||
|
CDN_ENABLED = 0
|
||||||
|
CDN_ITEM_FILE = PROJECT_DIR + 'data/cdn.txt'
|
||||||
|
CDN_ENABLED_AVAILABLE_ITEM_FILE = QUERY_DATA_DIR + 'available.json'
|
||||||
|
|
||||||
envs = []
|
envs = []
|
||||||
retry_time = 5
|
retry_time = 5
|
||||||
last_modify_time = 0
|
last_modify_time = 0
|
||||||
@@ -164,18 +169,22 @@ class Config:
|
|||||||
if envs == self.envs: return
|
if envs == self.envs: return
|
||||||
from py12306.query.query import Query
|
from py12306.query.query import Query
|
||||||
from py12306.user.user import User
|
from py12306.user.user import User
|
||||||
|
from py12306.helpers.cdn import Cdn
|
||||||
|
self.envs = envs
|
||||||
for key, value in envs:
|
for key, value in envs:
|
||||||
if key in self.disallow_update_configs: continue
|
if key in self.disallow_update_configs: continue
|
||||||
if value != -1:
|
if value != -1:
|
||||||
old = getattr(self, key)
|
old = getattr(self, key)
|
||||||
setattr(self, key, value)
|
setattr(self, key, value)
|
||||||
if not first:
|
if not first and old != value:
|
||||||
if key == 'USER_ACCOUNTS' and old != value:
|
if key == 'USER_ACCOUNTS':
|
||||||
User().update_user_accounts(auto=True, old=old)
|
User().update_user_accounts(auto=True, old=old)
|
||||||
elif key == 'QUERY_JOBS' and old != value:
|
elif key == 'QUERY_JOBS':
|
||||||
Query().update_query_jobs(auto=True) # 任务修改
|
Query().update_query_jobs(auto=True) # 任务修改
|
||||||
elif key == 'QUERY_INTERVAL' and old != value:
|
elif key == 'QUERY_INTERVAL':
|
||||||
Query().update_query_interval(auto=True)
|
Query().update_query_interval(auto=True)
|
||||||
|
elif key == 'CDN_ENABLED':
|
||||||
|
Cdn().update_cdn_status(auto=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_master(): # 是不是 主
|
def is_master(): # 是不是 主
|
||||||
@@ -190,20 +199,16 @@ class Config:
|
|||||||
def is_cluster_enabled():
|
def is_cluster_enabled():
|
||||||
return Config().CLUSTER_ENABLED
|
return Config().CLUSTER_ENABLED
|
||||||
|
|
||||||
# @staticmethod
|
@staticmethod
|
||||||
# def get_members():
|
def is_cdn_enabled():
|
||||||
# members = []
|
return Config().CDN_ENABLED
|
||||||
# for name, value in vars(Config).items():
|
|
||||||
# if name.isupper():
|
|
||||||
# members.append(([name, value]))
|
|
||||||
# return members
|
|
||||||
|
|
||||||
|
|
||||||
class EnvLoader:
|
class EnvLoader:
|
||||||
envs = []
|
envs = []
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.envs = [] # 不是单例不初始化怎么还会有值
|
self.envs = []
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_with_file(cls, file):
|
def load_with_file(cls, file):
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
# 查询余票
|
# 查询余票
|
||||||
import time
|
import time
|
||||||
|
|
||||||
BASE_URL_OF_12306 = 'https://kyfw.12306.cn'
|
HOST_URL_OF_12306 = 'kyfw.12306.cn'
|
||||||
|
BASE_URL_OF_12306 = 'https://' + HOST_URL_OF_12306
|
||||||
|
|
||||||
LEFT_TICKETS = {
|
LEFT_TICKETS = {
|
||||||
"url": BASE_URL_OF_12306 + "/otn/{type}?leftTicketDTO.train_date={left_date}&leftTicketDTO.from_station={left_station}&leftTicketDTO.to_station={arrive_station}&purpose_codes=ADULT",
|
"url": BASE_URL_OF_12306 + "/otn/{type}?leftTicketDTO.train_date={left_date}&leftTicketDTO.from_station={left_station}&leftTicketDTO.to_station={arrive_station}&purpose_codes=ADULT",
|
||||||
@@ -46,3 +47,5 @@ API_NOTIFICATION_BY_VOICE_CODE = 'http://ali-voice.showapi.com/sendVoice?'
|
|||||||
|
|
||||||
API_FREE_CODE_QCR_API = 'http://60.205.200.159/api'
|
API_FREE_CODE_QCR_API = 'http://60.205.200.159/api'
|
||||||
API_FREE_CODE_QCR_API_CHECK = 'http://check.huochepiao.360.cn/img_vcode'
|
API_FREE_CODE_QCR_API_CHECK = 'http://check.huochepiao.360.cn/img_vcode'
|
||||||
|
|
||||||
|
API_CHECK_CDN_AVAILABLE = 'https://{}/otn/dynamicJs/omseuuq'
|
||||||
|
|||||||
231
py12306/helpers/cdn.py
Normal file
231
py12306/helpers/cdn.py
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
import random
|
||||||
|
import json
|
||||||
|
from datetime import timedelta
|
||||||
|
from os import path
|
||||||
|
|
||||||
|
from py12306.cluster.cluster import Cluster
|
||||||
|
from py12306.config import Config
|
||||||
|
from py12306.app import app_available_check
|
||||||
|
from py12306.helpers.api import API_CHECK_CDN_AVAILABLE, HOST_URL_OF_12306
|
||||||
|
from py12306.helpers.func import *
|
||||||
|
from py12306.helpers.request import Request
|
||||||
|
from py12306.log.common_log import CommonLog
|
||||||
|
|
||||||
|
|
||||||
|
@singleton
|
||||||
|
class Cdn:
|
||||||
|
"""
|
||||||
|
CDN 管理
|
||||||
|
"""
|
||||||
|
items = []
|
||||||
|
available_items = []
|
||||||
|
unavailable_items = []
|
||||||
|
recheck_available_items = []
|
||||||
|
recheck_unavailable_items = []
|
||||||
|
retry_time = 3
|
||||||
|
is_ready = False
|
||||||
|
is_finished = False
|
||||||
|
is_ready_num = 10 # 当可用超过 10,已准备好
|
||||||
|
is_alive = True
|
||||||
|
is_recheck = False
|
||||||
|
|
||||||
|
safe_stay_time = 0.2
|
||||||
|
retry_num = 1
|
||||||
|
thread_num = 8
|
||||||
|
check_time_out = 3
|
||||||
|
|
||||||
|
last_check_at = 0
|
||||||
|
save_second = 5
|
||||||
|
check_keep_second = 60 * 60 * 24
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.cluster = Cluster()
|
||||||
|
create_thread_and_run(self, 'watch_cdn', False)
|
||||||
|
|
||||||
|
def init_data(self):
|
||||||
|
self.items = []
|
||||||
|
self.available_items = []
|
||||||
|
self.unavailable_items = []
|
||||||
|
self.is_finished = False
|
||||||
|
self.is_ready = False
|
||||||
|
self.is_recheck = False
|
||||||
|
|
||||||
|
def update_cdn_status(self, auto=False):
|
||||||
|
if auto:
|
||||||
|
if Config().is_cdn_enabled():
|
||||||
|
self.run()
|
||||||
|
else:
|
||||||
|
self.destroy()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def run(cls):
|
||||||
|
self = cls()
|
||||||
|
app_available_check()
|
||||||
|
self.is_alive = True
|
||||||
|
self.start()
|
||||||
|
pass
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
if not Config.is_cdn_enabled() or Config().is_slave(): return
|
||||||
|
self.load_items()
|
||||||
|
CommonLog.add_quick_log(CommonLog.MESSAGE_CDN_START_TO_CHECK.format(len(self.items))).flush()
|
||||||
|
self.restore_items()
|
||||||
|
for i in range(self.thread_num): # 多线程
|
||||||
|
create_thread_and_run(jobs=self, callback_name='check_available', wait=Const.IS_TEST)
|
||||||
|
|
||||||
|
def load_items(self):
|
||||||
|
with open(Config().CDN_ITEM_FILE, encoding='utf-8') as f:
|
||||||
|
for line, val in enumerate(f):
|
||||||
|
self.items.append(val.rstrip('\n'))
|
||||||
|
|
||||||
|
def restore_items(self):
|
||||||
|
"""
|
||||||
|
恢复已有数据
|
||||||
|
:return: bool
|
||||||
|
"""
|
||||||
|
result = False
|
||||||
|
if path.exists(Config().CDN_ENABLED_AVAILABLE_ITEM_FILE):
|
||||||
|
with open(Config().CDN_ENABLED_AVAILABLE_ITEM_FILE, encoding='utf-8') as f:
|
||||||
|
result = f.read()
|
||||||
|
try:
|
||||||
|
result = json.loads(result)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
# if Config.is_cluster_enabled(): # 集群不用同步 cdn
|
||||||
|
# result = self.get_data_from_cluster()
|
||||||
|
|
||||||
|
if result:
|
||||||
|
self.last_check_at = result.get('last_check_at', '')
|
||||||
|
if self.last_check_at: self.last_check_at = str_to_time(self.last_check_at)
|
||||||
|
self.available_items = result.get('items', [])
|
||||||
|
self.unavailable_items = result.get('fail_items', [])
|
||||||
|
CommonLog.add_quick_log(CommonLog.MESSAGE_CDN_RESTORE_SUCCESS.format(self.last_check_at,
|
||||||
|
self.last_check_at + timedelta(
|
||||||
|
seconds=self.check_keep_second))).flush()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
# def get_data_from_cluster(self):
|
||||||
|
# available_items = self.cluster.session.smembers(Cluster.KEY_CDN_AVAILABLE_ITEMS)
|
||||||
|
# last_time = self.cluster.session.get(Cluster.KEY_CDN_LAST_CHECK_AT, '')
|
||||||
|
# if available_items and last_time:
|
||||||
|
# return {'items': available_items, 'last_check_at': last_time}
|
||||||
|
# return False
|
||||||
|
|
||||||
|
def is_need_to_recheck(self):
|
||||||
|
"""
|
||||||
|
是否需要重新检查 cdn
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if self.last_check_at and (
|
||||||
|
time_now() - self.last_check_at).seconds > self.check_keep_second:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_unchecked_item(self):
|
||||||
|
if not self.is_recheck:
|
||||||
|
items = list(set(self.items) - set(self.available_items) - set(self.unavailable_items))
|
||||||
|
else:
|
||||||
|
items = list(set(self.items) - set(self.recheck_available_items) - set(self.recheck_unavailable_items))
|
||||||
|
if items: return random.choice(items)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def check_available(self):
|
||||||
|
while True and self.is_alive:
|
||||||
|
item = self.get_unchecked_item()
|
||||||
|
if not item: return self.check_did_finished()
|
||||||
|
self.check_item_available(item)
|
||||||
|
|
||||||
|
def watch_cdn(self):
|
||||||
|
"""
|
||||||
|
监控 cdn 状态,自动重新检测
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
while True:
|
||||||
|
if self.is_alive and not self.is_recheck and self.is_need_to_recheck(): # 重新检测
|
||||||
|
self.is_recheck = True
|
||||||
|
self.is_finished = False
|
||||||
|
CommonLog.add_quick_log(
|
||||||
|
CommonLog.MESSAGE_CDN_START_TO_RECHECK.format(len(self.items), time_now())).flush()
|
||||||
|
for i in range(self.thread_num): # 多线程
|
||||||
|
create_thread_and_run(jobs=self, callback_name='check_available', wait=Const.IS_TEST)
|
||||||
|
stay_second(self.retry_num)
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
|
"""
|
||||||
|
关闭 CDN
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
CommonLog.add_quick_log(CommonLog.MESSAGE_CDN_CLOSED).flush()
|
||||||
|
self.is_alive = False
|
||||||
|
self.init_data()
|
||||||
|
|
||||||
|
def check_item_available(self, item, try_num=0):
|
||||||
|
session = Request()
|
||||||
|
response = session.get(API_CHECK_CDN_AVAILABLE.format(item), headers={'Host': HOST_URL_OF_12306},
|
||||||
|
timeout=self.check_time_out,
|
||||||
|
verify=False)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
if not self.is_recheck:
|
||||||
|
self.available_items.append(item)
|
||||||
|
else:
|
||||||
|
self.recheck_available_items.append(item)
|
||||||
|
if not self.is_ready: self.check_is_ready()
|
||||||
|
elif try_num < self.retry_num: # 重试
|
||||||
|
stay_second(self.safe_stay_time)
|
||||||
|
return self.check_item_available(item, try_num + 1)
|
||||||
|
else:
|
||||||
|
if not self.is_recheck:
|
||||||
|
self.unavailable_items.append(item)
|
||||||
|
else:
|
||||||
|
self.recheck_unavailable_items.append(item)
|
||||||
|
if not self.is_recheck and (
|
||||||
|
not self.last_check_at or (time_now() - self.last_check_at).seconds > self.save_second):
|
||||||
|
self.save_available_items()
|
||||||
|
stay_second(self.safe_stay_time)
|
||||||
|
|
||||||
|
def check_did_finished(self):
|
||||||
|
self.is_ready = True
|
||||||
|
if not self.is_finished:
|
||||||
|
self.is_finished = True
|
||||||
|
if self.is_recheck:
|
||||||
|
self.is_recheck = False
|
||||||
|
self.available_items = self.recheck_available_items
|
||||||
|
self.unavailable_items = self.recheck_unavailable_items
|
||||||
|
self.recheck_available_items = []
|
||||||
|
self.recheck_unavailable_items = []
|
||||||
|
CommonLog.add_quick_log(CommonLog.MESSAGE_CDN_CHECKED_SUCCESS.format(len(self.available_items))).flush()
|
||||||
|
self.save_available_items()
|
||||||
|
|
||||||
|
def save_available_items(self):
|
||||||
|
self.last_check_at = time_now()
|
||||||
|
data = {'items': self.available_items, 'fail_items': self.unavailable_items,
|
||||||
|
'last_check_at': str(self.last_check_at)}
|
||||||
|
with open(Config().CDN_ENABLED_AVAILABLE_ITEM_FILE, 'w') as f:
|
||||||
|
f.write(json.dumps(data))
|
||||||
|
|
||||||
|
# if Config.is_master():
|
||||||
|
# self.cluster.session.sadd(Cluster.KEY_CDN_AVAILABLE_ITEMS, self.available_items)
|
||||||
|
# self.cluster.session.set(Cluster.KEY_CDN_LAST_CHECK_AT, time_now())
|
||||||
|
|
||||||
|
def check_is_ready(self):
|
||||||
|
if len(self.available_items) > self.is_ready_num:
|
||||||
|
self.is_ready = True
|
||||||
|
else:
|
||||||
|
self.is_ready = False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cdn(cls):
|
||||||
|
self = cls()
|
||||||
|
if self.is_ready:
|
||||||
|
return random.choice(self.available_items)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# Const.IS_TEST = True
|
||||||
|
Cdn.run()
|
||||||
|
while not Cdn().is_finished:
|
||||||
|
stay_second(1)
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
|
import requests
|
||||||
from requests.exceptions import *
|
from requests.exceptions import *
|
||||||
|
|
||||||
from py12306.helpers.func import *
|
from py12306.helpers.func import *
|
||||||
from requests_html import HTMLSession, HTMLResponse
|
from requests_html import HTMLSession, HTMLResponse
|
||||||
|
|
||||||
|
requests.packages.urllib3.disable_warnings()
|
||||||
|
|
||||||
|
|
||||||
class Request(HTMLSession):
|
class Request(HTMLSession):
|
||||||
"""
|
"""
|
||||||
@@ -57,3 +60,11 @@ class Request(HTMLSession):
|
|||||||
response.status_code = 500
|
response.status_code = 500
|
||||||
expand_class(response, 'json', Request.json)
|
expand_class(response, 'json', Request.json)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
def cdn_request(self, url: str, cdn=None, method='GET', **kwargs):
|
||||||
|
from py12306.helpers.api import HOST_URL_OF_12306
|
||||||
|
from py12306.helpers.cdn import Cdn
|
||||||
|
if not cdn: cdn = Cdn.get_cdn()
|
||||||
|
url = url.replace(HOST_URL_OF_12306, cdn)
|
||||||
|
|
||||||
|
return self.request(method,url, headers={'Host': HOST_URL_OF_12306}, verify=False, **kwargs)
|
||||||
|
|||||||
@@ -49,6 +49,12 @@ class CommonLog(BaseLog):
|
|||||||
|
|
||||||
MESSAGE_RESPONSE_EMPTY_ERROR = '网络错误'
|
MESSAGE_RESPONSE_EMPTY_ERROR = '网络错误'
|
||||||
|
|
||||||
|
MESSAGE_CDN_START_TO_CHECK = '正在筛选 {} 个 CDN...'
|
||||||
|
MESSAGE_CDN_START_TO_RECHECK = '正在重新筛选 {} 个 CDN...当前时间 {}\n'
|
||||||
|
MESSAGE_CDN_RESTORE_SUCCESS = 'CDN 恢复成功,上次检测 {},下次检测 {}\n'
|
||||||
|
MESSAGE_CDN_CHECKED_SUCCESS = '# CDN 检测完成,可用 CDN {} #\n'
|
||||||
|
MESSAGE_CDN_CLOSED = '# CDN 已关闭 #'
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.init_data()
|
self.init_data()
|
||||||
@@ -82,13 +88,16 @@ class CommonLog(BaseLog):
|
|||||||
disable = '未开启'
|
disable = '未开启'
|
||||||
self.add_quick_log('**** 当前配置 ****')
|
self.add_quick_log('**** 当前配置 ****')
|
||||||
self.add_quick_log('多线程查询: {}'.format(get_true_false_text(Config().QUERY_JOB_THREAD_ENABLED, enable, disable)))
|
self.add_quick_log('多线程查询: {}'.format(get_true_false_text(Config().QUERY_JOB_THREAD_ENABLED, enable, disable)))
|
||||||
|
self.add_quick_log('CDN 状态: {}'.format(get_true_false_text(Config().CDN_ENABLED, enable, disable))).flush()
|
||||||
|
self.add_quick_log('通知状态:')
|
||||||
self.add_quick_log(
|
self.add_quick_log(
|
||||||
'语音验证码: {}'.format(get_true_false_text(Config().NOTIFICATION_BY_VOICE_CODE, enable, disable)))
|
'语音验证码: {}'.format(get_true_false_text(Config().NOTIFICATION_BY_VOICE_CODE, enable, disable)))
|
||||||
self.add_quick_log('邮件通知: {}'.format(get_true_false_text(Config().EMAIL_ENABLED, enable, disable)))
|
self.add_quick_log('邮件通知: {}'.format(get_true_false_text(Config().EMAIL_ENABLED, enable, disable)))
|
||||||
self.add_quick_log('钉钉通知: {}'.format(get_true_false_text(Config().DINGTALK_ENABLED, enable, disable)))
|
self.add_quick_log('钉钉通知: {}'.format(get_true_false_text(Config().DINGTALK_ENABLED, enable, disable)))
|
||||||
self.add_quick_log('Telegram通知: {}'.format(get_true_false_text(Config().TELEGRAM_ENABLED, enable, disable)))
|
self.add_quick_log('Telegram通知: {}'.format(get_true_false_text(Config().TELEGRAM_ENABLED, enable, disable)))
|
||||||
self.add_quick_log('ServerChan通知: {}'.format(get_true_false_text(Config().SERVERCHAN_ENABLED, enable, disable)))
|
self.add_quick_log('ServerChan通知: {}'.format(get_true_false_text(Config().SERVERCHAN_ENABLED, enable, disable)))
|
||||||
self.add_quick_log('PushBear通知: {}'.format(get_true_false_text(Config().PUSHBEAR_ENABLED, enable, disable)))
|
self.add_quick_log(
|
||||||
|
'PushBear通知: {}'.format(get_true_false_text(Config().PUSHBEAR_ENABLED, enable, disable))).flush(sep='\t\t')
|
||||||
self.add_quick_log('查询间隔: {} 秒'.format(Config().QUERY_INTERVAL))
|
self.add_quick_log('查询间隔: {} 秒'.format(Config().QUERY_INTERVAL))
|
||||||
self.add_quick_log('用户心跳检测间隔: {} 秒'.format(Config().USER_HEARTBEAT_INTERVAL))
|
self.add_quick_log('用户心跳检测间隔: {} 秒'.format(Config().USER_HEARTBEAT_INTERVAL))
|
||||||
self.add_quick_log('WEB 管理页面: {}'.format(get_true_false_text(Config().WEB_ENABLE, enable, disable)))
|
self.add_quick_log('WEB 管理页面: {}'.format(get_true_false_text(Config().WEB_ENABLE, enable, disable)))
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ class QueryLog(BaseLog):
|
|||||||
# self.add_quick_log('加载status.json失败, 文件内容为: {}.'.format(repr(result)))
|
# self.add_quick_log('加载status.json失败, 文件内容为: {}.'.format(repr(result)))
|
||||||
# self.flush() # 这里可以用不用提示
|
# self.flush() # 这里可以用不用提示
|
||||||
|
|
||||||
|
|
||||||
if Config.is_cluster_enabled():
|
if Config.is_cluster_enabled():
|
||||||
result = self.get_data_from_cluster()
|
result = self.get_data_from_cluster()
|
||||||
|
|
||||||
@@ -157,19 +156,23 @@ class QueryLog(BaseLog):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def print_job_start(cls, job_name):
|
def print_job_start(cls, job_name):
|
||||||
self = cls()
|
self = cls()
|
||||||
message = '=== 正在进行第 {query_count} 次查询 {job_name} === {time}'.format(
|
message = '>> 第 {query_count} 次查询 {job_name} {time}'.format(
|
||||||
query_count=int(self.data.get('query_count', 0)) + 1,
|
query_count=int(self.data.get('query_count', 0)) + 1,
|
||||||
job_name=job_name, time=datetime.datetime.now())
|
job_name=job_name, time=time_now().strftime("%Y-%m-%d %H:%M:%S"))
|
||||||
self.add_log(message)
|
self.add_log(message)
|
||||||
self.refresh_data()
|
self.refresh_data()
|
||||||
if is_main_thread():
|
if is_main_thread():
|
||||||
self.flush(publish=False)
|
self.flush(publish=False)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_query_time_log(cls, start, end, is_cdn):
|
||||||
|
return cls().add_log(('*' if is_cdn else '') + '耗时 %.2f' % (end - start))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_stay_log(cls, second):
|
def add_stay_log(cls, second):
|
||||||
self = cls()
|
self = cls()
|
||||||
self.add_log('安全停留 {}'.format(second))
|
self.add_log('停留 {}'.format(second))
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def print_data_restored(self):
|
def print_data_restored(self):
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class Order:
|
|||||||
|
|
||||||
is_need_auth_code = False
|
is_need_auth_code = False
|
||||||
|
|
||||||
max_queue_wait = 120
|
max_queue_wait = 60 * 5 # 最大排队时长
|
||||||
current_queue_wait = 0
|
current_queue_wait = 0
|
||||||
retry_time = 3
|
retry_time = 3
|
||||||
wait_queue_interval = 3
|
wait_queue_interval = 3
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ class Job:
|
|||||||
query = None
|
query = None
|
||||||
cluster = None
|
cluster = None
|
||||||
ticket_info = {}
|
ticket_info = {}
|
||||||
|
is_cdn = False
|
||||||
|
query_time_out = 3
|
||||||
INDEX_TICKET_NUM = 11
|
INDEX_TICKET_NUM = 11
|
||||||
INDEX_TRAIN_NUMBER = 3
|
INDEX_TRAIN_NUMBER = 3
|
||||||
INDEX_TRAIN_NO = 2
|
INDEX_TRAIN_NO = 2
|
||||||
@@ -98,7 +100,10 @@ class Job:
|
|||||||
self.refresh_station(station)
|
self.refresh_station(station)
|
||||||
for date in self.left_dates:
|
for date in self.left_dates:
|
||||||
self.left_date = date
|
self.left_date = date
|
||||||
|
tmp_start_time = time.time()
|
||||||
response = self.query_by_date(date)
|
response = self.query_by_date(date)
|
||||||
|
tmp_end_time = time.time() # 耗时
|
||||||
|
QueryLog.add_query_time_log(tmp_start_time, tmp_end_time, is_cdn=self.is_cdn)
|
||||||
self.handle_response(response)
|
self.handle_response(response)
|
||||||
if not self.is_alive: return
|
if not self.is_alive: return
|
||||||
self.safe_stay()
|
self.safe_stay()
|
||||||
@@ -116,13 +121,17 @@ class Job:
|
|||||||
通过日期进行查询
|
通过日期进行查询
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
from py12306.helpers.cdn import Cdn
|
||||||
QueryLog.add_log(('\n' if not is_main_thread() else '') + QueryLog.MESSAGE_QUERY_START_BY_DATE.format(date,
|
QueryLog.add_log(('\n' if not is_main_thread() else '') + QueryLog.MESSAGE_QUERY_START_BY_DATE.format(date,
|
||||||
self.left_station,
|
self.left_station,
|
||||||
self.arrive_station))
|
self.arrive_station))
|
||||||
url = LEFT_TICKETS.get('url').format(left_date=date, left_station=self.left_station_code,
|
url = LEFT_TICKETS.get('url').format(left_date=date, left_station=self.left_station_code,
|
||||||
arrive_station=self.arrive_station_code, type='leftTicket/queryZ')
|
arrive_station=self.arrive_station_code, type='leftTicket/queryZ')
|
||||||
|
if Config.is_cdn_enabled() and Cdn().is_ready:
|
||||||
return self.query.session.get(url)
|
self.is_cdn = True
|
||||||
|
return self.query.session.cdn_request(url, timeout=self.query_time_out)
|
||||||
|
self.is_cdn = False
|
||||||
|
return self.query.session.get(url, timeout=self.query_time_out)
|
||||||
|
|
||||||
def handle_response(self, response):
|
def handle_response(self, response):
|
||||||
"""
|
"""
|
||||||
@@ -141,8 +150,7 @@ class Job:
|
|||||||
self.ticket_info = ticket_info = result.split('|')
|
self.ticket_info = ticket_info = result.split('|')
|
||||||
if not self.is_trains_number_valid(ticket_info): # 车次是否有效
|
if not self.is_trains_number_valid(ticket_info): # 车次是否有效
|
||||||
continue
|
continue
|
||||||
QueryLog.add_log(QueryLog.MESSAGE_QUERY_LOG_OF_EVERY_TRAIN.format(self.get_info_of_train_number(),
|
QueryLog.add_log(QueryLog.MESSAGE_QUERY_LOG_OF_EVERY_TRAIN.format(self.get_info_of_train_number()))
|
||||||
self.get_info_of_ticket_num()))
|
|
||||||
if not self.is_has_ticket(ticket_info):
|
if not self.is_has_ticket(ticket_info):
|
||||||
continue
|
continue
|
||||||
allow_seats = self.allow_seats if self.allow_seats else list(
|
allow_seats = self.allow_seats if self.allow_seats else list(
|
||||||
|
|||||||
Reference in New Issue
Block a user