基于 Clash 的多节点智能切换系统,专为数据采集场景设计。通过程序化控制 VPN 节点,实现多 IP 轮换,提升爬虫效率。
- 自动切换多国节点 - 支持按国家、延迟、成功率智能切换
- 智能节点选择 - 基于延迟和成功率的综合评分
- 节点健康监控 - 实时统计节点性能,自动剔除异常节点
- 无缝集成 - 提供 Scrapy 中间件,支持任何使用 requests 的框架
- 多种策略 - 支持手动、定时、请求数、智能等多种切换策略
爬虫代码 (Scrapy / Requests / aiohttp)
↓ proxies={'http': 'http://127.0.0.1:8901'}
VPN Gateway
├─ VPNGateway — 统一入口,管理切换策略
├─ ClashClient — Clash API 通信 (:9097)
└─ NodeManager — 节点过滤、评分、统计
↓ API 控制节点切换
Clash mihomo 内核 (port 8901)
↓
VPN 节点 (🇭🇰🇯🇵🇸🇬🇹🇼🇺🇸🇬🇧)
| 端口 | 用途 | 说明 |
|---|---|---|
| 8901 | 爬虫专用 | Clash 内核直连,IP 跟随节点切换,VPNGateway 初始化时自动开启 |
| 7897 | 日常上网 | Clash Verge 主进程转发,节点由 Clash Verge 界面控制 |
| 9097 | API 控制 | Clash External Controller,用于程序化控制节点 |
重要: 爬虫必须用 8901 端口。7897 是 Clash Verge 主进程转发,IP 不跟随程序切换节点。
- Clash Verge 客户端(推荐 Clash Verge Rev)
- Python 3.7+
- 活跃的 VPN 订阅(含多国节点)
- 支持平台: macOS / Windows / Linux
# 1. 克隆项目
git clone <repository-url>
cd vpn_gateway
# 2. 安装依赖
pip install -r requirements.txt
# 3. 配置
cp config.example.yaml config.yaml
# 编辑 config.yaml:
# clash.port: 9097 (Clash Verge 默认)
# clash.secret: 你的 API 密码
# proxy.port: 8901 (内核直连端口)-
下载安装 Clash Verge Rev
- macOS:
.dmg(Apple Silicon 选aarch64,Intel 选x64) - Windows:
.msi安装包 - Linux:
.deb/.rpm/.AppImage
- macOS:
-
导入 VPN 订阅 → 设置 → 订阅 → 添加订阅地址
-
启用 External Controller
- 设置 → Clash 内核
- External Controller:
127.0.0.1:9097 - Secret: 设置密码(需与 config.yaml 一致)
-
测试连接
python test_connection.py 127.0.0.1 9097 <your-secret> 8901
from src import VPNGateway
import requests
gateway = VPNGateway("config.yaml")
proxy = gateway.get_proxy() # {'http': 'http://127.0.0.1:8901', ...}
# 切换到美国节点
gateway.switch_to_country('US')
# 发起请求
response = requests.get('https://api.ipify.org', proxies=proxy)
print(f"当前 IP: {response.text}")
# 记录结果(驱动智能切换)
gateway.record_request(success=response.ok)from src import VPNGateway
import requests, time
gateway = VPNGateway("config.yaml")
proxy = gateway.get_proxy()
def scrape_with_rotation(url, max_retries=3, **kwargs):
"""请求失败自动切换节点重试"""
for attempt in range(max_retries):
try:
resp = requests.get(url, proxies=proxy, timeout=15, **kwargs)
if resp.status_code in (403, 429, 503):
gateway.record_request(success=False)
gateway.smart_switch()
time.sleep(2)
continue
gateway.record_request(success=True)
return resp
except (requests.Timeout, requests.ConnectionError):
gateway.record_request(success=False)
gateway.smart_switch()
time.sleep(2)
return Nonecountries = ['US', 'JP', 'SG', 'HK', 'GB', 'TW']
for i, url in enumerate(url_list):
country = countries[i % len(countries)]
gateway.switch_to_country(country)
time.sleep(1)
resp = scrape_with_rotation(url)
if resp:
process(resp)python examples/scrapy_integration.py详见 examples/scrapy_integration.py 中的 VPNMiddleware 实现。
config.yaml 完整配置:
clash:
host: "127.0.0.1"
port: 9097 # Clash External Controller 端口
secret: "your-secret" # API 密码
proxy:
host: "127.0.0.1"
port: 8901 # 内核直连端口(爬虫用)
strategy:
mode: "smart" # manual | time_based | request_based | smart
time_interval: 300 # time_based: 每 N 秒切换
request_threshold: 100 # request_based: 每 N 个请求切换
smart:
health_check_interval: 60
failure_rate_threshold: 0.3 # 失败率超过 30% 自动切换
node_filter:
include_countries: [] # 例: ["US", "JP", "SG"]
exclude_countries: []
include_keywords: [] # 例: ["优质", "IEPL"]
exclude_keywords: []| 策略 | 说明 | 适用场景 |
|---|---|---|
manual |
不自动切换 | 手动控制 |
time_based |
每 N 秒切换 | 长时间采集 |
request_based |
每 N 个请求切换 | 批量采集 |
smart |
失败率过高自动切换 | 爬虫推荐 |
gateway.get_proxy() # 获取代理字典
gateway.switch_to_country('US') # 切到指定国家
gateway.switch_to_node(node_name) # 切到指定节点
gateway.smart_switch() # 自动选最优节点
gateway.record_request(success=True) # 记录请求结果
gateway.get_available_nodes() # 列出所有可用节点
gateway.get_current_node() # 当前节点名
gateway.get_nodes_by_country() # 按国家分组
gateway.get_stats() # 统计信息# 爬虫任务(跟随程序节点切换)
export http_proxy=http://127.0.0.1:8901
export https_proxy=http://127.0.0.1:8901
# 日常上网
export http_proxy=http://127.0.0.1:7897
export https_proxy=http://127.0.0.1:7897
# 取消代理
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY# 检查 Clash 是否运行
# macOS/Linux:
ps aux | grep -i clash
# Windows:
tasklist | findstr clash
# 测试 API
curl --noproxy "*" http://127.0.0.1:9097/proxies- 确认使用的是 8901 端口(不是 7897)
- 确认 Clash 运行模式为 Global:
curl --noproxy "*" http://127.0.0.1:9097/configs | python -m json.tool | grep mode - 运行验证脚本:
python test_connection.py 127.0.0.1 9097 <secret> 8901
python scripts/find_clash_config.py- 快速开始 - 详细的安装和配置指南
- 启用 API - 如何启用 Clash External Controller
- Clash 配置 - Clash 客户端配置说明
- Clash Verge 配置 - Clash Verge 专项配置
config.yaml包含 API 密码,已在.gitignore中- 不要将订阅链接提交到代码仓库
- 使用
config.example.yaml作为模板分享
MIT License