批量检测mihomo节点里gemini和gpt可用性脚本

从 不科学手动测试节点质量的一点小思路 说起,当时我就在想,节点的质量到底怎么检测才是真实有效,从不科学手动测试里,我的想法就是,只有真实的去测试每个对应的项目,才能得出对应渠道数据库的黑ip,不黑的话,那就是好ip,但是手动太累了,就ai写了个py,批量检测下。
因为散热器炸了,换好新的散热,我就想,先把ai方面检测了吧,遂有了下面的python,恢复公益站 心尘公益 API 沉浸式翻译 第四批已领完 已恢复 的使用,以防其他没问题,被ip绊住了。
下午我自己测了下,基本没啥问题,但是有些前提哈,仅适合使用clash客户端或者mihomo(我自己用)这样的,然后有自己newapi聚合站有基础的打野gemini+论坛公益的gpt的佬们用。

我曾想过各种杂七杂八检测gemini和gpt的方式,论坛我看佬们也晒了蛮多,但是我用了下发现不尽人意,明明检测是ok的,实际使用就被墙,明明检测是无效节点,但是gemini和gpt跑的飞快,后来我想了下,还是最原始的操作吧,我直接对话批量检测,慢归慢,扫出来的节点有效能用才ok,对喽,因为有的节点延迟太高,对话时间超时,也会归类为无效节点,我想这类节点,哪怕能用,10秒都连不上,这么不稳定,无效就无效吧。

节点数量少,几个十几个,手动很方便,但是节点多了,真的太痛苦了,还是批量吧。

覆写js,保证auto分组

// AUTO测试组
function main(config) {
  const proxyCount = config?.proxies?.length ?? 0;
  try {
    if (config.proxies && config.proxies.length > 0) {
      console.log("原始代理节点列表:");
      config.proxies.forEach(proxy => {
        console.log(`- ${proxy.name || '未知名称'}`);
      });
    }
//全局屏蔽
    const specificNodesToBlock = [
//gemini gpt双不支持
  "节点名字",
    ].sort(naturalSort);
    
    // 屏蔽包含特定关键字的节点
    const blockedKeywords = ["氪金分割线", "????","中国", "群", "续费", "充值后可解锁更多节点哦", "分割", "充值", "剩余", "失联", "余额", "永久", "分享", "备用", "前往", "恢复", "webshare", "建议", "标准", "持续", "后台", "重置", "距离", "年付", "邀请", "返利", "循环", "官网", "客服", "网站", "网址", "获取", "订阅", "流量", "到期", "机场", "下次", "版本", "官址", "过期", "已用", "联系", "邮箱", "工单", "贩卖", "通知", "倒卖", "防止", "国内", "地址", "频道", "无法", "说明", "使用", "提示", "特别", "访问", "支持", "付费", "失联", "设置", "总计", "澳门", "升级", "解锁"];
      if (config.proxies && config.proxies.length > 0) {
        console.log("开始过滤代理节点...");
        config.proxies = config.proxies.filter(proxy => {
          // 增加一个检查,确保 proxy 是一个有效的对象
          if (!proxy) {
            console.log("过滤掉无效代理: null/undefined");
            return false; // 过滤掉 null 或 undefined 的代理
          }
          const originalName = proxy.name || '';
          const name = originalName.toLowerCase();
          const server = proxy.server || '';
          const port = proxy.port || 0;
          const password = proxy.password || '';
          console.log(`正在处理代理: ${originalName}`);
          // 检查是否为需要精确屏蔽的节点
          const isSpecificallyBlocked = specificNodesToBlock.includes(originalName);
          if (isSpecificallyBlocked) {
            console.log(`  - ${originalName} 被精确屏蔽`);
            return false; // 如果匹配,则屏蔽该节点
          }
          // 检查是否包含被屏蔽的关键字
          const hasBlockedKeyword = blockedKeywords.some(keyword => {
            if (typeof keyword === 'string') {
              const result = name.includes(keyword);
              if (result) console.log(`  - ${originalName} 匹配字符串关键字: ${keyword}`);
              return result;
            } else if (keyword instanceof RegExp) {
              const result = keyword.test(originalName); // 使用 originalName 进行正则匹配
              if (result) console.log(`  - ${originalName} 匹配正则表达式关键字: ${keyword}`);
              return result;
            }
            return false;
          });
          const shouldKeep = !isSpecificallyBlocked && !hasBlockedKeyword;
          console.log(`  - ${originalName} 最终保留状态: ${shouldKeep}`);
          return shouldKeep;
        });
        console.log("代理节点过滤完成,剩余节点数:", config.proxies.length);
        
        // 处理重复节点名称,添加数字后缀
        const nameCount = {};
        config.proxies = config.proxies.map(proxy => {
          const originalName = proxy.name || '';
          if (nameCount[originalName]) {
            nameCount[originalName]++;
            proxy.name = `${originalName}${nameCount[originalName]}`;
          } else {
            nameCount[originalName] = 1;
          }
          return proxy;
        });
        console.log("节点重命名完成");
      }
    } catch (error) {
      console.error("代理节点过滤过程中发生错误:", error);
    }
  if (proxyCount === 0) {
    throw new Error("配置文件中未找到任何代理");
  }
  // 覆盖原配置中DNS配置
  config["dns"] = dnsConfig;
  // 覆盖原配置中的代理组
  config["proxy-groups"] = proxyGroupConfig;
  // 覆盖原配置中的规则
  config["rule-providers"] = ruleProviders;
  config["rules"] = rules;
  //覆盖通用配置
  config["mixed-port"] = 7890;
  config["allow-lan"] = true;
  config["bind-address"] = "*";
  config["ipv6"] = true;
  config["unified-delay"] = true;
  // 返回修改后的配置
  return config;
}
// DNS配置
const dnsConfig = {
  "enable": true,
  "ipv6": false,
  "listen": ":53",
  "prefer-h3": false,
  "respect-rules": true,
  "enhanced-mode": "fake-ip",
  "fake-ip-range": "198.18.0.1/16",
  "fake-ip-filter": [
    // 本地主机/设备
    "+.lan",
    "+.local",
    // Windows网络出现小地球图标
    "+.msftconnecttest.com",
    "+.msftncsi.com",
    // QQ快速登录检测失败
    "localhost.ptlogin2.qq.com",
    "localhost.sec.qq.com",
    // 微信快速登录检测失败
    "localhost.work.weixin.qq.com"
  ],
    "use-hosts": false,
    "use-system-hosts": false,
    "nameserver": ["https://1.1.1.1/dns-query", "https://dns.google/dns-query"], // 国外默认的域名解析服务器
    "default-nameserver": ["tls://223.5.5.5", "tls://119.29.29.29"],  //国内默认DNS 用于解析 DNS服务器 的域名
    "proxy-server-nameserver": ["https://doh.pub/dns-query"],
    "direct-nameserver": ['https://doh.pub/dns-query','https://dns.alidns.com/dns-query'],   //用于 direct 出口域名解析的 DNS 服务器
    "nameserver-policy": {
         "geosite:cn": ["https://doh.pub/dns-query"],
         "geolocation-!cn": ["https://1.1.1.1/dns-query", "https://dns.google/dns-query"]
      }
  }
  
// 代理组通用配置
// 代理组通用配置 - 基础版 (用于 select 等不主动测速的组)
const groupBaseOption = {
  "timeout": 10000,
  "url": "https://www.gstatic.com/generate_204",
  "max-failed-times": 3,
  "hidden": false
};
// 健康检查组通用配置 (用于 url-test, fallback 等)
const healthCheckGroupOption = {
  ...groupBaseOption,
  "interval": 600, // 每600秒检查一次
  "lazy": false, // 启动时立即检查
};
// 代理组排除过滤器
// Helper function to create a regex filter from a node list
const createExcludeFilter = (nodes) => {
  if (!nodes || nodes.length === 0) {
    return "";
  }
  // Escape special regex characters in each node name
  const escapedNodes = nodes.map(name => name.replace(/[.*+?^${}()|[]]/g, '$&'));
  return `(?i)${escapedNodes.join('|')}`;
};
const naturalSort = (a, b) => a.localeCompare(b, 'zh-CN', { numeric: true });
const excludeForAUTONodes = [
];
// Gemini 排除的节点列表【不支持】
const excludeForGeminiNodes = [
//批量检查不能用
  "节点名字",
].sort(naturalSort);
// OpenAI 排除的节点列表【不支持】
const excludeForOpenAINodes = [
//批量检查不能用
  "节点名字",
].sort(naturalSort);
// 使用辅助函数生成最终的过滤器字符串
const excludeForAUTO = createExcludeFilter(excludeForAUTONodes);
const excludeForGemini = createExcludeFilter(excludeForGeminiNodes);
const excludeForOpenAI = createExcludeFilter(excludeForOpenAINodes);
// 代理组规则
const proxyGroupConfig = [
  {
    ...groupBaseOption,
    "name": "AUTO",
    "type": "select",
    "include-all": true,
    "tolerance": 50,
    "exclude-filter": excludeForAUTO,
    "icon": "https://cdn.jsdelivr.net/gh/Koolson/Qure@master/IconSet/Color/Speedtest.png"
  }
];
 // 规则集通用配置
 const ruleProviderCommon = {
  "type": "http",
  "format": "yaml",
  "interval": 86400,
  "proxy": "AUTO"
};
// 规则集配置
const ruleProviders = {
  "OpenAI": {
    ...ruleProviderCommon,
    "behavior": "classical",
    "url": "https://cdn.jsdelivr.net/gh/lianwusuoai/clash_rule@master/rule/Clash/OpenAI/OpenAI.yaml",
    "path": "./ruleset/OpenAI.yaml"
  },
  "Gemini": {
    ...ruleProviderCommon,
    "behavior": "classical",
    "url": "https://cdn.jsdelivr.net/gh/lianwusuoai/clash_rule@master/rule/Clash/Gemini/Gemini.yaml",
    "path": "./ruleset/Gemini.yaml"
  },
};
// 规则
const rules =  [
  "DOMAIN-SUFFIX,openai.com,AUTO",
  "DOMAIN-SUFFIX,googleapis.com,AUTO",
  //规则组
  "RULE-SET,Gemini,AUTO",
  "RULE-SET,OpenAI,AUTO",
  //自定义 大公司包含关键字--代理
  "DOMAIN-KEYWORD,googleapis,AUTO",
  "DOMAIN-KEYWORD,openai.com,AUTO",
  //自定义 大公司包含关键字--直连
  "DOMAIN-KEYWORD,12306,DIRECT",
  "DOMAIN-KEYWORD,alipay,DIRECT",
  "DOMAIN-KEYWORD,baidu,DIRECT",
  "DOMAIN-KEYWORD,douyin,DIRECT",
  "DOMAIN-KEYWORD,gov.cn,DIRECT",
  "DOMAIN-KEYWORD,immersivetranslate,DIRECT",
  "DOMAIN-KEYWORD,jd,DIRECT",
  "DOMAIN-KEYWORD,quark,DIRECT",
  "DOMAIN-KEYWORD,qq,DIRECT",
  "DOMAIN-KEYWORD,sogou,DIRECT",
  "DOMAIN-KEYWORD,taobao,DIRECT",
  "DOMAIN-KEYWORD,tencent,DIRECT",
  "DOMAIN-KEYWORD,Thunder,DIRECT",
  "DOMAIN-KEYWORD,xiaohongshu,DIRECT",
  "DOMAIN-KEYWORD,xiaomi,DIRECT",
  "DOMAIN-KEYWORD,xunlei,DIRECT",
  "DOMAIN-KEYWORD,youku,DIRECT",
  "DOMAIN-KEYWORD,zhihu,DIRECT",
  //自定义网站组-代理
  "DOMAIN-SUFFIX,linux.do,AUTO",
  "DOMAIN-SUFFIX,linux.edu.com,AUTO",
  "DOMAIN-SUFFIX,linux.edu.com.lv,AUTO",
  "DOMAIN-SUFFIX,veloera.wei.bi,AUTO",
  //软件组
  "PROCESS-NAME,douyin_tray.exe,DIRECT",
  // 自定义 IP-CIDR 规则
  'IP-CIDR,127.0.0.0/8,DIRECT',
  'IP-CIDR,192.168.0.0/16,DIRECT',
  'GEOIP,CN,DIRECT',
  'GEOIP,private,DIRECT',
  // 国内直连
  "MATCH,AUTO"
];



使用真实的url+key进行检测真实使用环境
CHAT_COMPLETIONS_URL = 填写自己newapi的url
API_KEY =填写自己newapi的key

AI连通性检测.py
import requests
import time
from datetime import datetime
import sys
import re
import os
import json
# --- 全局配置 ---
CONTROLLER_PORT = 7891
PROXY_PORT = 7890
API_KEY = "填写自己newapi的key"
CHAT_COMPLETIONS_URL = "http://填写自己的/v1/chat/completions"
MAIN_SELECTOR = "AUTO"
OVERRIDE_JS_PATH = "data/override/198289f8d6f.js"
SWITCH_DELAY = 2
API_TIMEOUT = 10 # API请求的超时时间(秒)
# --- JS解析与API交互 ---
def parse_js_exclusions(js_content, var_name):
    """从JS代码字符串中解析出指定的数组变量内容"""
    try:
        match = re.search(fr'consts+{var_name}s*=s*[([sS]*?)]', js_content)
        if not match:
            print(f"  - 警告: 未在JS文件中找到变量 '{var_name}'。")
            return set()
        
        content_inside_brackets = match.group(1)
        nodes = re.findall(r'["'](.*?)["']', content_inside_brackets)
        cleaned_nodes = {node.strip() for node in nodes}
        print(f"  - 成功解析变量 '{var_name}',找到 {len(cleaned_nodes)} 个排除节点。")
        return cleaned_nodes
    except Exception as e:
        print(f"  - 错误: 解析JS变量 '{var_name}' 时发生错误: {e}")
        return set()
def check_api_connection(port):
    print(f"正在尝试连接到 API 控制器,地址: http://127.0.0.1:{port}")
    try:
        response = requests.get(f"http://127.0.0.1:{port}/", timeout=3)
        if response.status_code in [200, 302]:
            print("✓ API 控制器连接成功!")
            return True
    except Exception:
        pass
    print(f"✗ 无法连接到 API 控制器,请检查端口 {port} 是否正确以及Mihomo/Clash是否正在运行。")
    return False
def get_group_proxies(port, group_name):
    print(f"正在从策略组 '{group_name}' 获取全量节点列表...")
    try:
        url = f"http://127.0.0.1:{port}/proxies/{group_name}"
        response = requests.get(url, timeout=5)
        response.raise_for_status()
        proxies = response.json().get('all', [])
        cleaned_proxies = {p.strip() for p in proxies}
        print(f"✓ 成功获取到 {len(cleaned_proxies)} 个唯一节点。")
        return cleaned_proxies
    except Exception as e:
        print(f"✗ 获取策略组 '{group_name}' 节点时发生错误: {e}")
        return set()
def get_nodes_delay(port, nodes_to_check):
    print("正在一次性获取所有节点的延迟数据...")
    try:
        url = f"http://127.0.0.1:{port}/proxies"
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        proxies_data = response.json().get('proxies', {})
        delay_info = {}
        for node in nodes_to_check:
            details = proxies_data.get(node, {})
            history = details.get('history', [])
            delay = history[-1].get('delay', 0) if history else 0
            delay_info[node] = delay
        print(f"✓ 成功获取到 {len(delay_info)} 个目标节点的延迟数据。")
        return delay_info
    except Exception as e:
        print(f"✗ 获取节点延迟信息时发生错误: {e}")
        return None
def switch_proxy(port, selector_name, proxy_name):
    try:
        url = f"http://127.0.0.1:{port}/proxies/{selector_name}"
        payload = {"name": proxy_name}
        requests.put(url, json=payload, timeout=3).raise_for_status()
        return True
    except Exception as e:
        print(f"  ✗ 切换到节点 '{proxy_name}' 失败: {e}")
        return False
def get_current_proxy(port, selector_name):
   try:
       url = f"http://127.0.0.1:{port}/proxies/{selector_name}"
       response = requests.get(url, timeout=3)
       response.raise_for_status()
       return response.json().get('now')
   except Exception:
       return None
def close_all_connections(port):
    """强制关闭所有活动的代理连接,确保切换后使用新节点。静默执行。"""
    try:
        requests.delete(f"http://127.0.0.1:{port}/connections", timeout=2)
        # 静默执行,不打印任何信息
    except Exception:
        # 静默执行,忽略错误
        pass
# --- 连接测试函数 (V22 最终版) ---
def test_gemini_connection(proxy_port):
    proxies = {'http': f'http://127.0.0.1:{proxy_port}', 'https': f'http://127.0.0.1:{proxy_port}'}
    headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
    data = {"model": "gemini-1.5-flash", "messages": [{"role": "user", "content": "hi"}], "max_tokens": 10}
    try:
        # 直接使用 requests.post,确保每次都是独立连接,不受连接池影响
        response = requests.post(CHAT_COMPLETIONS_URL, headers=headers, json=data, proxies=proxies, timeout=API_TIMEOUT)
        if response.status_code == 200:
            response_json = response.json()
            if response_json and 'choices' in response_json and len(response_json['choices']) > 0:
                return '支持'
        return '不支持'
    except Exception:
        return '超时'
def test_openai_connection(proxy_port):
    proxies = {'http': f'http://127.0.0.1:{proxy_port}', 'https': f'http://127.0.0.1:{proxy_port}'}
    headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
    data = {"model": "gpt-4.1-nano", "messages": [{"role": "user", "content": "hi"}], "max_tokens": 10}
    try:
        # 直接使用 requests.post,确保每次都是独立连接,不受连接池影响
        response = requests.post(CHAT_COMPLETIONS_URL, headers=headers, json=data, proxies=proxies, timeout=API_TIMEOUT)
        if response.status_code == 200:
            response_json = response.json()
            if response_json and 'choices' in response_json and len(response_json['choices']) > 0:
                return '支持'
        return '不支持'
    except Exception:
        return '超时'
# --- 结果处理与写入 ---
def write_final_report(results, timestamp):
    filename = f"测速/AI问题节点报告_{timestamp}.yaml"
    report = {"全部不支持": [], "不支持 Gemini": [], "不支持 OpenAI": [], "超时节点": results.get("timeout_nodes", [])}
    
    for node, res in results.items():
        if node == "timeout_nodes": continue
        gemini_ok = res.get("Gemini") == "支持"
        openai_ok = res.get("OpenAI") == "支持"
        
        if "Gemini" in res and "OpenAI" in res:
            if not gemini_ok and not openai_ok: report["全部不支持"].append(node)
        
        if "Gemini" in res and not gemini_ok: report["不支持 Gemini"].append(node)
        if "OpenAI" in res and not openai_ok: report["不支持 OpenAI"].append(node)
            
    yaml_content = [f"报告名称: AI服务问题节点报告", f"测试时间: {timestamp}"]
    for category, nodes in report.items():
        yaml_content.append(f"
# {category}")
        yaml_content.append(f"{category}:")
        if nodes:
            unique_nodes = sorted(list(set(nodes)))
            for node in unique_nodes:
                yaml_content.append(f'  "{node}",')
    
    with open(filename, 'w', encoding='utf-8') as f:
        f.write('
'.join(yaml_content))
    print(f"
✓ 问题节点报告已保存到: {filename}")
# --- 主函数 (V22) ---
def main():
    print("=" * 50)
    print(" Mihomo/Clash AI 服务测试脚本 (V22 - 最终版)")
    print("=" * 50)
    if not check_api_connection(CONTROLLER_PORT): sys.exit(1)
    print("
--- 步骤 1: 解析JS获取排除列表 ---")
    if not os.path.exists(OVERRIDE_JS_PATH):
        print(f"✗ 错误: 找不到 override.js 文件,路径: {OVERRIDE_JS_PATH}")
        sys.exit(1)
    with open(OVERRIDE_JS_PATH, 'r', encoding='utf-8') as f:
        js_code = f.read()
    exclude_nodes = parse_js_exclusions(js_code, 'excludeForAUTONodes')
    print("
--- 步骤 2: 计算测试范围 ---")
    all_auto_nodes = get_group_proxies(CONTROLLER_PORT, MAIN_SELECTOR)
    if not all_auto_nodes:
        print("✗ 未能从'AUTO'组获取任何节点,测试无法继续。")
        sys.exit(1)
    
    total_nodes_to_check = all_auto_nodes - exclude_nodes
    print(f"  - 总计待测节点 (去重后): {len(total_nodes_to_check)} 个节点")
    print("
--- 步骤 3: 预先筛选超时节点 ---")
    delays = get_nodes_delay(CONTROLLER_PORT, total_nodes_to_check)
    if delays is None: sys.exit(1)
    
    timeout_nodes = {name for name, delay in delays.items() if delay == 0}
    available_nodes = total_nodes_to_check - timeout_nodes
    print(f"  - 发现 {len(timeout_nodes)} 个超时节点,将不参与后续测试。")
    
    print("
--- 步骤 4: 执行统一调度测试 ---")
    final_results = {"timeout_nodes": list(timeout_nodes)}
    
    sorted_available_nodes = sorted(list(available_nodes))
    print(f"
--- 步骤 4: 执行独立连接测试 ---")
    print(f"- 将对以下 {len(sorted_available_nodes)} 个可用节点进行测试...")
    
    total_node_count = len(sorted_available_nodes)
    for i, node in enumerate(sorted_available_nodes):
        current_progress = f"{i+1}/{total_node_count}"
        print(f"
- {current_progress} 测试节点: {node}")
        if not switch_proxy(CONTROLLER_PORT, MAIN_SELECTOR, node):
            continue
        
        # 核心修复:强制关闭所有活动连接,确保新节点生效(静默)
        close_all_connections(CONTROLLER_PORT)
        time.sleep(SWITCH_DELAY) # 等待连接重置和路由刷新
        
        final_results[node] = {}
        results_line = []
        
        # 同时测试 Gemini 和 OpenAI
        gemini_result = test_gemini_connection(PROXY_PORT)
        final_results[node]["Gemini"] = gemini_result
        results_line.append(f"Gemini: {gemini_result}")
        
        openai_result = test_openai_connection(PROXY_PORT)
        final_results[node]["OpenAI"] = openai_result
        results_line.append(f"OpenAI: {openai_result}")
        
        print(f"  → {'       '.join(results_line)}")
    print("
- 测试完成,不恢复节点选择。")
    write_final_report(final_results, datetime.now().strftime("%Y-%m-%d_%H-%M"))
    print("
--- 所有测试完成 ---")
if __name__ == "__main__":
    main()


9e6a97d7092310783f15e4d57876fe981aaaca5e.jpg

    
然后你会得到不支持的节点名,丢到覆写js的gemini和openai分组单独屏蔽就好啦。

对于超时的节点,有空再针对测试下超时的节点就好啦
HISTORY_REPORT_PATH = “测速/AI问题节点报告_2025-08-08_16-11.yaml”
就是找当前文件夹“测速”下面刚测完的文件,文件里有超时的节点信息,针对这些超时的单独测

import requests
import time
from datetime import datetime
import sys
import re
import os
import json
import yaml
# --- 全局配置 ---
CONTROLLER_PORT = 7891
PROXY_PORT = 7890
API_KEY = "同上  写自己的newapi的key"
CHAT_COMPLETIONS_URL = "http://同上/v1/chat/completions"
MAIN_SELECTOR = "AUTO"
OVERRIDE_JS_PATH = "data/override/auto.js"
HISTORY_REPORT_PATH = "测速/AI问题节点报告_2025-08-08_16-11.yaml"  # 历史报告文件路径
SWITCH_DELAY = 2
API_TIMEOUT = 10 # API请求的超时时间(秒)
# --- JS解析与API交互 ---
def parse_js_exclusions(js_content, var_name):
    """从JS代码字符串中解析出指定的数组变量内容"""
    try:
        match = re.search(fr'consts+{var_name}s*=s*[([sS]*?)]', js_content)
        if not match:
            print(f"  - 警告: 未在JS文件中找到变量 '{var_name}'。")
            return set()
        
        content_inside_brackets = match.group(1)
        nodes = re.findall(r'["'](.*?)["']', content_inside_brackets)
        cleaned_nodes = {node.strip() for node in nodes}
        print(f"  - 成功解析变量 '{var_name}',找到 {len(cleaned_nodes)} 个排除节点。")
        return cleaned_nodes
    except Exception as e:
        print(f"  - 错误: 解析JS变量 '{var_name}' 时发生错误: {e}")
        return set()
def parse_timeout_nodes_from_report(report_path):
    """从历史报告文件中解析超时节点列表"""
    print(f"正在从历史报告文件中解析超时节点: {report_path}")
    try:
        if not os.path.exists(report_path):
            print(f"  - 警告: 找不到历史报告文件,路径: {report_path}")
            return set()
        
        timeout_nodes = set()
        current_category = None
        
        with open(report_path, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                # 检查是否是分类标题
                if line.startswith("# "):
                    current_category = line[2:]  # 去掉"# "
                # 检查是否是超时节点分类
                elif current_category == "超时节点" and line.startswith('"'):
                    # 提取节点名称,去掉引号和可能的逗号
       &
        											
汇总网页前端与后端开发中遇到的高频疑难问题,附带详尽的技术解决文档和调试笔记,帮助开发者快速定位并解决实际问题。包揽全网大多数网站源码教程,提供小程序、公众号、APP、H5、商城、支付、游戏、区块链、直播、影音、小说等 源码 教程。
用户必须遵守《计算机软件保护条例(2013修订)》第十七条:为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。鉴于此条例,用户从本平台下载的全部源码(软件)教程仅限学习研究,未经版权归属者授权不得商用,若因商用引起的版权纠纷,一切责任均由使用者自行承担,本平台所属公司及其雇员不承担任何法律责任。
汇总网页前端与后端开发中遇到的高频疑难问题,附带详尽的技术解决文档和调试笔记,帮助开发者快速定位并解决实际问题。 » 批量检测mihomo节点里gemini和gpt可用性脚本

粤ICP备2023047419号   Copyright © 2018-2025 肇庆市火石科技有限公司   All Rights Reserved   XML地图