账号管理器
| 937 | |
| 938 | # ==================== 账号管理器 ==================== |
| 939 | class AccountManager: |
| 940 | """账号管理器""" |
| 941 | |
| 942 | def __init__(self, account_url: str, account_index: int, config: Config): |
| 943 | self.account_url = account_url |
| 944 | self.account_index = account_index + 1 |
| 945 | self.config = config |
| 946 | self.logger = Logger() |
| 947 | self.proxy_manager = ProxyManager(config.PROXY_API_URL) |
| 948 | |
| 949 | # 登录重试机制(参考顺丰代理.py的实现) |
| 950 | self.login_success = False |
| 951 | self.user_id = None |
| 952 | self.phone = None |
| 953 | self.http_client = None |
| 954 | |
| 955 | retry_count = 0 |
| 956 | while retry_count < MAX_PROXY_RETRIES and not self.login_success: |
| 957 | try: |
| 958 | # 每次重试都重新获取代理和创建HTTP客户端 |
| 959 | self.http_client = SFHttpClient(config, self.proxy_manager) |
| 960 | |
| 961 | # 尝试登录(带超时) |
| 962 | success, self.user_id, self.phone = self.http_client.login(account_url) |
| 963 | |
| 964 | if success: |
| 965 | masked_phone = self.phone[:3] + "*" * 4 + self.phone[7:] |
| 966 | self.logger.user_info(self.account_index, masked_phone) |
| 967 | self.login_success = True |
| 968 | break |
| 969 | else: |
| 970 | if retry_count < MAX_PROXY_RETRIES - 1: |
| 971 | print(f'账号{self.account_index} 登录失败,尝试重新获取代理 ({retry_count + 1}/{MAX_PROXY_RETRIES})') |
| 972 | time.sleep(2) |
| 973 | except Exception as e: |
| 974 | print(f'账号{self.account_index} 登录异常: {str(e)[:100]}') |
| 975 | |
| 976 | retry_count += 1 |
| 977 | |
| 978 | # 如果所有代理重试都失败,记录错误 |
| 979 | if not self.login_success: |
| 980 | self.logger.error(f'账号{self.account_index} 登录失败,已重试{MAX_PROXY_RETRIES}次,所有代理均不可用') |
| 981 | |
| 982 | def run(self) -> Dict[str, Any]: |
| 983 | """运行账号任务 |
| 984 | |
| 985 | Returns: |
| 986 | Dict: 包含账号统计信息的字典 |
| 987 | """ |
| 988 | if not self.login_success: |
| 989 | return { |
| 990 | 'success': False, |
| 991 | 'phone': '', |
| 992 | 'points_before': 0, |
| 993 | 'points_after': 0, |
| 994 | 'points_earned': 0 |
| 995 | } |
| 996 |
no outgoing calls
no test coverage detected