import random import time from requests.exceptions import SSLError from py12306.config import Config from py12306.helpers.OCR import OCR from py12306.helpers.api import * from py12306.helpers.request import Request from py12306.helpers.func import * from py12306.log.common_log import CommonLog from py12306.log.user_log import UserLog class AuthCode: """ 验证码类 """ session = None data_path = None retry_time = 5 def __init__(self, session): self.data_path = Config().RUNTIME_DIR self.session = session @classmethod def get_auth_code(cls, session): self = cls(session) img = self.download_code() position = OCR.get_img_position(img) if not position: # 打码失败 return self.retry_get_auth_code() answer = ','.join(map(str, position)) if not self.check_code(answer): return self.retry_get_auth_code() return position def retry_get_auth_code(self): # TODO 安全次数检测 CommonLog.add_quick_log(CommonLog.MESSAGE_RETRY_AUTH_CODE.format(self.retry_time)).flush() time.sleep(self.retry_time) return self.get_auth_code(self.session) def download_code(self): url = API_AUTH_CODE_BASE64_DOWNLOAD.format(random=random.random()) # code_path = self.data_path + 'code.png' try: UserLog.add_quick_log(UserLog.MESSAGE_DOWNLAODING_THE_CODE).flush() # response = self.session.save_to_file(url, code_path) # TODO 返回错误情况 response = self.session.get(url) result = response.json() if result.get('image'): return result.get('image') raise SSLError('返回数据为空') except SSLError as e: UserLog.add_quick_log( UserLog.MESSAGE_DOWNLAOD_AUTH_CODE_FAIL.format(e, self.retry_time)).flush() time.sleep(self.retry_time) return self.download_code() def check_code(self, answer): """ 校验验证码 :return: """ url = API_AUTH_CODE_CHECK.get('url').format(answer=answer, random=time_int()) response = self.session.get(url) result = response.json() if result.get('result_code') == '4': UserLog.add_quick_log(UserLog.MESSAGE_CODE_AUTH_SUCCESS).flush() return True else: # {'result_message': '验证码校验失败', 'result_code': '5'} UserLog.add_quick_log( UserLog.MESSAGE_CODE_AUTH_FAIL.format(result.get('result_message'))).flush() self.session.cookies.clear_session_cookies() return False if __name__ == '__main__': code_result = AuthCode.get_auth_code()