优化错误处理
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
- [ ] 邮件通知
|
||||
|
||||
## 使用
|
||||
py12306 需要运行 python 3.6 以上版本(其它版本暂未测试)
|
||||
py12306 需要运行在 python 3.6 以上版本(其它版本暂未测试)
|
||||
|
||||
**1. 安装依赖**
|
||||
```bash
|
||||
@@ -57,6 +57,8 @@ python main.py -t -n
|
||||
python main.py
|
||||
```
|
||||
|
||||
## 下单成功图片
|
||||

|
||||
|
||||
## Thanks
|
||||
感谢大佬 [testerSunshine](https://github.com/testerSunshine/12306),借鉴了部分实现
|
||||
|
||||
BIN
data/images/order_success.png
Normal file
BIN
data/images/order_success.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 384 KiB |
@@ -56,3 +56,24 @@ class App:
|
||||
if not cls.check_user_account_is_empty():
|
||||
CommonLog.add_quick_log(CommonLog.MESSAGE_CHECK_EMPTY_USER_ACCOUNT).flush(exit=True)
|
||||
if Const.IS_TEST_NOTIFICATION: cls.test_send_notifications()
|
||||
|
||||
|
||||
# Expand
|
||||
class Dict(dict):
|
||||
def get(self, key, default=None, sep='.'):
|
||||
keys = key.split(sep)
|
||||
for i, key in enumerate(keys):
|
||||
try:
|
||||
value = self[key]
|
||||
if len(keys[i + 1:]) and isinstance(value, Dict):
|
||||
return value.get(sep.join(keys[i + 1:]), default=default, sep=sep)
|
||||
return value
|
||||
except:
|
||||
return self.dict_to_dict(default)
|
||||
|
||||
def __getitem__(self, k):
|
||||
return self.dict_to_dict(super().__getitem__(k))
|
||||
|
||||
@staticmethod
|
||||
def dict_to_dict(value):
|
||||
return Dict(value) if isinstance(value, dict) else value
|
||||
|
||||
@@ -4,11 +4,11 @@ import threading
|
||||
import functools
|
||||
|
||||
from time import sleep
|
||||
from types import MethodType
|
||||
|
||||
from py12306 import config
|
||||
|
||||
|
||||
|
||||
def singleton(cls):
|
||||
"""
|
||||
将一个类作为单例
|
||||
@@ -120,6 +120,13 @@ def sleep_forever_when_in_test():
|
||||
if Const.IS_TEST: sleep_forever()
|
||||
|
||||
|
||||
def expand_class(cls, key, value, keep_old=True):
|
||||
if (keep_old):
|
||||
setattr(cls, 'old_' + key, getattr(cls, key))
|
||||
setattr(cls, key, MethodType(value, cls))
|
||||
return cls
|
||||
|
||||
|
||||
@singleton
|
||||
class Const:
|
||||
IS_TEST = False
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
from requests_html import HTMLSession
|
||||
from py12306.helpers.app import *
|
||||
from py12306.helpers.func import *
|
||||
from requests_html import HTMLSession, HTMLResponse
|
||||
|
||||
|
||||
class Request(HTMLSession):
|
||||
@@ -18,3 +20,27 @@ class Request(HTMLSession):
|
||||
for chunk in response.iter_content(chunk_size=1024):
|
||||
f.write(chunk)
|
||||
return response
|
||||
|
||||
@staticmethod
|
||||
def _handle_response(response, **kwargs) -> HTMLResponse:
|
||||
"""
|
||||
扩充 response
|
||||
:param response:
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
response = HTMLSession._handle_response(response, **kwargs)
|
||||
expand_class(response, 'json', Request.json)
|
||||
return response
|
||||
|
||||
def json(self, default={}):
|
||||
"""
|
||||
重写 json 方法,拦截错误
|
||||
:return:
|
||||
"""
|
||||
from py12306.helpers.app import Dict
|
||||
try:
|
||||
result = self.old_json()
|
||||
return Dict(result)
|
||||
except:
|
||||
return Dict(default)
|
||||
|
||||
@@ -101,9 +101,9 @@ class QueryLog(BaseLog):
|
||||
self = cls()
|
||||
self.add_quick_log('查询余票请求失败')
|
||||
if code:
|
||||
self.add_quick_log('状态码{} '.format(code))
|
||||
self.add_quick_log('状态码 {} '.format(code))
|
||||
if reason:
|
||||
self.add_quick_log('错误原因{} '.format(reason))
|
||||
self.add_quick_log('错误原因 {} '.format(reason))
|
||||
self.flush(sep='\t')
|
||||
return self
|
||||
|
||||
|
||||
@@ -105,6 +105,8 @@ class Order:
|
||||
OrderLog.add_quick_log(OrderLog.MESSAGE_SUBMIT_ORDER_REQUEST_SUCCESS).flush()
|
||||
return True
|
||||
else:
|
||||
if (str(result.get('messages', '')).find('未处理') >= 0): # 未处理订单
|
||||
stay_second(self.retry_time)
|
||||
OrderLog.add_quick_log(
|
||||
OrderLog.MESSAGE_SUBMIT_ORDER_REQUEST_FAIL.format(result.get('messages', '-'))).flush()
|
||||
return False
|
||||
@@ -134,9 +136,9 @@ class Order:
|
||||
}
|
||||
response = self.session.post(API_CHECK_ORDER_INFO, data)
|
||||
result = response.json()
|
||||
if 'data' in result and result['data'].get('submitStatus'): # 成功
|
||||
if result.get('data.submitStatus'): # 成功
|
||||
OrderLog.add_quick_log(OrderLog.MESSAGE_CHECK_ORDER_INFO_SUCCESS).flush()
|
||||
if result['data'].get("ifShowPassCode") != 'N':
|
||||
if result.get('data.ifShowPassCode') != 'N':
|
||||
self.is_need_auth_code = True
|
||||
return True
|
||||
else:
|
||||
@@ -181,7 +183,7 @@ class Order:
|
||||
}
|
||||
response = self.session.post(API_GET_QUEUE_COUNT, data)
|
||||
result = response.json()
|
||||
if 'data' in result and ('countT' in result['data'] or 'ticket' in result['data']): # 成功
|
||||
if result.get('data.countT') or result.get('data.ticket'): # 成功
|
||||
"""
|
||||
"data": {
|
||||
"count": "66",
|
||||
@@ -191,7 +193,7 @@ class Order:
|
||||
"op_1": "true"
|
||||
}
|
||||
"""
|
||||
ticket = result['data']['ticket'].split(',') # 暂不清楚具体作用
|
||||
ticket = result.get('data.ticket').split(',') # 暂不清楚具体作用
|
||||
ticket_number = sum(map(int, ticket))
|
||||
current_position = int(data.get('countT', 0))
|
||||
OrderLog.add_quick_log(
|
||||
@@ -251,13 +253,13 @@ class Order:
|
||||
"submitStatus": true
|
||||
}
|
||||
"""
|
||||
if result['data'].get('submitStatus'): # 成功
|
||||
if result.get('data.submitStatus'): # 成功
|
||||
OrderLog.add_quick_log(OrderLog.MESSAGE_CONFIRM_SINGLE_FOR_QUEUE_SUCCESS).flush()
|
||||
return True
|
||||
else:
|
||||
# 加入小黑屋 TODO
|
||||
OrderLog.add_quick_log(
|
||||
OrderLog.MESSAGE_CONFIRM_SINGLE_FOR_QUEUE_ERROR.format(result['data'].get('errMsg', '-'))).flush()
|
||||
OrderLog.MESSAGE_CONFIRM_SINGLE_FOR_QUEUE_ERROR.format(result.get('data.errMsg', '-'))).flush()
|
||||
else:
|
||||
OrderLog.add_quick_log(OrderLog.MESSAGE_CONFIRM_SINGLE_FOR_QUEUE_FAIL.format(
|
||||
result.get('messages', '-'))).flush()
|
||||
|
||||
@@ -159,11 +159,7 @@ class Job:
|
||||
"""
|
||||
if response.status_code != 200:
|
||||
QueryLog.print_query_error(response.reason, response.status_code)
|
||||
try:
|
||||
result_data = response.json().get('data', {})
|
||||
result = result_data.get('result', [])
|
||||
except:
|
||||
pass # TODO
|
||||
result = response.json().get('data.result')
|
||||
return result if result else False
|
||||
|
||||
def is_has_ticket(self, ticket_info):
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import threading
|
||||
|
||||
from requests_html import HTMLSession
|
||||
|
||||
from py12306.helpers.app import app_available_check
|
||||
from py12306.helpers.func import *
|
||||
from py12306.helpers.request import Request
|
||||
from py12306.log.query_log import QueryLog
|
||||
from py12306.query.job import Job
|
||||
|
||||
@@ -21,7 +21,7 @@ class Query:
|
||||
|
||||
def __init__(self):
|
||||
self.interval = init_interval_by_number(config.QUERY_INTERVAL)
|
||||
self.session = HTMLSession()
|
||||
self.session = Request()
|
||||
|
||||
@classmethod
|
||||
def run(cls):
|
||||
|
||||
@@ -178,10 +178,9 @@ class UserJob:
|
||||
def get_user_info(self):
|
||||
response = self.session.get(API_USER_INFO.get('url'))
|
||||
result = response.json()
|
||||
user_data = result.get('data')
|
||||
if user_data.get('userDTO') and user_data['userDTO'].get('loginUserDTO'):
|
||||
user_data = user_data['userDTO']['loginUserDTO']
|
||||
self.update_user_info({**user_data, **{'user_name': user_data['name']}})
|
||||
user_data = result.get('data.userDTO.loginUserDTO')
|
||||
if user_data:
|
||||
self.update_user_info({**user_data, **{'user_name': user_data.get('name')}})
|
||||
return True
|
||||
return None
|
||||
|
||||
@@ -201,8 +200,8 @@ class UserJob:
|
||||
if self.passengers: return self.passengers
|
||||
response = self.session.post(API_USER_PASSENGERS)
|
||||
result = response.json()
|
||||
if result.get('data') and result.get('data').get('normal_passengers'):
|
||||
self.passengers = result.get('data').get('normal_passengers')
|
||||
if result.get('data.normal_passengers'):
|
||||
self.passengers = result.get('data.normal_passengers')
|
||||
return self.passengers
|
||||
else:
|
||||
UserLog.add_quick_log(
|
||||
|
||||
Reference in New Issue
Block a user