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

|
||||||
|
|
||||||
## Thanks
|
## Thanks
|
||||||
感谢大佬 [testerSunshine](https://github.com/testerSunshine/12306),借鉴了部分实现
|
感谢大佬 [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():
|
if not cls.check_user_account_is_empty():
|
||||||
CommonLog.add_quick_log(CommonLog.MESSAGE_CHECK_EMPTY_USER_ACCOUNT).flush(exit=True)
|
CommonLog.add_quick_log(CommonLog.MESSAGE_CHECK_EMPTY_USER_ACCOUNT).flush(exit=True)
|
||||||
if Const.IS_TEST_NOTIFICATION: cls.test_send_notifications()
|
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
|
import functools
|
||||||
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
from types import MethodType
|
||||||
|
|
||||||
from py12306 import config
|
from py12306 import config
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def singleton(cls):
|
def singleton(cls):
|
||||||
"""
|
"""
|
||||||
将一个类作为单例
|
将一个类作为单例
|
||||||
@@ -120,6 +120,13 @@ def sleep_forever_when_in_test():
|
|||||||
if Const.IS_TEST: sleep_forever()
|
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
|
@singleton
|
||||||
class Const:
|
class Const:
|
||||||
IS_TEST = False
|
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):
|
class Request(HTMLSession):
|
||||||
@@ -18,3 +20,27 @@ class Request(HTMLSession):
|
|||||||
for chunk in response.iter_content(chunk_size=1024):
|
for chunk in response.iter_content(chunk_size=1024):
|
||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
return response
|
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 = cls()
|
||||||
self.add_quick_log('查询余票请求失败')
|
self.add_quick_log('查询余票请求失败')
|
||||||
if code:
|
if code:
|
||||||
self.add_quick_log('状态码{} '.format(code))
|
self.add_quick_log('状态码 {} '.format(code))
|
||||||
if reason:
|
if reason:
|
||||||
self.add_quick_log('错误原因{} '.format(reason))
|
self.add_quick_log('错误原因 {} '.format(reason))
|
||||||
self.flush(sep='\t')
|
self.flush(sep='\t')
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,8 @@ class Order:
|
|||||||
OrderLog.add_quick_log(OrderLog.MESSAGE_SUBMIT_ORDER_REQUEST_SUCCESS).flush()
|
OrderLog.add_quick_log(OrderLog.MESSAGE_SUBMIT_ORDER_REQUEST_SUCCESS).flush()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
if (str(result.get('messages', '')).find('未处理') >= 0): # 未处理订单
|
||||||
|
stay_second(self.retry_time)
|
||||||
OrderLog.add_quick_log(
|
OrderLog.add_quick_log(
|
||||||
OrderLog.MESSAGE_SUBMIT_ORDER_REQUEST_FAIL.format(result.get('messages', '-'))).flush()
|
OrderLog.MESSAGE_SUBMIT_ORDER_REQUEST_FAIL.format(result.get('messages', '-'))).flush()
|
||||||
return False
|
return False
|
||||||
@@ -134,9 +136,9 @@ class Order:
|
|||||||
}
|
}
|
||||||
response = self.session.post(API_CHECK_ORDER_INFO, data)
|
response = self.session.post(API_CHECK_ORDER_INFO, data)
|
||||||
result = response.json()
|
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()
|
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
|
self.is_need_auth_code = True
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
@@ -181,7 +183,7 @@ class Order:
|
|||||||
}
|
}
|
||||||
response = self.session.post(API_GET_QUEUE_COUNT, data)
|
response = self.session.post(API_GET_QUEUE_COUNT, data)
|
||||||
result = response.json()
|
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": {
|
"data": {
|
||||||
"count": "66",
|
"count": "66",
|
||||||
@@ -191,7 +193,7 @@ class Order:
|
|||||||
"op_1": "true"
|
"op_1": "true"
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
ticket = result['data']['ticket'].split(',') # 暂不清楚具体作用
|
ticket = result.get('data.ticket').split(',') # 暂不清楚具体作用
|
||||||
ticket_number = sum(map(int, ticket))
|
ticket_number = sum(map(int, ticket))
|
||||||
current_position = int(data.get('countT', 0))
|
current_position = int(data.get('countT', 0))
|
||||||
OrderLog.add_quick_log(
|
OrderLog.add_quick_log(
|
||||||
@@ -251,13 +253,13 @@ class Order:
|
|||||||
"submitStatus": true
|
"submitStatus": true
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
if result['data'].get('submitStatus'): # 成功
|
if result.get('data.submitStatus'): # 成功
|
||||||
OrderLog.add_quick_log(OrderLog.MESSAGE_CONFIRM_SINGLE_FOR_QUEUE_SUCCESS).flush()
|
OrderLog.add_quick_log(OrderLog.MESSAGE_CONFIRM_SINGLE_FOR_QUEUE_SUCCESS).flush()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
# 加入小黑屋 TODO
|
# 加入小黑屋 TODO
|
||||||
OrderLog.add_quick_log(
|
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:
|
else:
|
||||||
OrderLog.add_quick_log(OrderLog.MESSAGE_CONFIRM_SINGLE_FOR_QUEUE_FAIL.format(
|
OrderLog.add_quick_log(OrderLog.MESSAGE_CONFIRM_SINGLE_FOR_QUEUE_FAIL.format(
|
||||||
result.get('messages', '-'))).flush()
|
result.get('messages', '-'))).flush()
|
||||||
|
|||||||
@@ -159,11 +159,7 @@ class Job:
|
|||||||
"""
|
"""
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
QueryLog.print_query_error(response.reason, response.status_code)
|
QueryLog.print_query_error(response.reason, response.status_code)
|
||||||
try:
|
result = response.json().get('data.result')
|
||||||
result_data = response.json().get('data', {})
|
|
||||||
result = result_data.get('result', [])
|
|
||||||
except:
|
|
||||||
pass # TODO
|
|
||||||
return result if result else False
|
return result if result else False
|
||||||
|
|
||||||
def is_has_ticket(self, ticket_info):
|
def is_has_ticket(self, ticket_info):
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import threading
|
import threading
|
||||||
|
|
||||||
from requests_html import HTMLSession
|
|
||||||
|
|
||||||
from py12306.helpers.app import app_available_check
|
from py12306.helpers.app import app_available_check
|
||||||
from py12306.helpers.func import *
|
from py12306.helpers.func import *
|
||||||
|
from py12306.helpers.request import Request
|
||||||
from py12306.log.query_log import QueryLog
|
from py12306.log.query_log import QueryLog
|
||||||
from py12306.query.job import Job
|
from py12306.query.job import Job
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ class Query:
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.interval = init_interval_by_number(config.QUERY_INTERVAL)
|
self.interval = init_interval_by_number(config.QUERY_INTERVAL)
|
||||||
self.session = HTMLSession()
|
self.session = Request()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls):
|
def run(cls):
|
||||||
|
|||||||
@@ -178,10 +178,9 @@ class UserJob:
|
|||||||
def get_user_info(self):
|
def get_user_info(self):
|
||||||
response = self.session.get(API_USER_INFO.get('url'))
|
response = self.session.get(API_USER_INFO.get('url'))
|
||||||
result = response.json()
|
result = response.json()
|
||||||
user_data = result.get('data')
|
user_data = result.get('data.userDTO.loginUserDTO')
|
||||||
if user_data.get('userDTO') and user_data['userDTO'].get('loginUserDTO'):
|
if user_data:
|
||||||
user_data = user_data['userDTO']['loginUserDTO']
|
self.update_user_info({**user_data, **{'user_name': user_data.get('name')}})
|
||||||
self.update_user_info({**user_data, **{'user_name': user_data['name']}})
|
|
||||||
return True
|
return True
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -201,8 +200,8 @@ class UserJob:
|
|||||||
if self.passengers: return self.passengers
|
if self.passengers: return self.passengers
|
||||||
response = self.session.post(API_USER_PASSENGERS)
|
response = self.session.post(API_USER_PASSENGERS)
|
||||||
result = response.json()
|
result = response.json()
|
||||||
if result.get('data') and result.get('data').get('normal_passengers'):
|
if result.get('data.normal_passengers'):
|
||||||
self.passengers = result.get('data').get('normal_passengers')
|
self.passengers = result.get('data.normal_passengers')
|
||||||
return self.passengers
|
return self.passengers
|
||||||
else:
|
else:
|
||||||
UserLog.add_quick_log(
|
UserLog.add_quick_log(
|
||||||
|
|||||||
Reference in New Issue
Block a user