优化错误处理

This commit is contained in:
Jalin
2019-01-08 16:45:54 +08:00
parent bb136d17ba
commit 054c476c4e
10 changed files with 77 additions and 24 deletions

View File

@@ -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
```
## 下单成功图片
![下单成功图片](./data/images/order_success.png)
## Thanks
感谢大佬 [testerSunshine](https://github.com/testerSunshine/12306),借鉴了部分实现

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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()

View File

@@ -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):

View File

@@ -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):

View File

@@ -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(