添加Webshare代理获取脚本和Clash配置
- 添加fetch_proxies.py脚本,支持从Webshare API获取代理 - 生成多种格式的代理文件:raw、http、socks5 - 生成Clash配置文件clash_config.yaml - 包含代理组配置和分流规则 - 支持自动选择和故障转移
This commit is contained in:
parent
24963efa76
commit
064cbe1d5f
|
|
@ -0,0 +1,23 @@
|
||||||
|
# 环境变量文件
|
||||||
|
.env
|
||||||
|
|
||||||
|
# Python缓存
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
.Python
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# IDE文件
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# 系统文件
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# 日志文件
|
||||||
|
*.log
|
||||||
|
|
@ -0,0 +1,227 @@
|
||||||
|
allow-lan: false
|
||||||
|
external-controller: 127.0.0.1:9090
|
||||||
|
log-level: info
|
||||||
|
mode: rule
|
||||||
|
port: 7890
|
||||||
|
proxies:
|
||||||
|
- name: proxy-1
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 6269
|
||||||
|
server: 45.196.40.191
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-2
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 6452
|
||||||
|
server: 130.180.228.168
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-3
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 7926
|
||||||
|
server: 72.1.154.35
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-4
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 6479
|
||||||
|
server: 63.141.62.186
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-5
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 6219
|
||||||
|
server: 216.170.122.181
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-6
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 5758
|
||||||
|
server: 192.53.67.209
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-7
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 8160
|
||||||
|
server: 130.180.231.18
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-8
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 5936
|
||||||
|
server: 192.53.142.239
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-9
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 5686
|
||||||
|
server: 103.130.178.22
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-10
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 6563
|
||||||
|
server: 216.98.254.253
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-11
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 5896
|
||||||
|
server: 192.46.188.237
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-12
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 8932
|
||||||
|
server: 45.56.161.56
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-13
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 6766
|
||||||
|
server: 192.46.201.252
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-14
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 6384
|
||||||
|
server: 45.196.50.62
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-15
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 6363
|
||||||
|
server: 193.160.83.42
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-16
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 5898
|
||||||
|
server: 103.130.178.234
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-17
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 6622
|
||||||
|
server: 72.46.139.62
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-18
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 6799
|
||||||
|
server: 72.46.139.239
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-19
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 5726
|
||||||
|
server: 103.130.178.62
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
- name: proxy-20
|
||||||
|
password: lvo4zphp2wwj
|
||||||
|
port: 6247
|
||||||
|
server: 72.46.138.21
|
||||||
|
type: http
|
||||||
|
username: fbkjstyt
|
||||||
|
proxy-groups:
|
||||||
|
- name: 🚀 节点选择
|
||||||
|
proxies:
|
||||||
|
- ♻️ 自动选择
|
||||||
|
- 🎯 故障转移
|
||||||
|
- proxy-1
|
||||||
|
- proxy-2
|
||||||
|
- proxy-3
|
||||||
|
- proxy-4
|
||||||
|
- proxy-5
|
||||||
|
- proxy-6
|
||||||
|
- proxy-7
|
||||||
|
- proxy-8
|
||||||
|
- proxy-9
|
||||||
|
- proxy-10
|
||||||
|
- proxy-11
|
||||||
|
- proxy-12
|
||||||
|
- proxy-13
|
||||||
|
- proxy-14
|
||||||
|
- proxy-15
|
||||||
|
- proxy-16
|
||||||
|
- proxy-17
|
||||||
|
- proxy-18
|
||||||
|
- proxy-19
|
||||||
|
- proxy-20
|
||||||
|
type: select
|
||||||
|
- interval: 300
|
||||||
|
name: ♻️ 自动选择
|
||||||
|
proxies: &id001
|
||||||
|
- proxy-1
|
||||||
|
- proxy-2
|
||||||
|
- proxy-3
|
||||||
|
- proxy-4
|
||||||
|
- proxy-5
|
||||||
|
- proxy-6
|
||||||
|
- proxy-7
|
||||||
|
- proxy-8
|
||||||
|
- proxy-9
|
||||||
|
- proxy-10
|
||||||
|
- proxy-11
|
||||||
|
- proxy-12
|
||||||
|
- proxy-13
|
||||||
|
- proxy-14
|
||||||
|
- proxy-15
|
||||||
|
- proxy-16
|
||||||
|
- proxy-17
|
||||||
|
- proxy-18
|
||||||
|
- proxy-19
|
||||||
|
- proxy-20
|
||||||
|
type: url-test
|
||||||
|
url: http://www.gstatic.com/generate_204
|
||||||
|
- interval: 300
|
||||||
|
name: 🎯 故障转移
|
||||||
|
proxies: *id001
|
||||||
|
type: fallback
|
||||||
|
url: http://www.gstatic.com/generate_204
|
||||||
|
- name: 🌍 国外媒体
|
||||||
|
proxies:
|
||||||
|
- 🚀 节点选择
|
||||||
|
- ♻️ 自动选择
|
||||||
|
- 🎯 故障转移
|
||||||
|
- proxy-1
|
||||||
|
- proxy-2
|
||||||
|
- proxy-3
|
||||||
|
- proxy-4
|
||||||
|
- proxy-5
|
||||||
|
- proxy-6
|
||||||
|
- proxy-7
|
||||||
|
- proxy-8
|
||||||
|
- proxy-9
|
||||||
|
- proxy-10
|
||||||
|
- proxy-11
|
||||||
|
- proxy-12
|
||||||
|
- proxy-13
|
||||||
|
- proxy-14
|
||||||
|
- proxy-15
|
||||||
|
- proxy-16
|
||||||
|
- proxy-17
|
||||||
|
- proxy-18
|
||||||
|
- proxy-19
|
||||||
|
- proxy-20
|
||||||
|
type: select
|
||||||
|
- name: 🍃 应用净化
|
||||||
|
proxies:
|
||||||
|
- REJECT
|
||||||
|
- DIRECT
|
||||||
|
type: select
|
||||||
|
rules:
|
||||||
|
- DOMAIN-SUFFIX,google.com,🚀 节点选择
|
||||||
|
- DOMAIN-SUFFIX,youtube.com,🌍 国外媒体
|
||||||
|
- DOMAIN-SUFFIX,facebook.com,🌍 国外媒体
|
||||||
|
- DOMAIN-SUFFIX,twitter.com,🌍 国外媒体
|
||||||
|
- DOMAIN-SUFFIX,instagram.com,🌍 国外媒体
|
||||||
|
- DOMAIN-SUFFIX,netflix.com,🌍 国外媒体
|
||||||
|
- DOMAIN-KEYWORD,google,🚀 节点选择
|
||||||
|
- DOMAIN-KEYWORD,youtube,🌍 国外媒体
|
||||||
|
- DOMAIN-KEYWORD,facebook,🌍 国外媒体
|
||||||
|
- DOMAIN-KEYWORD,github,🚀 节点选择
|
||||||
|
- GEOIP,CN,DIRECT
|
||||||
|
- MATCH,🚀 节点选择
|
||||||
|
socks-port: 7891
|
||||||
|
|
@ -0,0 +1,410 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Webshare SOCKS代理获取脚本
|
||||||
|
使用简单的下载接口直接获取代理列表
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
import yaml
|
||||||
|
from typing import Optional, List, Dict
|
||||||
|
|
||||||
|
def load_api_key() -> Optional[str]:
|
||||||
|
"""
|
||||||
|
从.env文件或环境变量中加载API密钥
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
API密钥或None
|
||||||
|
"""
|
||||||
|
# 首先尝试从.env文件读取
|
||||||
|
env_file = ".env"
|
||||||
|
if os.path.exists(env_file):
|
||||||
|
try:
|
||||||
|
with open(env_file, 'r', encoding='utf-8') as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if not line or line.startswith('#'):
|
||||||
|
continue
|
||||||
|
if '=' in line:
|
||||||
|
# 处理 TOKEN=xxx 格式
|
||||||
|
key, value = line.split('=', 1)
|
||||||
|
if key.strip() == 'TOKEN':
|
||||||
|
return value.strip()
|
||||||
|
else:
|
||||||
|
# 如果第一行不包含=,则认为是直接的token
|
||||||
|
return line
|
||||||
|
except Exception as e:
|
||||||
|
print(f"读取.env文件时出错: {e}")
|
||||||
|
|
||||||
|
# 然后尝试从环境变量读取
|
||||||
|
api_key = os.getenv('TOKEN') or os.getenv('WEBSHARE_API_KEY')
|
||||||
|
if api_key:
|
||||||
|
return api_key.strip()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_download_token(api_key: str) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
获取下载token
|
||||||
|
|
||||||
|
Args:
|
||||||
|
api_key: API密钥
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
下载token或None
|
||||||
|
"""
|
||||||
|
url = "https://proxy.webshare.io/api/v2/download_token/proxy_list/"
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Token {api_key}",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("🔑 正在获取下载token...")
|
||||||
|
response = requests.post(url, headers=headers)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
download_token = data.get("key") # API返回的字段是'key'而不是'download_token'
|
||||||
|
if download_token:
|
||||||
|
print("✅ 成功获取下载token")
|
||||||
|
return download_token
|
||||||
|
else:
|
||||||
|
print("❌ 响应中未找到下载token")
|
||||||
|
print(f"🔍 可用的键: {list(data.keys())}")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
print(f"❌ 获取下载token失败 {response.status_code}: {response.text}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"获取下载token时出错: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def download_proxies(download_token: str, country: str = "-", auth_method: str = "username",
|
||||||
|
endpoint_mode: str = "direct", location: str = ""):
|
||||||
|
"""
|
||||||
|
使用下载token获取代理列表
|
||||||
|
|
||||||
|
Args:
|
||||||
|
download_token: 下载token (不是API key)
|
||||||
|
country: 国家代码 (- 表示任意国家)
|
||||||
|
auth_method: 认证方式 (username 或 ipauth)
|
||||||
|
endpoint_mode: 端点模式 (direct 或 backbone)
|
||||||
|
location: 位置过滤 (可选)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
代理列表文本
|
||||||
|
"""
|
||||||
|
# 构建下载URL - 正确的格式
|
||||||
|
if location:
|
||||||
|
# URL编码位置参数
|
||||||
|
location_encoded = requests.utils.quote(location)
|
||||||
|
url = f"https://proxy.webshare.io/api/v2/proxy/list/download/{download_token}/{country}/any/{auth_method}/{endpoint_mode}/{location_encoded}/"
|
||||||
|
else:
|
||||||
|
# 没有位置过滤时,不包含最后的路径参数
|
||||||
|
url = f"https://proxy.webshare.io/api/v2/proxy/list/download/{download_token}/{country}/any/{auth_method}/{endpoint_mode}/"
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(f"📡 正在从下载接口获取代理: {url}")
|
||||||
|
response = requests.get(url)
|
||||||
|
|
||||||
|
# 检查响应状态
|
||||||
|
if response.status_code == 404:
|
||||||
|
print("❌ 404错误 - 可能是URL格式不正确或token无效")
|
||||||
|
return None
|
||||||
|
elif response.status_code == 401:
|
||||||
|
print("❌ 401错误 - 下载token无效")
|
||||||
|
return None
|
||||||
|
elif response.status_code != 200:
|
||||||
|
print(f"❌ HTTP错误 {response.status_code}: {response.text}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 检查是否返回了错误信息
|
||||||
|
if "invalid" in response.text.lower() or "error" in response.text.lower():
|
||||||
|
print(f"❌ API返回错误: {response.text}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
return response.text
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"下载代理列表时出错: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def format_proxy_list(proxy_text: str, output_format: str = "socks5") -> list:
|
||||||
|
"""
|
||||||
|
格式化代理列表
|
||||||
|
|
||||||
|
Args:
|
||||||
|
proxy_text: 原始代理文本
|
||||||
|
output_format: 输出格式 (socks5, http, raw)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
格式化的代理列表
|
||||||
|
"""
|
||||||
|
if not proxy_text:
|
||||||
|
return []
|
||||||
|
|
||||||
|
lines = proxy_text.strip().split('\n')
|
||||||
|
formatted_proxies = []
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 假设格式为: ip:port:username:password
|
||||||
|
parts = line.split(':')
|
||||||
|
if len(parts) >= 4:
|
||||||
|
ip, port, username, password = parts[0], parts[1], parts[2], parts[3]
|
||||||
|
|
||||||
|
if output_format == "socks5":
|
||||||
|
formatted_proxy = f"socks5://{username}:{password}@{ip}:{port}"
|
||||||
|
elif output_format == "http":
|
||||||
|
formatted_proxy = f"http://{username}:{password}@{ip}:{port}"
|
||||||
|
else: # raw
|
||||||
|
formatted_proxy = line
|
||||||
|
|
||||||
|
formatted_proxies.append(formatted_proxy)
|
||||||
|
elif len(parts) >= 2:
|
||||||
|
# 无认证格式: ip:port
|
||||||
|
ip, port = parts[0], parts[1]
|
||||||
|
if output_format == "socks5":
|
||||||
|
formatted_proxy = f"socks5://{ip}:{port}"
|
||||||
|
elif output_format == "http":
|
||||||
|
formatted_proxy = f"http://{ip}:{port}"
|
||||||
|
else: # raw
|
||||||
|
formatted_proxy = line
|
||||||
|
|
||||||
|
formatted_proxies.append(formatted_proxy)
|
||||||
|
|
||||||
|
return formatted_proxies
|
||||||
|
|
||||||
|
def save_proxies_to_file(proxies: list, filename: str = "socks_proxies.txt"):
|
||||||
|
"""
|
||||||
|
保存代理列表到文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
proxies: 代理列表
|
||||||
|
filename: 文件名
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with open(filename, 'w', encoding='utf-8') as f:
|
||||||
|
for proxy in proxies:
|
||||||
|
f.write(f"{proxy}\n")
|
||||||
|
print(f"✅ 代理列表已保存到 {filename}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 保存文件时出错: {e}")
|
||||||
|
|
||||||
|
def parse_proxies(proxy_text: str) -> list:
|
||||||
|
"""
|
||||||
|
解析代理文本,提取代理信息
|
||||||
|
|
||||||
|
Args:
|
||||||
|
proxy_text: 代理文本
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
代理信息列表
|
||||||
|
"""
|
||||||
|
proxies = []
|
||||||
|
lines = proxy_text.strip().split('\n')
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 解析格式: host:port:username:password
|
||||||
|
parts = line.split(':')
|
||||||
|
if len(parts) >= 4:
|
||||||
|
proxy = {
|
||||||
|
'host': parts[0],
|
||||||
|
'port': parts[1],
|
||||||
|
'username': parts[2],
|
||||||
|
'password': ':'.join(parts[3:]) # 密码可能包含冒号
|
||||||
|
}
|
||||||
|
proxies.append(proxy)
|
||||||
|
|
||||||
|
return proxies
|
||||||
|
|
||||||
|
def save_proxies(proxies: list, filename: str, format_type: str = "raw"):
|
||||||
|
"""
|
||||||
|
保存代理列表到文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
proxies: 代理列表
|
||||||
|
filename: 文件名
|
||||||
|
format_type: 格式类型 ("raw", "http", "socks5")
|
||||||
|
"""
|
||||||
|
with open(filename, 'w', encoding='utf-8') as f:
|
||||||
|
for proxy in proxies:
|
||||||
|
if format_type == "raw":
|
||||||
|
# 原始格式: host:port:username:password
|
||||||
|
line = f"{proxy['host']}:{proxy['port']}:{proxy['username']}:{proxy['password']}"
|
||||||
|
elif format_type == "http":
|
||||||
|
# HTTP格式: http://username:password@host:port
|
||||||
|
line = f"http://{proxy['username']}:{proxy['password']}@{proxy['host']}:{proxy['port']}"
|
||||||
|
elif format_type == "socks5":
|
||||||
|
# SOCKS5格式: socks5://username:password@host:port
|
||||||
|
line = f"socks5://{proxy['username']}:{proxy['password']}@{proxy['host']}:{proxy['port']}"
|
||||||
|
else:
|
||||||
|
line = f"{proxy['host']}:{proxy['port']}:{proxy['username']}:{proxy['password']}"
|
||||||
|
|
||||||
|
f.write(line + '\n')
|
||||||
|
|
||||||
|
print(f"📄 已保存 {len(proxies)} 个代理到 {filename} ({format_type}格式)")
|
||||||
|
|
||||||
|
def generate_clash_config(proxies: List[Dict[str, str]]) -> Dict:
|
||||||
|
"""
|
||||||
|
生成Clash配置文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
proxies: 代理列表
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Clash配置字典
|
||||||
|
"""
|
||||||
|
clash_proxies = []
|
||||||
|
proxy_names = []
|
||||||
|
|
||||||
|
for i, proxy in enumerate(proxies):
|
||||||
|
proxy_name = f"proxy-{i+1}"
|
||||||
|
proxy_names.append(proxy_name)
|
||||||
|
|
||||||
|
# 创建HTTP代理配置
|
||||||
|
clash_proxy = {
|
||||||
|
"name": proxy_name,
|
||||||
|
"type": "http",
|
||||||
|
"server": proxy['host'],
|
||||||
|
"port": int(proxy['port']),
|
||||||
|
"username": proxy['username'],
|
||||||
|
"password": proxy['password']
|
||||||
|
}
|
||||||
|
clash_proxies.append(clash_proxy)
|
||||||
|
|
||||||
|
# 创建完整的Clash配置
|
||||||
|
clash_config = {
|
||||||
|
"port": 7890,
|
||||||
|
"socks-port": 7891,
|
||||||
|
"allow-lan": False,
|
||||||
|
"mode": "rule",
|
||||||
|
"log-level": "info",
|
||||||
|
"external-controller": "127.0.0.1:9090",
|
||||||
|
"proxies": clash_proxies,
|
||||||
|
"proxy-groups": [
|
||||||
|
{
|
||||||
|
"name": "🚀 节点选择",
|
||||||
|
"type": "select",
|
||||||
|
"proxies": ["♻️ 自动选择", "🎯 故障转移"] + proxy_names
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "♻️ 自动选择",
|
||||||
|
"type": "url-test",
|
||||||
|
"proxies": proxy_names,
|
||||||
|
"url": "http://www.gstatic.com/generate_204",
|
||||||
|
"interval": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "🎯 故障转移",
|
||||||
|
"type": "fallback",
|
||||||
|
"proxies": proxy_names,
|
||||||
|
"url": "http://www.gstatic.com/generate_204",
|
||||||
|
"interval": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "🌍 国外媒体",
|
||||||
|
"type": "select",
|
||||||
|
"proxies": ["🚀 节点选择", "♻️ 自动选择", "🎯 故障转移"] + proxy_names
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "🍃 应用净化",
|
||||||
|
"type": "select",
|
||||||
|
"proxies": ["REJECT", "DIRECT"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rules": [
|
||||||
|
"DOMAIN-SUFFIX,google.com,🚀 节点选择",
|
||||||
|
"DOMAIN-SUFFIX,youtube.com,🌍 国外媒体",
|
||||||
|
"DOMAIN-SUFFIX,facebook.com,🌍 国外媒体",
|
||||||
|
"DOMAIN-SUFFIX,twitter.com,🌍 国外媒体",
|
||||||
|
"DOMAIN-SUFFIX,instagram.com,🌍 国外媒体",
|
||||||
|
"DOMAIN-SUFFIX,netflix.com,🌍 国外媒体",
|
||||||
|
"DOMAIN-KEYWORD,google,🚀 节点选择",
|
||||||
|
"DOMAIN-KEYWORD,youtube,🌍 国外媒体",
|
||||||
|
"DOMAIN-KEYWORD,facebook,🌍 国外媒体",
|
||||||
|
"DOMAIN-KEYWORD,github,🚀 节点选择",
|
||||||
|
"GEOIP,CN,DIRECT",
|
||||||
|
"MATCH,🚀 节点选择"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return clash_config
|
||||||
|
|
||||||
|
def save_clash_config(proxies: List[Dict[str, str]], filename: str = "clash_config.yaml"):
|
||||||
|
"""
|
||||||
|
保存Clash配置文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
proxies: 代理列表
|
||||||
|
filename: 文件名
|
||||||
|
"""
|
||||||
|
clash_config = generate_clash_config(proxies)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(filename, 'w', encoding='utf-8') as f:
|
||||||
|
yaml.dump(clash_config, f, default_flow_style=False, allow_unicode=True, indent=2)
|
||||||
|
print(f"📄 已保存Clash配置到 {filename}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 保存Clash配置时出错: {e}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数"""
|
||||||
|
print("🚀 开始获取Webshare代理列表...")
|
||||||
|
|
||||||
|
# 加载API密钥
|
||||||
|
api_key = load_api_key()
|
||||||
|
if not api_key:
|
||||||
|
print("❌ 无法加载API密钥")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 获取下载token
|
||||||
|
download_token = get_download_token(api_key)
|
||||||
|
if not download_token:
|
||||||
|
print("❌ 获取下载token失败")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 下载代理列表
|
||||||
|
proxy_text = download_proxies(download_token)
|
||||||
|
if not proxy_text:
|
||||||
|
print("❌ 获取代理列表失败")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 解析代理
|
||||||
|
proxies = parse_proxies(proxy_text)
|
||||||
|
if not proxies:
|
||||||
|
print("❌ 未找到有效的代理")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"✅ 成功获取 {len(proxies)} 个代理")
|
||||||
|
|
||||||
|
# 保存原始代理列表
|
||||||
|
save_proxies(proxies, "proxies_raw.txt", format_type="raw")
|
||||||
|
|
||||||
|
# 保存HTTP格式代理列表
|
||||||
|
save_proxies(proxies, "proxies_http.txt", format_type="http")
|
||||||
|
|
||||||
|
# 保存SOCKS5格式代理列表
|
||||||
|
save_proxies(proxies, "proxies_socks5.txt", format_type="socks5")
|
||||||
|
|
||||||
|
# 生成Clash配置文件
|
||||||
|
save_clash_config(proxies, "clash_config.yaml")
|
||||||
|
|
||||||
|
print("🎉 代理列表已保存完成!")
|
||||||
|
print("📁 文件说明:")
|
||||||
|
print(" - proxies_raw.txt: 原始格式 (host:port:username:password)")
|
||||||
|
print(" - proxies_http.txt: HTTP格式 (http://username:password@host:port)")
|
||||||
|
print(" - proxies_socks5.txt: SOCKS5格式 (socks5://username:password@host:port)")
|
||||||
|
print(" - clash_config.yaml: Clash配置文件")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
curl "https://proxy.webshare.io/api/v2/proxy/list/download/ulowafkljtigyvuxlitaakdaqvozmcjrnnhwegdf/-/any/username/direct/san%20francisco/"
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@45.196.40.191:6269
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@130.180.228.168:6452
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@72.1.154.35:7926
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@63.141.62.186:6479
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@216.170.122.181:6219
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@192.53.67.209:5758
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@130.180.231.18:8160
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@192.53.142.239:5936
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@103.130.178.22:5686
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@216.98.254.253:6563
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@192.46.188.237:5896
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@45.56.161.56:8932
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@192.46.201.252:6766
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@45.196.50.62:6384
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@193.160.83.42:6363
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@103.130.178.234:5898
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@72.46.139.62:6622
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@72.46.139.239:6799
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@103.130.178.62:5726
|
||||||
|
http://fbkjstyt:lvo4zphp2wwj@72.46.138.21:6247
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
45.196.40.191:6269:fbkjstyt:lvo4zphp2wwj
|
||||||
|
130.180.228.168:6452:fbkjstyt:lvo4zphp2wwj
|
||||||
|
72.1.154.35:7926:fbkjstyt:lvo4zphp2wwj
|
||||||
|
63.141.62.186:6479:fbkjstyt:lvo4zphp2wwj
|
||||||
|
216.170.122.181:6219:fbkjstyt:lvo4zphp2wwj
|
||||||
|
192.53.67.209:5758:fbkjstyt:lvo4zphp2wwj
|
||||||
|
130.180.231.18:8160:fbkjstyt:lvo4zphp2wwj
|
||||||
|
192.53.142.239:5936:fbkjstyt:lvo4zphp2wwj
|
||||||
|
103.130.178.22:5686:fbkjstyt:lvo4zphp2wwj
|
||||||
|
216.98.254.253:6563:fbkjstyt:lvo4zphp2wwj
|
||||||
|
192.46.188.237:5896:fbkjstyt:lvo4zphp2wwj
|
||||||
|
45.56.161.56:8932:fbkjstyt:lvo4zphp2wwj
|
||||||
|
192.46.201.252:6766:fbkjstyt:lvo4zphp2wwj
|
||||||
|
45.196.50.62:6384:fbkjstyt:lvo4zphp2wwj
|
||||||
|
193.160.83.42:6363:fbkjstyt:lvo4zphp2wwj
|
||||||
|
103.130.178.234:5898:fbkjstyt:lvo4zphp2wwj
|
||||||
|
72.46.139.62:6622:fbkjstyt:lvo4zphp2wwj
|
||||||
|
72.46.139.239:6799:fbkjstyt:lvo4zphp2wwj
|
||||||
|
103.130.178.62:5726:fbkjstyt:lvo4zphp2wwj
|
||||||
|
72.46.138.21:6247:fbkjstyt:lvo4zphp2wwj
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@45.196.40.191:6269
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@130.180.228.168:6452
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@72.1.154.35:7926
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@63.141.62.186:6479
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@216.170.122.181:6219
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@192.53.67.209:5758
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@130.180.231.18:8160
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@192.53.142.239:5936
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@103.130.178.22:5686
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@216.98.254.253:6563
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@192.46.188.237:5896
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@45.56.161.56:8932
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@192.46.201.252:6766
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@45.196.50.62:6384
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@193.160.83.42:6363
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@103.130.178.234:5898
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@72.46.139.62:6622
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@72.46.139.239:6799
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@103.130.178.62:5726
|
||||||
|
socks5://fbkjstyt:lvo4zphp2wwj@72.46.138.21:6247
|
||||||
Loading…
Reference in New Issue