下载
GitHub项目地址:https://github.com/wzdnzd/aggregator
下载包上传到青龙的data/scripts文件夹内
两种方式:
青龙直接拉取
下载zip包
创建文件夹aggregator到scripts内(根据方便重命名)
安装青龙依赖
PyYAML tqdm geoip2 pycryptodomex fofa-hack requests urllib3
创建环境
gist 创建与 api 获取
创建gist https://gist.github.com/创建clash.yaml 文件,内容随意
保存用户名后面的根路径
再创建GitHub token,https://github.com/settings/personal-access-tokens
创建gist读写权限,日期随意,
在文件subscribe目录下创建merged2upload.py文件
内容
import requests
import base64
import os
import time
import urllib3
# 禁用 SSL 警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def fetch_and_decode_base64(url, timeout=10, retries=2, backoff_factor=2):
print(f"Fetching {url}")
for attempt in range(retries):
try:
response = requests.get(url, timeout=timeout, verify=False) # 注意:verify=False 在生产环境中是不安全的
response.raise_for_status()
print(f"Successfully fetched {url} on attempt {attempt + 1}")
response_bytes = response.content
# 添加填充,如果需要
padding = '=' * (-len(response_bytes) % 4)
response_bytes += padding.encode('utf-8')
# 解码 base64
decoded_bytes = base64.b64decode(response_bytes)
# 尝试解码为 UTF-8,如果失败,则返回空字符串
try:
decoded_content = decoded_bytes.decode('utf-8')
except UnicodeDecodeError:
print(f"Warning: Non-UTF-8 content detected from {url}. Skipping this content.")
decoded_content = "" # 返回空字符串而不是原始字节串
return decoded_content
except requests.RequestException as e:
print(f"Error fetching {url} on attempt {attempt + 1}: {e}")
if attempt < retries - 1:
time.sleep(backoff_factor * (2 ** attempt))
return None
def upload_to_gist(content, gist_id, github_token):
url = f"https://api.github.com/gists/{gist_id}"
headers = {
'Authorization': f'token {github_token}',
'Accept': 'application/vnd.github.v3+json'
}
data = {
"files": {
"configsub.yaml": {
"content": content
}
}
}
try:
response = requests.patch(url, headers=headers, json=data)
response.raise_for_status()
print(f"Successfully updated Gist: {gist_id}")
except requests.RequestException as e:
print(f"Error updating Gist: {e}")
def main():
print("Starting the script...")
current_dir = os.path.dirname(__file__)
parent_dir = os.path.dirname(current_dir)
file_path = os.path.join(parent_dir, 'data', 'subscribes.txt')
with open(file_path, 'r') as file:
urls = file.read().strip().split('\n')
all_decoded_texts = []
for url in urls:
print(f"Processing URL: {url}")
decoded_content = fetch_and_decode_base64(url)
if decoded_content: # 确保只添加非空字符串
all_decoded_texts.append(decoded_content)
print(f"Decoded content from {url} added to the list.")
# 确保列表中的所有元素都是字符串
merged_content = "\n".join(all_decoded_texts)
encoded_merged_content = base64.b64encode(merged_content.encode('utf-8')).decode('utf-8')
merged_file_path = os.path.join(parent_dir, 'data', 'merged.txt')
with open(merged_file_path, 'w') as file:
file.write(encoded_merged_content)
print(f"Encoded merged content written to {merged_file_path}")
# 定义环境变量
github_token = 'GITHUB_TOKEN'
GIST_ID = 'GIST_ID'
# 从环境变量中读取
github_token = os.environ.get('GITHUB_TOKEN')
gist_id = os.environ.get('GIST_ID')
# 检查环境变量是否设置
if github_token is None or gist_id is None:
print("环境变量 GITHUB_PAT 和 GIST_ID 必须设置。")
exit(1)
# 将合并后的内容上传到Gist
print(f"正在将合并后的内容上传到Gist: {gist_id}")
upload_to_gist(encoded_merged_content, gist_id, github_token)
print("脚本执行成功。")
if __name__ == "__main__":
main()
赋予变量
# 定义环境变量
github_token = ‘GITHUB_TOKEN’
GIST_ID = ‘GIST_ID’
根据实际情况填写

全自动运行重点
在aggregator文件目录下创建clash_sub_collector.sh文件
内容:
#!/bin/bash # 设置HTTP代理(根据自己的需要开启,需要的话去掉#,记得换成自己的代理地址!!!!!) #export http_proxy="http://your.proxy.server:8080" #export https_proxy="http://your.proxy.server:8080" # 运行机场获取脚本 echo "Running collect.py script..." python -u ./subscribe/collect.py -si #根据实际目录填写 # 运行gits上传脚本 echo "Running merged2upload.py script..." python ./subscribe/merged2upload.py #根据实际目录填写 # 取消代理设置(上面如果开启,记得把下面也一起打开) #unset http_proxy #unset https_proxy
在青龙面板创建任务
名称随意
命令/脚本
aggregator/clash_sub_collector.sh
定时规则
0 8,17 * * *

