switch_proxy.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import httpx
  2. import time
  3. import json
  4. import uuid
  5. import logging
  6. import websockets
  7. from typing import Optional, List
  8. from websockets import WebSocketCommonProtocol
  9. logging.basicConfig(level=logging.INFO)
  10. class ClashProxyManager:
  11. def __init__(self):
  12. self.key_group = 0
  13. self.clash_api_base_url = [
  14. "http://192.168.31.201:58001/api",
  15. "http://192.168.31.201:58002/api",
  16. "http://192.168.31.201:58003/api",
  17. "http://192.168.31.201:58004/api",
  18. "http://192.168.31.201:58005/api",
  19. "http://192.168.31.201:58006/api",
  20. "http://192.168.31.201:58007/api",
  21. "http://192.168.31.201:58008/api",
  22. "http://192.168.31.201:58009/api",
  23. "http://192.168.31.201:58010/api",
  24. ]
  25. self.proxy_keyword = [
  26. ['sg', 'SG', '新加坡', '马来西亚'],
  27. ['jp', '日本'],
  28. ]
  29. self.all_proxies = []
  30. self.selected_proxies = []
  31. def get_all_proxies(self, clash_tool_url: str) -> List[str]:
  32. url = f"{clash_tool_url}/proxies"
  33. try:
  34. response = httpx.get(url)
  35. response.raise_for_status()
  36. proxies = response.json()
  37. logging.info("Available proxies:")
  38. # 输出读取的所有代理信息
  39. # for proxy_name, proxy_info in proxies['proxies'].items():
  40. # logging.info(f"Name: {proxy_name}, Type: {proxy_info.get('type', 'Unknown')}")
  41. return list(proxies['proxies'].keys())
  42. except Exception as e:
  43. logging.error(f"Failed to get proxies: {e}")
  44. return []
  45. def filter_proxy(self):
  46. for keyword in self.proxy_keyword[self.key_group]:
  47. for item in self.all_proxies:
  48. if keyword.lower() in item.lower():
  49. self.selected_proxies.append(item)
  50. def switch_proxy(self, proxy_name: str, clash_api_base_url: str) -> None:
  51. url = f"{clash_api_base_url}/proxies/GLOBAL"
  52. data = {"name": proxy_name}
  53. try:
  54. response = httpx.put(url, json=data)
  55. if response.status_code == 204:
  56. logging.info(f"Switched to proxy: {proxy_name}")
  57. else:
  58. logging.error(f"Failed to switch proxy: {response.status_code} - {proxy_name}")
  59. except Exception as e:
  60. logging.error(f"Failed to switch proxy: {e}")
  61. def main(self) -> None:
  62. # 读取所有代理
  63. if not self.all_proxies:
  64. for clash_tool_url in self.clash_api_base_url:
  65. proxies = self.get_all_proxies(clash_tool_url)
  66. if proxies:
  67. self.all_proxies = proxies
  68. break
  69. if not self.all_proxies:
  70. logging.error("Failed to get all proxies")
  71. return
  72. # 通过关键词过滤出需要的代理
  73. self.filter_proxy()
  74. if not self.selected_proxies:
  75. logging.error("Failed to filter proxies")
  76. return
  77. # 遍历所有的线路api, 切换代理
  78. # 两个循环, 设换不重复的代理
  79. switched_agent = []
  80. for clash_api_base_url in self.clash_api_base_url:
  81. for select_proxy in self.selected_proxies:
  82. if select_proxy in switched_agent:
  83. continue
  84. else:
  85. self.switch_proxy(select_proxy, clash_api_base_url)
  86. switched_agent.append(select_proxy)
  87. break
  88. if __name__ == "__main__":
  89. manager = ClashProxyManager()
  90. manager.main()