switch_proxy.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import json
  2. import random
  3. import subprocess
  4. import httpx
  5. def load_config():
  6. with open("config.json", "r") as f:
  7. return json.load(f)
  8. config = load_config()
  9. END = config["total_container"]
  10. START_PORT = config["start_web_port"]
  11. START_API_PORT = config["start_port"]
  12. base_url_list = [f'http://192.168.31.201:{START_PORT + i}' for i in range(0, END)]
  13. base_api_list = [f'http://192.168.31.201:{START_API_PORT + i}' for i in range(0, END)]
  14. class ProxyManager:
  15. def __init__(self, base_url):
  16. self.base_url = base_url
  17. def switch_to_global(self):
  18. print(f"{self.base_url}/api/configs 切换全局代理")
  19. headers = {
  20. "accept": "application/json, text/plain, */*",
  21. "accept-encoding": "gzip, deflate, br, zstd",
  22. "accept-language": "zh-CN,zh",
  23. "connection": "keep-alive",
  24. "content-type": "application/json",
  25. "host": base_url.replace('http://', ''),
  26. "origin": base_url,
  27. "referer": base_url,
  28. "sec-ch-ua": '"Not A(Brand";v="8", "Chromium";v="132", "Brave";v="132"',
  29. "sec-ch-ua-mobile": "?0",
  30. "sec-ch-ua-platform": '"macOS"',
  31. "sec-fetch-dest": "empty",
  32. "sec-fetch-mode": "cors",
  33. "sec-fetch-site": "same-origin",
  34. "sec-gpc": "1",
  35. "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
  36. }
  37. data = {"mode": "Global"}
  38. try:
  39. with httpx.Client() as client:
  40. response = client.patch(self.base_url + "/api/configs", json=data, headers=headers)
  41. if response.status_code == 204:
  42. print(f"{self.base_url}/api/configs 切换全局代理成功")
  43. else:
  44. print(f"{self.base_url}/api/configs 切换全局代理失败 {response.status_code}")
  45. exit(1)
  46. except httpx.RequestError as exc:
  47. print(f"请求失败: {exc}")
  48. exit(1)
  49. def get_proxy_name(self):
  50. print(f'{self.base_url}/api/proxies 获取代理名称')
  51. try:
  52. response = httpx.get(self.base_url + "/api/proxies")
  53. response.raise_for_status()
  54. proxies = response.json()
  55. proxy_name_list = [item for item in proxies['proxies']['GLOBAL']['all'] if item not in ('DIRECT', 'REJECT')]
  56. return proxy_name_list
  57. except Exception as e:
  58. print(f'get_proxy_name: {e}')
  59. exit(1)
  60. def switch_proxy(self, proxy_name, base_api):
  61. print(f'{self.base_url}/api/proxies/GLOBAL 切换代理')
  62. try:
  63. target_url = self.base_url + '/api/proxies/GLOBAL'
  64. response = httpx.put(target_url, json={"name": proxy_name})
  65. if response.status_code == 204:
  66. # 切换代理成功, 检测代理
  67. return self.check_proxy(base_api)
  68. else:
  69. print(f"切换代理失败: {response.status_code} - {proxy_name}\n重试...")
  70. return False
  71. except Exception as e:
  72. print(f"切换代理失败: {e}\n重试...")
  73. return False
  74. def check_proxy(self, proxy_url):
  75. # proxy_url: 代理地址, 没有密码
  76. # 测试目标地址:
  77. command = ["curl", "-x", proxy_url, "ip.sb"]
  78. # 执行命令并获取输出
  79. try:
  80. result = subprocess.run(command, capture_output=True, text=True, check=True)
  81. if not result:
  82. return False
  83. print("Output:", result.stdout)
  84. return True
  85. except subprocess.CalledProcessError as e:
  86. # 如果命令执行失败,打印错误信息
  87. print("Error:", e.stderr)
  88. return False
  89. used_proxy = []
  90. for base_url, base_api in zip(base_url_list, base_api_list):
  91. manager = ProxyManager(base_url)
  92. manager.switch_to_global()
  93. proxy_name_list = manager.get_proxy_name()
  94. while proxy_name_list:
  95. proxy_name = random.choice(proxy_name_list)
  96. if proxy_name not in used_proxy:
  97. if manager.switch_proxy(proxy_name, base_api):
  98. break
  99. result = used_proxy.append(proxy_name)