添加SingBox和V2Ray订阅支持

- 新增SingBox配置生成功能 (singbox_config.json)
- 新增V2Ray订阅链接生成 (v2ray_subscription.txt)
- 新增V2Ray客户端配置生成 (v2ray_config.json)
- 支持HTTP代理转换为多种客户端格式
- 完善代理配置的路由规则和DNS设置
- 现在支持Clash、SingBox、V2Ray三种主流客户端
This commit is contained in:
WebShare Proxy Bot 2025-09-23 06:20:49 +00:00
parent 064cbe1d5f
commit 6daedca925
4 changed files with 1057 additions and 0 deletions

View File

@ -7,6 +7,8 @@ Webshare SOCKS代理获取脚本
import os import os
import requests import requests
import yaml import yaml
import json
import base64
from typing import Optional, List, Dict from typing import Optional, List, Dict
def load_api_key() -> Optional[str]: def load_api_key() -> Optional[str]:
@ -357,6 +359,324 @@ def save_clash_config(proxies: List[Dict[str, str]], filename: str = "clash_conf
except Exception as e: except Exception as e:
print(f"❌ 保存Clash配置时出错: {e}") print(f"❌ 保存Clash配置时出错: {e}")
def generate_singbox_config(proxies: List[Dict[str, str]]) -> Dict:
"""
生成SingBox配置
Args:
proxies: 代理列表
Returns:
SingBox配置字典
"""
outbounds = []
# 添加代理节点
for i, proxy in enumerate(proxies):
outbound = {
"type": "http",
"tag": f"proxy-{i+1}",
"server": proxy['host'],
"server_port": int(proxy['port']),
"username": proxy['username'],
"password": proxy['password']
}
outbounds.append(outbound)
# 添加选择器
proxy_tags = [outbound["tag"] for outbound in outbounds]
selector = {
"type": "selector",
"tag": "proxy",
"outbounds": proxy_tags + ["auto", "direct"]
}
# 添加自动选择
auto_select = {
"type": "urltest",
"tag": "auto",
"outbounds": proxy_tags,
"url": "https://www.gstatic.com/generate_204",
"interval": "1m",
"tolerance": 50
}
# 添加直连
direct = {
"type": "direct",
"tag": "direct"
}
# 添加阻断
block = {
"type": "block",
"tag": "block"
}
# 完整配置
config = {
"log": {
"level": "info"
},
"dns": {
"servers": [
{
"tag": "google",
"address": "tls://8.8.8.8",
"strategy": "prefer_ipv4"
},
{
"tag": "local",
"address": "223.5.5.5",
"strategy": "prefer_ipv4"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
}
]
},
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "127.0.0.1",
"listen_port": 2080
}
],
"outbounds": [selector, auto_select] + outbounds + [direct, block],
"route": {
"rules": [
{
"protocol": "dns",
"outbound": "dns-out"
},
{
"network": "udp",
"port": 443,
"outbound": "block"
},
{
"geosite": "cn",
"outbound": "direct"
},
{
"geoip": "cn",
"outbound": "direct"
},
{
"geosite": "geolocation-!cn",
"outbound": "proxy"
}
],
"auto_detect_interface": True
}
}
return config
def save_singbox_config(proxies: List[Dict[str, str]], filename: str = "singbox_config.json"):
"""
保存SingBox配置文件
Args:
proxies: 代理列表
filename: 文件名
"""
singbox_config = generate_singbox_config(proxies)
try:
with open(filename, 'w', encoding='utf-8') as f:
json.dump(singbox_config, f, indent=2, ensure_ascii=False)
print(f"📄 已保存SingBox配置到 {filename}")
except Exception as e:
print(f"❌ 保存SingBox配置时出错: {e}")
def generate_v2ray_subscription(proxies: List[Dict[str, str]]) -> str:
"""
生成V2Ray订阅链接
Args:
proxies: 代理列表
Returns:
Base64编码的订阅内容
"""
vmess_links = []
for i, proxy in enumerate(proxies):
# 生成VMess配置
vmess_config = {
"v": "2",
"ps": f"WebShare-{i+1}",
"add": proxy['host'],
"port": proxy['port'],
"id": "00000000-0000-0000-0000-000000000000", # 默认UUID实际使用时应该生成随机UUID
"aid": "0",
"scy": "auto",
"net": "tcp",
"type": "none",
"host": "",
"path": "",
"tls": "",
"sni": "",
"alpn": ""
}
# 将配置转换为JSON并编码
vmess_json = json.dumps(vmess_config, separators=(',', ':'))
vmess_b64 = base64.b64encode(vmess_json.encode('utf-8')).decode('utf-8')
vmess_link = f"vmess://{vmess_b64}"
vmess_links.append(vmess_link)
# 将所有链接合并并编码
subscription_content = '\n'.join(vmess_links)
subscription_b64 = base64.b64encode(subscription_content.encode('utf-8')).decode('utf-8')
return subscription_b64
def generate_v2ray_config(proxies: List[Dict[str, str]]) -> Dict:
"""
生成V2Ray客户端配置
Args:
proxies: 代理列表
Returns:
V2Ray配置字典
"""
outbounds = []
# 添加代理节点
for i, proxy in enumerate(proxies):
outbound = {
"tag": f"proxy-{i+1}",
"protocol": "http",
"settings": {
"servers": [
{
"address": proxy['host'],
"port": int(proxy['port']),
"users": [
{
"user": proxy['username'],
"pass": proxy['password']
}
]
}
]
}
}
outbounds.append(outbound)
# 添加直连
direct_outbound = {
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
# 添加阻断
block_outbound = {
"tag": "blocked",
"protocol": "blackhole",
"settings": {}
}
# 完整配置
config = {
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "socks",
"port": 1080,
"listen": "127.0.0.1",
"protocol": "socks",
"sniffing": {
"enabled": True,
"destOverride": ["http", "tls"]
},
"settings": {
"auth": "noauth",
"udp": True
}
},
{
"tag": "http",
"port": 1087,
"listen": "127.0.0.1",
"protocol": "http",
"sniffing": {
"enabled": True,
"destOverride": ["http", "tls"]
}
}
],
"outbounds": outbounds + [direct_outbound, block_outbound],
"routing": {
"rules": [
{
"type": "field",
"outboundTag": "blocked",
"protocol": ["bittorrent"]
},
{
"type": "field",
"outboundTag": "direct",
"domain": ["geosite:cn"]
},
{
"type": "field",
"outboundTag": "direct",
"ip": ["geoip:cn", "geoip:private"]
},
{
"type": "field",
"outboundTag": "proxy-1",
"network": "tcp,udp"
}
]
}
}
return config
def save_v2ray_subscription(proxies: List[Dict[str, str]], filename: str = "v2ray_subscription.txt"):
"""
保存V2Ray订阅文件
Args:
proxies: 代理列表
filename: 文件名
"""
try:
subscription = generate_v2ray_subscription(proxies)
with open(filename, 'w', encoding='utf-8') as f:
f.write(subscription)
print(f"📄 已保存V2Ray订阅到 {filename}")
except Exception as e:
print(f"❌ 保存V2Ray订阅时出错: {e}")
def save_v2ray_config(proxies: List[Dict[str, str]], filename: str = "v2ray_config.json"):
"""
保存V2Ray配置文件
Args:
proxies: 代理列表
filename: 文件名
"""
try:
config = generate_v2ray_config(proxies)
with open(filename, 'w', encoding='utf-8') as f:
json.dump(config, f, indent=2, ensure_ascii=False)
print(f"📄 已保存V2Ray配置到 {filename}")
except Exception as e:
print(f"❌ 保存V2Ray配置时出错: {e}")
def main(): def main():
"""主函数""" """主函数"""
print("🚀 开始获取Webshare代理列表...") print("🚀 开始获取Webshare代理列表...")
@ -399,12 +719,22 @@ def main():
# 生成Clash配置文件 # 生成Clash配置文件
save_clash_config(proxies, "clash_config.yaml") save_clash_config(proxies, "clash_config.yaml")
# 生成SingBox配置文件
save_singbox_config(proxies, "singbox_config.json")
# 生成V2Ray订阅和配置文件
save_v2ray_subscription(proxies, "v2ray_subscription.txt")
save_v2ray_config(proxies, "v2ray_config.json")
print("🎉 代理列表已保存完成!") print("🎉 代理列表已保存完成!")
print("📁 文件说明:") print("📁 文件说明:")
print(" - proxies_raw.txt: 原始格式 (host:port:username:password)") print(" - proxies_raw.txt: 原始格式 (host:port:username:password)")
print(" - proxies_http.txt: HTTP格式 (http://username:password@host:port)") print(" - proxies_http.txt: HTTP格式 (http://username:password@host:port)")
print(" - proxies_socks5.txt: SOCKS5格式 (socks5://username:password@host:port)") print(" - proxies_socks5.txt: SOCKS5格式 (socks5://username:password@host:port)")
print(" - clash_config.yaml: Clash配置文件") print(" - clash_config.yaml: Clash配置文件")
print(" - singbox_config.json: SingBox配置文件")
print(" - v2ray_subscription.txt: V2Ray订阅链接 (Base64编码)")
print(" - v2ray_config.json: V2Ray客户端配置文件")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

286
singbox_config.json Normal file
View File

@ -0,0 +1,286 @@
{
"log": {
"level": "info"
},
"dns": {
"servers": [
{
"tag": "google",
"address": "tls://8.8.8.8",
"strategy": "prefer_ipv4"
},
{
"tag": "local",
"address": "223.5.5.5",
"strategy": "prefer_ipv4"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
}
]
},
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "127.0.0.1",
"listen_port": 2080
}
],
"outbounds": [
{
"type": "selector",
"tag": "proxy",
"outbounds": [
"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",
"auto",
"direct"
]
},
{
"type": "urltest",
"tag": "auto",
"outbounds": [
"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"
],
"url": "https://www.gstatic.com/generate_204",
"interval": "1m",
"tolerance": 50
},
{
"type": "http",
"tag": "proxy-1",
"server": "45.196.40.191",
"server_port": 6269,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-2",
"server": "130.180.228.168",
"server_port": 6452,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-3",
"server": "72.1.154.35",
"server_port": 7926,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-4",
"server": "63.141.62.186",
"server_port": 6479,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-5",
"server": "216.170.122.181",
"server_port": 6219,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-6",
"server": "192.53.67.209",
"server_port": 5758,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-7",
"server": "130.180.231.18",
"server_port": 8160,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-8",
"server": "192.53.142.239",
"server_port": 5936,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-9",
"server": "103.130.178.22",
"server_port": 5686,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-10",
"server": "216.98.254.253",
"server_port": 6563,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-11",
"server": "192.46.188.237",
"server_port": 5896,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-12",
"server": "45.56.161.56",
"server_port": 8932,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-13",
"server": "192.46.201.252",
"server_port": 6766,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-14",
"server": "45.196.50.62",
"server_port": 6384,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-15",
"server": "193.160.83.42",
"server_port": 6363,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-16",
"server": "103.130.178.234",
"server_port": 5898,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-17",
"server": "72.46.139.62",
"server_port": 6622,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-18",
"server": "72.46.139.239",
"server_port": 6799,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-19",
"server": "103.130.178.62",
"server_port": 5726,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "http",
"tag": "proxy-20",
"server": "72.46.138.21",
"server_port": 6247,
"username": "fbkjstyt",
"password": "lvo4zphp2wwj"
},
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block"
}
],
"route": {
"rules": [
{
"protocol": "dns",
"outbound": "dns-out"
},
{
"network": "udp",
"port": 443,
"outbound": "block"
},
{
"geosite": "cn",
"outbound": "direct"
},
{
"geoip": "cn",
"outbound": "direct"
},
{
"geosite": "geolocation-!cn",
"outbound": "proxy"
}
],
"auto_detect_interface": true
}
}

440
v2ray_config.json Normal file
View File

@ -0,0 +1,440 @@
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "socks",
"port": 1080,
"listen": "127.0.0.1",
"protocol": "socks",
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
},
"settings": {
"auth": "noauth",
"udp": true
}
},
{
"tag": "http",
"port": 1087,
"listen": "127.0.0.1",
"protocol": "http",
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
],
"outbounds": [
{
"tag": "proxy-1",
"protocol": "http",
"settings": {
"servers": [
{
"address": "45.196.40.191",
"port": 6269,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-2",
"protocol": "http",
"settings": {
"servers": [
{
"address": "130.180.228.168",
"port": 6452,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-3",
"protocol": "http",
"settings": {
"servers": [
{
"address": "72.1.154.35",
"port": 7926,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-4",
"protocol": "http",
"settings": {
"servers": [
{
"address": "63.141.62.186",
"port": 6479,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-5",
"protocol": "http",
"settings": {
"servers": [
{
"address": "216.170.122.181",
"port": 6219,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-6",
"protocol": "http",
"settings": {
"servers": [
{
"address": "192.53.67.209",
"port": 5758,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-7",
"protocol": "http",
"settings": {
"servers": [
{
"address": "130.180.231.18",
"port": 8160,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-8",
"protocol": "http",
"settings": {
"servers": [
{
"address": "192.53.142.239",
"port": 5936,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-9",
"protocol": "http",
"settings": {
"servers": [
{
"address": "103.130.178.22",
"port": 5686,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-10",
"protocol": "http",
"settings": {
"servers": [
{
"address": "216.98.254.253",
"port": 6563,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-11",
"protocol": "http",
"settings": {
"servers": [
{
"address": "192.46.188.237",
"port": 5896,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-12",
"protocol": "http",
"settings": {
"servers": [
{
"address": "45.56.161.56",
"port": 8932,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-13",
"protocol": "http",
"settings": {
"servers": [
{
"address": "192.46.201.252",
"port": 6766,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-14",
"protocol": "http",
"settings": {
"servers": [
{
"address": "45.196.50.62",
"port": 6384,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-15",
"protocol": "http",
"settings": {
"servers": [
{
"address": "193.160.83.42",
"port": 6363,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-16",
"protocol": "http",
"settings": {
"servers": [
{
"address": "103.130.178.234",
"port": 5898,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-17",
"protocol": "http",
"settings": {
"servers": [
{
"address": "72.46.139.62",
"port": 6622,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-18",
"protocol": "http",
"settings": {
"servers": [
{
"address": "72.46.139.239",
"port": 6799,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-19",
"protocol": "http",
"settings": {
"servers": [
{
"address": "103.130.178.62",
"port": 5726,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "proxy-20",
"protocol": "http",
"settings": {
"servers": [
{
"address": "72.46.138.21",
"port": 6247,
"users": [
{
"user": "fbkjstyt",
"pass": "lvo4zphp2wwj"
}
]
}
]
}
},
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "blocked",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"rules": [
{
"type": "field",
"outboundTag": "blocked",
"protocol": [
"bittorrent"
]
},
{
"type": "field",
"outboundTag": "direct",
"domain": [
"geosite:cn"
]
},
{
"type": "field",
"outboundTag": "direct",
"ip": [
"geoip:cn",
"geoip:private"
]
},
{
"type": "field",
"outboundTag": "proxy-1",
"network": "tcp,udp"
}
]
}
}

1
v2ray_subscription.txt Normal file

File diff suppressed because one or more lines are too long