-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcfst.py
209 lines (176 loc) · 7.5 KB
/
cfst.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
import os
import subprocess
import csv
import sys
import requests
import json
import random
import time
from colo_emojis import colo_emojis
from sk import remove_unreachable_ips
# ------------------------------
# 初始化设置
# ------------------------------
# 检查是否已安装 requests
try:
import requests
print("requests 已安装")
except ImportError:
print("requests 未安装,正在安装...")
subprocess.check_call([sys.executable, "-m", "pip", "install", "requests"])
# 获取当前脚本的路径
script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
# 切换到当前脚本所在的目录
os.chdir(script_dir)
# 创建所需的目录
os.makedirs("csv", exist_ok=True)
os.makedirs("log", exist_ok=True)
os.makedirs("port", exist_ok=True)
os.makedirs("cfip", exist_ok=True)
os.makedirs("speed", exist_ok=True)
# 定义文件路径和变量
cfst_path = "cfst"
result_file = "csv/result.csv"
cfip_file = "cfip/ip.txt"
output_txt = "cfip/ip.txt"
port_txt = "port/ipport.txt"
log_file = "log/log.txt"
output_cf_txt = "speed/ip.txt"
proxy_txt = "cfip/proxy.txt"
iplog_file = "log/iplog.txt"
commit_message = "Update result.csv and ip.txt"
download_url = "https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.2.5/CloudflareST_linux_arm64.tar.gz"
# 定义 cfcolo 变量(目标区域)
cfcolo = "HKG,LAX,SJC,SEA,SFO,SIN,TPE" # HKG,ICN,LAX,SJC,ORD,NRT,HND,FRA,SIN,LHR,TPE
# Cloudflare 支持的标准端口列表
cf_ports = [443, 2053, 2083, 2087, 2096, 8443]
# 随机选择 Cloudflare 的标准端口
random_port = random.choice(cf_ports)
# 获取下载文件的文件名
downloaded_file = download_url.split("/")[-1]
# ------------------------------
# 工具函数
# ------------------------------
def remove_file(file_path):
"""删除指定路径的文件"""
if os.path.exists(file_path):
os.remove(file_path)
print(f"已删除 {file_path} 文件。")
def get_colo(ip_address):
"""获取 IP 的 colo 信息,并写入日志文件"""
# 使用 Cloudflare 的 cdn-cgi/trace API
api_url = f'http://{ip_address}/cdn-cgi/trace' # 使用 HTTP
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
'Connection': 'keep-alive',
}
try:
# 增加超时时间(连接超时 10 秒,读取超时 20 秒)
response = requests.get(api_url, headers=headers, timeout=(5, 10))
if response.status_code == 200:
data = response.text
# 将完整的响应数据写入日志文件
with open(log_file, mode="a", encoding="utf-8") as log:
log.write(f"完整数据来自 {ip_address}:\n")
log.write(data + "\n\n")
# 解析 colo 信息
colo = "CF优选"
for line in data.splitlines():
if line.startswith("colo="):
colo = line.split("=")[1]
break
# 返回 colo
return f"{colo}"
else:
print(f"API 请求失败,IP {ip_address} 状态码: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"API 请求出错,IP {ip_address}: {e}")
# 降低请求频率,每次请求后等待 5 秒
time.sleep(5)
# 默认返回值
return "CF优选"
# ------------------------------
# 主程序逻辑
# ------------------------------
# 检查 cfst 文件是否存在
if not os.path.exists(cfst_path):
print(f"文件 {cfst_path} 不存在,正在执行安装和测试命令...")
subprocess.run(["wget", "-N", download_url], check=True)
if downloaded_file.endswith(".tar.gz"):
try:
subprocess.run(["tar", "-zxf", downloaded_file], check=True)
print(f"已成功解压: {downloaded_file}")
except subprocess.CalledProcessError as e:
print(f"解压失败: {e}")
sys.exit(1)
elif downloaded_file.endswith(".zip"):
try:
subprocess.run(["unzip", downloaded_file], check=True)
print(f"已成功解压: {downloaded_file}")
except subprocess.CalledProcessError as e:
print(f"解压失败: {e}")
sys.exit(1)
else:
print("无法识别的压缩文件格式!")
sys.exit(1)
remove_file(downloaded_file)
subprocess.run(["mv", "CloudflareST", "cfst"], check=True)
subprocess.run(["chmod", "+x", "cfst"], check=True)
# 删除 result.csv 和 ip.txt 以及 log.txt 文件
remove_file(result_file)
remove_file(cfip_file)
remove_file(log_file)
# 执行 cfst 命令,使用变量传递 cfcolo 和随机端口
subprocess.run(["./cfst", "-o", "csv/result.csv", "-httping", "-cfcolo", cfcolo, "-tl", "150", "-tll", "20", "-tp", str(random_port), "-dn", "20"], check=True)
# 提取 IP 地址和下载速度,并保存到 ip.txt 和 ipport.txt
ip_addresses = []
download_speeds = []
with open(result_file, mode="r", encoding="utf-8") as csvfile:
reader = csv.reader(csvfile)
header = next(reader)
if "下载速度 (MB/s)" in header:
speed_index = header.index("下载速度 (MB/s)")
else:
print("无法找到下载速度列,请检查 CSV 文件表头。")
sys.exit(1)
for row in reader:
ip_addresses.append(row[0])
download_speeds.append(row[speed_index])
if len(ip_addresses) >= 20:
break
# 将 IP 地址和 colo 信息写入 ip.txt
with open(output_txt, mode="w", encoding="utf-8") as txtfile:
for ip, speed in zip(ip_addresses, download_speeds):
colo = get_colo(ip) # 接收 colo 和 proxyip
txtfile.write(f"{ip}#{colo}\n")
print(f"IP: {ip}, colo: {colo}")
print(f"提取的 IP 地址和 colo 信息已保存到 {output_txt}")
# 将 IP 地址、端口、colo 信息和下载速度写入 ipport.txt
with open(port_txt, mode="w", encoding="utf-8") as txtfile:
for ip, speed in zip(ip_addresses, download_speeds):
colo = get_colo(ip)
emoji = colo_emojis.get(colo, "☁️") # 确保 colo_emojis 的键是 colo
txtfile.write(f"{ip}:{str(random_port)}#{emoji}{colo}┃⚡{speed}(MB/s)\n")
print(f"IP: {ip}, Port: {random_port}, colo: {emoji}{colo}, Speed: {speed}")
print(f"提取的 IP 地址、端口、colo 信息和下载速度已保存到 {port_txt}")
remove_unreachable_ips(output_cf_txt, iplog_file)
# 筛选下载速度大于 10 MB/s 的 IP,并追加写入 ip.txt
with open(output_cf_txt, mode="a", encoding="utf-8") as cf_file:
for ip, speed in zip(ip_addresses, download_speeds):
if float(speed) > 10:
colo = get_colo(ip)
emoji = colo_emojis.get(colo, "☁️") # 确保 colo_emojis 的键是 colo
cf_file.write(f"{ip}:{str(random_port)}#{emoji}{colo}┃⚡{speed}(MB/s)\n")
print(f"符合条件的 IP: {ip}, Port: {random_port}, colo: {emoji}{colo}, Speed: {speed}")
print(f"筛选出的 IP 地址、端口、colo 信息和下载速度已追加到 {output_cf_txt}")
# Git 上传步骤
try:
subprocess.run(["git", "add", "."], check=True)
subprocess.run(["git", "commit", "-m", commit_message], check=True)
subprocess.run(["git", "push", "-u", "origin", "main"], check=True)
print("已将文件上传到 GitHub 仓库。")
except subprocess.CalledProcessError as e:
print(f"Git 操作失败: {e}")
sys.exit(1)