import base64 import json import os import sys import requests def get_vpn_servers(): sub_url = os.getenv("VPN_SUB_URL") if not sub_url: print("Ошибка: Переменная окружения VPN_SUB_URL не задана!") sys.exit(1) headers = { "User-Agent": "Happ/2.1.0 (iPhone; iOS 15.5; Scale/3.00)", "Accept": "*/*", } try: print("Отправка запроса к серверу VPN...") response = requests.get(sub_url, headers=headers, timeout=15) if response.status_code != 200: print(f"Ошибка服务器: Статус {response.status_code}") sys.exit(1) raw_content = response.text.strip() # 1. Проверяем формат JSON try: data = json.loads(raw_content) print("Обнаружен формат JSON.") # Если сервер вернул словарь, ищем ключи. Если вернул сразу список — берем его как есть. if isinstance(data, dict): servers = data.get("data", {}).get("server_user", data) else: servers = data with open("servers.json", "w", encoding="utf-8") as f: json.dump(servers, f, indent=2, ensure_ascii=False) # Выводим количество найденных элементов для наглядности в логах count = len(servers) if isinstance(servers, list) else 1 print( f"Данные успешно сохранены в файл servers.json (Элементов: {count})" ) return except json.JSONDecodeError: # Если не JSON, двигаемся к проверке Base64 pass # 2. Проверяем формат Base64 (на случай изменения выдачи) try: padded_content = raw_content + "=" * (4 - len(raw_content) % 4) decoded_bytes = base64.b64decode(padded_content) decoded_text = decoded_bytes.decode("utf-8", errors="ignore").strip() if any( proto in decoded_text for proto in ["vless://", "vmess://", "ss://", "trojan://"] ): print("Обнаружена Base64 подписка.") with open("servers.txt", "w", encoding="utf-8") as f: f.write(decoded_text) links_list = [ line.strip() for line in decoded_text.splitlines() if line.strip() ] with open("servers.json", "w", encoding="utf-8") as f: json.dump(links_list, f, indent=2, ensure_ascii=False) print("Ссылки сохранены в servers.txt и servers.json") return except Exception: pass # 3. Проверяем сырой текст со ссылками if any( proto in raw_content for proto in ["vless://", "vmess://", "ss://", "trojan://"] ): print("Сервер вернул сырой текст со ссылками.") with open("servers.txt", "w", encoding="utf-8") as f: f.write(raw_content) links_list = [ line.strip() for line in raw_content.splitlines() if line.strip() ] with open("servers.json", "w", encoding="utf-8") as f: json.dump(links_list, f, indent=2, ensure_ascii=False) print("Данные сохранены в servers.txt и servers.json") return print("Неизвестный формат ответа. Сохраняем в raw_response.txt") with open("raw_response.txt", "w", encoding="utf-8") as f: f.write(raw_content) sys.exit(1) except Exception as e: print(f"Произошла критическая ошибка: {e}") sys.exit(1) if __name__ == "__main__": get_vpn_servers()