diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..10ebf9e --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,40 @@ +name: ClashNodeConverter + +on: + schedule: + - cron: '0 7-22/5 * * *' + push: + paths-ignore: + - '**' + workflow_dispatch: + +jobs: + run_demo_actions: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + # 转到 Settings > Secrets and variables > Actions + # 点击 New repository secret,添加 Secret,名称为 BOT,输入你的token + token: ${{ secrets.BOT }} + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.10.10' + + - name: Install requirements.txt + run: | + pip install -r ./requirements.txt + + - name: Run ClashNodeConverter.py + run: python ClashNodeConverter.py + + - name: Commit and push file + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add clash_config.yaml + git commit -m "update" || echo "No changes to commit" + git push https://${{ secrets.BOT }}:x-oauth-basic@github.com/${GITHUB_REPOSITORY}.git diff --git a/ClashNodeConverter.py b/ClashNodeConverter.py new file mode 100644 index 0000000..74e69cd --- /dev/null +++ b/ClashNodeConverter.py @@ -0,0 +1,1586 @@ +import base64 +import subprocess +import platform +import time +import urllib.parse +import json +import requests +import os +import glob +import re +import yaml +import random +import string +import httpx +import asyncio +from itertools import chain +from typing import Dict, List, Optional +import sys +from datetime import datetime +from asyncio import Semaphore +import ssl +ssl._create_default_https_context = ssl._create_unverified_context +import warnings +warnings.filterwarnings('ignore') +from requests_html import HTMLSession + +TEST_URL = "http://www.gstatic.com/generate_204" +CLASH_API_PORTS = [9090] +CLASH_API_HOST = "127.0.0.1" +CLASH_API_SECRET = "" +TIMEOUT = 2 +MAX_CONCURRENT_TESTS = 100 +CONFIG_FILE = 'clash_config.yaml' +INPUT = "input" # 从文件中加载代理节点,支持yaml/yml、txt(每条代理链接占一行) + +headers = { + 'Accept-Charset': 'utf-8', + 'Accept': 'text/html,application/x-yaml,*/*', + 'User-Agent': 'Clash Verge/1.7.7' +} + +# Clash 配置文件的基础结构 +clash_config_template = { + "port": 7890, + "socks-port": 7891, + "redir-port": 7892, + "allow-lan": True, + "mode": "rule", + "log-level": "info", + "external-controller": "127.0.0.1:9090", + "dns": { + "enable": True, + "ipv6": False, + "default-nameserver": [ + "223.5.5.5", + "119.29.29.29" + ], + "enhanced-mode": "fake-ip", + "fake-ip-range": "198.18.0.1/16", + "use-hosts": True, + "nameserver": [ + "https://doh.pub/dns-query", + "https://dns.alidns.com/dns-query" + ], + "fallback": [ + "https://doh.dns.sb/dns-query", + "https://dns.cloudflare.com/dns-query", + "https://dns.twnic.tw/dns-query", + "tls://8.8.4.4:853" + ], + "fallback-filter": { + "geoip": True, + "ipcidr": [ + "240.0.0.0/4", + "0.0.0.0/32" + ] + } + }, + "proxies": [], + "proxy-groups": [ + { + "name": "节点选择", + "type": "select", + "proxies": [ + "自动选择", + "故障转移", + "DIRECT" + ] + }, + { + "name": "自动选择", + "type": "url-test", + "exclude-filter": "(?i)中国|China|CN|电信|移动|联通", + "proxies": [], + "url": "http://www.gstatic.com/generate_204", + "interval": 300 + }, + { + "name": "故障转移", + "type": "fallback", + "exclude-filter": "(?i)中国|China|CN|电信|移动|联通", + "proxies": [], + "url": "http://www.gstatic.com/generate_204", + "interval": 300 + }, + { + "name": "手动选择", + "type": "select", + "proxies": [] + }, + ], + "rules": [ + "IP-CIDR,80.85.152.22/32,DIRECT,no-resolve", + "IP-CIDR,212.87.195.76/32,DIRECT,no-resolve", + "DOMAIN,209.200.246.194:7002,DIRECT", + "DOMAIN-SUFFIX,services.googleapis.cn,节点选择", + "DOMAIN-SUFFIX,xn--ngstr-lra8j.com,节点选择", + "DOMAIN,safebrowsing.urlsec.qq.com,DIRECT", + "DOMAIN,safebrowsing.googleapis.com,DIRECT", + "DOMAIN,developer.apple.com,节点选择", + "DOMAIN-SUFFIX,digicert.com,节点选择", + "DOMAIN,ocsp.apple.com,节点选择", + "DOMAIN,ocsp.comodoca.com,节点选择", + "DOMAIN,ocsp.usertrust.com,节点选择", + "DOMAIN,ocsp.sectigo.com,节点选择", + "DOMAIN,ocsp.verisign.net,节点选择", + "DOMAIN-SUFFIX,apple-dns.net,节点选择", + "DOMAIN,testflight.apple.com,节点选择", + "DOMAIN,sandbox.itunes.apple.com,节点选择", + "DOMAIN,itunes.apple.com,节点选择", + "DOMAIN-SUFFIX,apps.apple.com,节点选择", + "DOMAIN-SUFFIX,blobstore.apple.com,节点选择", + "DOMAIN,cvws.icloud-content.com,节点选择", + "DOMAIN-SUFFIX,mzstatic.com,DIRECT", + "DOMAIN-SUFFIX,itunes.apple.com,DIRECT", + "DOMAIN-SUFFIX,icloud.com,DIRECT", + "DOMAIN-SUFFIX,icloud-content.com,DIRECT", + "DOMAIN-SUFFIX,me.com,DIRECT", + "DOMAIN-SUFFIX,aaplimg.com,DIRECT", + "DOMAIN-SUFFIX,cdn20.com,DIRECT", + "DOMAIN-SUFFIX,cdn-apple.com,DIRECT", + "DOMAIN-SUFFIX,akadns.net,DIRECT", + "DOMAIN-SUFFIX,akamaiedge.net,DIRECT", + "DOMAIN-SUFFIX,edgekey.net,DIRECT", + "DOMAIN-SUFFIX,mwcloudcdn.com,DIRECT", + "DOMAIN-SUFFIX,mwcname.com,DIRECT", + "DOMAIN-SUFFIX,apple.com,DIRECT", + "DOMAIN-SUFFIX,apple-cloudkit.com,DIRECT", + "DOMAIN-SUFFIX,apple-mapkit.com,DIRECT", + "DOMAIN-SUFFIX,126.com,DIRECT", + "DOMAIN-SUFFIX,126.net,DIRECT", + "DOMAIN-SUFFIX,127.net,DIRECT", + "DOMAIN-SUFFIX,163.com,DIRECT", + "DOMAIN-SUFFIX,360buyimg.com,DIRECT", + "DOMAIN-SUFFIX,36kr.com,DIRECT", + "DOMAIN-SUFFIX,acfun.tv,DIRECT", + "DOMAIN-SUFFIX,air-matters.com,DIRECT", + "DOMAIN-SUFFIX,aixifan.com,DIRECT", + "DOMAIN-KEYWORD,alicdn,DIRECT", + "DOMAIN-KEYWORD,alipay,DIRECT", + "DOMAIN-KEYWORD,taobao,DIRECT", + "DOMAIN-SUFFIX,amap.com,DIRECT", + "DOMAIN-SUFFIX,autonavi.com,DIRECT", + "DOMAIN-KEYWORD,baidu,DIRECT", + "DOMAIN-SUFFIX,bdimg.com,DIRECT", + "DOMAIN-SUFFIX,bdstatic.com,DIRECT", + "DOMAIN-SUFFIX,bilibili.com,DIRECT", + "DOMAIN-SUFFIX,bilivideo.com,DIRECT", + "DOMAIN-SUFFIX,caiyunapp.com,DIRECT", + "DOMAIN-SUFFIX,clouddn.com,DIRECT", + "DOMAIN-SUFFIX,cnbeta.com,DIRECT", + "DOMAIN-SUFFIX,cnbetacdn.com,DIRECT", + "DOMAIN-SUFFIX,cootekservice.com,DIRECT", + "DOMAIN-SUFFIX,csdn.net,DIRECT", + "DOMAIN-SUFFIX,ctrip.com,DIRECT", + "DOMAIN-SUFFIX,dgtle.com,DIRECT", + "DOMAIN-SUFFIX,dianping.com,DIRECT", + "DOMAIN-SUFFIX,douban.com,DIRECT", + "DOMAIN-SUFFIX,doubanio.com,DIRECT", + "DOMAIN-SUFFIX,duokan.com,DIRECT", + "DOMAIN-SUFFIX,easou.com,DIRECT", + "DOMAIN-SUFFIX,ele.me,DIRECT", + "DOMAIN-SUFFIX,feng.com,DIRECT", + "DOMAIN-SUFFIX,fir.im,DIRECT", + "DOMAIN-SUFFIX,frdic.com,DIRECT", + "DOMAIN-SUFFIX,g-cores.com,DIRECT", + "DOMAIN-SUFFIX,godic.net,DIRECT", + "DOMAIN-SUFFIX,gtimg.com,DIRECT", + "DOMAIN,cdn.hockeyapp.net,DIRECT", + "DOMAIN-SUFFIX,hongxiu.com,DIRECT", + "DOMAIN-SUFFIX,hxcdn.net,DIRECT", + "DOMAIN-SUFFIX,iciba.com,DIRECT", + "DOMAIN-SUFFIX,ifeng.com,DIRECT", + "DOMAIN-SUFFIX,ifengimg.com,DIRECT", + "DOMAIN-SUFFIX,ipip.net,DIRECT", + "DOMAIN-SUFFIX,iqiyi.com,DIRECT", + "DOMAIN-SUFFIX,jd.com,DIRECT", + "DOMAIN-SUFFIX,jianshu.com,DIRECT", + "DOMAIN-SUFFIX,knewone.com,DIRECT", + "DOMAIN-SUFFIX,le.com,DIRECT", + "DOMAIN-SUFFIX,lecloud.com,DIRECT", + "DOMAIN-SUFFIX,lemicp.com,DIRECT", + "DOMAIN-SUFFIX,licdn.com,DIRECT", + "DOMAIN-SUFFIX,luoo.net,DIRECT", + "DOMAIN-SUFFIX,meituan.com,DIRECT", + "DOMAIN-SUFFIX,meituan.net,DIRECT", + "DOMAIN-SUFFIX,mi.com,DIRECT", + "DOMAIN-SUFFIX,miaopai.com,DIRECT", + "DOMAIN-SUFFIX,microsoft.com,DIRECT", + "DOMAIN-SUFFIX,microsoftonline.com,DIRECT", + "DOMAIN-SUFFIX,miui.com,DIRECT", + "DOMAIN-SUFFIX,miwifi.com,DIRECT", + "DOMAIN-SUFFIX,mob.com,DIRECT", + "DOMAIN-SUFFIX,netease.com,DIRECT", + "DOMAIN-SUFFIX,office.com,DIRECT", + "DOMAIN-SUFFIX,office365.com,DIRECT", + "DOMAIN-KEYWORD,officecdn,DIRECT", + "DOMAIN-SUFFIX,oschina.net,DIRECT", + "DOMAIN-SUFFIX,ppsimg.com,DIRECT", + "DOMAIN-SUFFIX,pstatp.com,DIRECT", + "DOMAIN-SUFFIX,qcloud.com,DIRECT", + "DOMAIN-SUFFIX,qdaily.com,DIRECT", + "DOMAIN-SUFFIX,qdmm.com,DIRECT", + "DOMAIN-SUFFIX,qhimg.com,DIRECT", + "DOMAIN-SUFFIX,qhres.com,DIRECT", + "DOMAIN-SUFFIX,qidian.com,DIRECT", + "DOMAIN-SUFFIX,qihucdn.com,DIRECT", + "DOMAIN-SUFFIX,qiniu.com,DIRECT", + "DOMAIN-SUFFIX,qiniucdn.com,DIRECT", + "DOMAIN-SUFFIX,qiyipic.com,DIRECT", + "DOMAIN-SUFFIX,qq.com,DIRECT", + "DOMAIN-SUFFIX,qqurl.com,DIRECT", + "DOMAIN-SUFFIX,rarbg.to,DIRECT", + "DOMAIN-SUFFIX,ruguoapp.com,DIRECT", + "DOMAIN-SUFFIX,segmentfault.com,DIRECT", + "DOMAIN-SUFFIX,sinaapp.com,DIRECT", + "DOMAIN-SUFFIX,smzdm.com,DIRECT", + "DOMAIN-SUFFIX,snapdrop.net,DIRECT", + "DOMAIN-SUFFIX,sogou.com,DIRECT", + "DOMAIN-SUFFIX,sogoucdn.com,DIRECT", + "DOMAIN-SUFFIX,sohu.com,DIRECT", + "DOMAIN-SUFFIX,soku.com,DIRECT", + "DOMAIN-SUFFIX,speedtest.net,DIRECT", + "DOMAIN-SUFFIX,sspai.com,DIRECT", + "DOMAIN-SUFFIX,suning.com,DIRECT", + "DOMAIN-SUFFIX,taobao.com,DIRECT", + "DOMAIN-SUFFIX,tencent.com,DIRECT", + "DOMAIN-SUFFIX,tenpay.com,DIRECT", + "DOMAIN-SUFFIX,tianyancha.com,DIRECT", + "DOMAIN-SUFFIX,tmall.com,DIRECT", + "DOMAIN-SUFFIX,tudou.com,DIRECT", + "DOMAIN-SUFFIX,umetrip.com,DIRECT", + "DOMAIN-SUFFIX,upaiyun.com,DIRECT", + "DOMAIN-SUFFIX,upyun.com,DIRECT", + "DOMAIN-SUFFIX,veryzhun.com,DIRECT", + "DOMAIN-SUFFIX,weather.com,DIRECT", + "DOMAIN-SUFFIX,weibo.com,DIRECT", + "DOMAIN-SUFFIX,xiami.com,DIRECT", + "DOMAIN-SUFFIX,xiami.net,DIRECT", + "DOMAIN-SUFFIX,xiaomicp.com,DIRECT", + "DOMAIN-SUFFIX,ximalaya.com,DIRECT", + "DOMAIN-SUFFIX,xmcdn.com,DIRECT", + "DOMAIN-SUFFIX,xunlei.com,DIRECT", + "DOMAIN-SUFFIX,yhd.com,DIRECT", + "DOMAIN-SUFFIX,yihaodianimg.com,DIRECT", + "DOMAIN-SUFFIX,yinxiang.com,DIRECT", + "DOMAIN-SUFFIX,ykimg.com,DIRECT", + "DOMAIN-SUFFIX,youdao.com,DIRECT", + "DOMAIN-SUFFIX,youku.com,DIRECT", + "DOMAIN-SUFFIX,zealer.com,DIRECT", + "DOMAIN-SUFFIX,zhihu.com,DIRECT", + "DOMAIN-SUFFIX,zhimg.com,DIRECT", + "DOMAIN-SUFFIX,zimuzu.tv,DIRECT", + "DOMAIN-SUFFIX,zoho.com,DIRECT", + "DOMAIN-KEYWORD,amazon,节点选择", + "DOMAIN-KEYWORD,google,节点选择", + "DOMAIN-KEYWORD,gmail,节点选择", + "DOMAIN-KEYWORD,youtube,节点选择", + "DOMAIN-KEYWORD,facebook,节点选择", + "DOMAIN-SUFFIX,fb.me,节点选择", + "DOMAIN-SUFFIX,fbcdn.net,节点选择", + "DOMAIN-KEYWORD,twitter,节点选择", + "DOMAIN-KEYWORD,instagram,节点选择", + "DOMAIN-KEYWORD,dropbox,节点选择", + "DOMAIN-SUFFIX,twimg.com,节点选择", + "DOMAIN-KEYWORD,blogspot,节点选择", + "DOMAIN-SUFFIX,youtu.be,节点选择", + "DOMAIN-KEYWORD,whatsapp,节点选择", + "DOMAIN-KEYWORD,admarvel,REJECT", + "DOMAIN-KEYWORD,admaster,REJECT", + "DOMAIN-KEYWORD,adsage,REJECT", + "DOMAIN-KEYWORD,adsmogo,REJECT", + "DOMAIN-KEYWORD,adsrvmedia,REJECT", + "DOMAIN-KEYWORD,adwords,REJECT", + "DOMAIN-KEYWORD,adservice,REJECT", + "DOMAIN-SUFFIX,appsflyer.com,REJECT", + "DOMAIN-KEYWORD,domob,REJECT", + "DOMAIN-SUFFIX,doubleclick.net,REJECT", + "DOMAIN-KEYWORD,duomeng,REJECT", + "DOMAIN-KEYWORD,dwtrack,REJECT", + "DOMAIN-KEYWORD,guanggao,REJECT", + "DOMAIN-KEYWORD,lianmeng,REJECT", + "DOMAIN-SUFFIX,mmstat.com,REJECT", + "DOMAIN-KEYWORD,mopub,REJECT", + "DOMAIN-KEYWORD,omgmta,REJECT", + "DOMAIN-KEYWORD,openx,REJECT", + "DOMAIN-KEYWORD,partnerad,REJECT", + "DOMAIN-KEYWORD,pingfore,REJECT", + "DOMAIN-KEYWORD,supersonicads,REJECT", + "DOMAIN-KEYWORD,uedas,REJECT", + "DOMAIN-KEYWORD,umeng,REJECT", + "DOMAIN-KEYWORD,usage,REJECT", + "DOMAIN-SUFFIX,vungle.com,REJECT", + "DOMAIN-KEYWORD,wlmonitor,REJECT", + "DOMAIN-KEYWORD,zjtoolbar,REJECT", + "DOMAIN-SUFFIX,9to5mac.com,节点选择", + "DOMAIN-SUFFIX,abpchina.org,节点选择", + "DOMAIN-SUFFIX,adblockplus.org,节点选择", + "DOMAIN-SUFFIX,adobe.com,节点选择", + "DOMAIN-SUFFIX,akamaized.net,节点选择", + "DOMAIN-SUFFIX,alfredapp.com,节点选择", + "DOMAIN-SUFFIX,amplitude.com,节点选择", + "DOMAIN-SUFFIX,ampproject.org,节点选择", + "DOMAIN-SUFFIX,android.com,节点选择", + "DOMAIN-SUFFIX,angularjs.org,节点选择", + "DOMAIN-SUFFIX,aolcdn.com,节点选择", + "DOMAIN-SUFFIX,apkpure.com,节点选择", + "DOMAIN-SUFFIX,appledaily.com,节点选择", + "DOMAIN-SUFFIX,appshopper.com,节点选择", + "DOMAIN-SUFFIX,appspot.com,节点选择", + "DOMAIN-SUFFIX,arcgis.com,节点选择", + "DOMAIN-SUFFIX,archive.org,节点选择", + "DOMAIN-SUFFIX,armorgames.com,节点选择", + "DOMAIN-SUFFIX,aspnetcdn.com,节点选择", + "DOMAIN-SUFFIX,att.com,节点选择", + "DOMAIN-SUFFIX,awsstatic.com,节点选择", + "DOMAIN-SUFFIX,azureedge.net,节点选择", + "DOMAIN-SUFFIX,azurewebsites.net,节点选择", + "DOMAIN-SUFFIX,bing.com,节点选择", + "DOMAIN-SUFFIX,bintray.com,节点选择", + "DOMAIN-SUFFIX,bit.com,节点选择", + "DOMAIN-SUFFIX,bit.ly,节点选择", + "DOMAIN-SUFFIX,bitbucket.org,节点选择", + "DOMAIN-SUFFIX,bjango.com,节点选择", + "DOMAIN-SUFFIX,bkrtx.com,节点选择", + "DOMAIN-SUFFIX,blog.com,节点选择", + "DOMAIN-SUFFIX,blogcdn.com,节点选择", + "DOMAIN-SUFFIX,blogger.com,节点选择", + "DOMAIN-SUFFIX,blogsmithmedia.com,节点选择", + "DOMAIN-SUFFIX,blogspot.com,节点选择", + "DOMAIN-SUFFIX,blogspot.hk,节点选择", + "DOMAIN-SUFFIX,bloomberg.com,节点选择", + "DOMAIN-SUFFIX,box.com,节点选择", + "DOMAIN-SUFFIX,box.net,节点选择", + "DOMAIN-SUFFIX,cachefly.net,节点选择", + "DOMAIN-SUFFIX,chromium.org,节点选择", + "DOMAIN-SUFFIX,cl.ly,节点选择", + "DOMAIN-SUFFIX,cloudflare.com,节点选择", + "DOMAIN-SUFFIX,cloudfront.net,节点选择", + "DOMAIN-SUFFIX,cloudmagic.com,节点选择", + "DOMAIN-SUFFIX,cmail19.com,节点选择", + "DOMAIN-SUFFIX,cnet.com,节点选择", + "DOMAIN-SUFFIX,cocoapods.org,节点选择", + "DOMAIN-SUFFIX,comodoca.com,节点选择", + "DOMAIN-SUFFIX,crashlytics.com,节点选择", + "DOMAIN-SUFFIX,culturedcode.com,节点选择", + "DOMAIN-SUFFIX,d.pr,节点选择", + "DOMAIN-SUFFIX,danilo.to,节点选择", + "DOMAIN-SUFFIX,dayone.me,节点选择", + "DOMAIN-SUFFIX,db.tt,节点选择", + "DOMAIN-SUFFIX,deskconnect.com,节点选择", + "DOMAIN-SUFFIX,disq.us,节点选择", + "DOMAIN-SUFFIX,disqus.com,节点选择", + "DOMAIN-SUFFIX,disquscdn.com,节点选择", + "DOMAIN-SUFFIX,dnsimple.com,节点选择", + "DOMAIN-SUFFIX,docker.com,节点选择", + "DOMAIN-SUFFIX,dribbble.com,节点选择", + "DOMAIN-SUFFIX,droplr.com,节点选择", + "DOMAIN-SUFFIX,duckduckgo.com,节点选择", + "DOMAIN-SUFFIX,dueapp.com,节点选择", + "DOMAIN-SUFFIX,dytt8.net,节点选择", + "DOMAIN-SUFFIX,edgecastcdn.net,节点选择", + "DOMAIN-SUFFIX,edgekey.net,节点选择", + "DOMAIN-SUFFIX,edgesuite.net,节点选择", + "DOMAIN-SUFFIX,engadget.com,节点选择", + "DOMAIN-SUFFIX,entrust.net,节点选择", + "DOMAIN-SUFFIX,eurekavpt.com,节点选择", + "DOMAIN-SUFFIX,evernote.com,节点选择", + "DOMAIN-SUFFIX,fabric.io,节点选择", + "DOMAIN-SUFFIX,fast.com,节点选择", + "DOMAIN-SUFFIX,fastly.net,节点选择", + "DOMAIN-SUFFIX,fc2.com,节点选择", + "DOMAIN-SUFFIX,feedburner.com,节点选择", + "DOMAIN-SUFFIX,feedly.com,节点选择", + "DOMAIN-SUFFIX,feedsportal.com,节点选择", + "DOMAIN-SUFFIX,fiftythree.com,节点选择", + "DOMAIN-SUFFIX,firebaseio.com,节点选择", + "DOMAIN-SUFFIX,flexibits.com,节点选择", + "DOMAIN-SUFFIX,flickr.com,节点选择", + "DOMAIN-SUFFIX,flipboard.com,节点选择", + "DOMAIN-SUFFIX,g.co,节点选择", + "DOMAIN-SUFFIX,gabia.net,节点选择", + "DOMAIN-SUFFIX,geni.us,节点选择", + "DOMAIN-SUFFIX,gfx.ms,节点选择", + "DOMAIN-SUFFIX,ggpht.com,节点选择", + "DOMAIN-SUFFIX,ghostnoteapp.com,节点选择", + "DOMAIN-SUFFIX,git.io,节点选择", + "DOMAIN-KEYWORD,github,节点选择", + "DOMAIN-SUFFIX,globalsign.com,节点选择", + "DOMAIN-SUFFIX,gmodules.com,节点选择", + "DOMAIN-SUFFIX,godaddy.com,节点选择", + "DOMAIN-SUFFIX,golang.org,节点选择", + "DOMAIN-SUFFIX,gongm.in,节点选择", + "DOMAIN-SUFFIX,goo.gl,节点选择", + "DOMAIN-SUFFIX,goodreaders.com,节点选择", + "DOMAIN-SUFFIX,goodreads.com,节点选择", + "DOMAIN-SUFFIX,gravatar.com,节点选择", + "DOMAIN-SUFFIX,gstatic.com,节点选择", + "DOMAIN-SUFFIX,gvt0.com,节点选择", + "DOMAIN-SUFFIX,hockeyapp.net,节点选择", + "DOMAIN-SUFFIX,hotmail.com,节点选择", + "DOMAIN-SUFFIX,icons8.com,节点选择", + "DOMAIN-SUFFIX,ifixit.com,节点选择", + "DOMAIN-SUFFIX,ift.tt,节点选择", + "DOMAIN-SUFFIX,ifttt.com,节点选择", + "DOMAIN-SUFFIX,iherb.com,节点选择", + "DOMAIN-SUFFIX,imageshack.us,节点选择", + "DOMAIN-SUFFIX,img.ly,节点选择", + "DOMAIN-SUFFIX,imgur.com,节点选择", + "DOMAIN-SUFFIX,imore.com,节点选择", + "DOMAIN-SUFFIX,instapaper.com,节点选择", + "DOMAIN-SUFFIX,ipn.li,节点选择", + "DOMAIN-SUFFIX,is.gd,节点选择", + "DOMAIN-SUFFIX,issuu.com,节点选择", + "DOMAIN-SUFFIX,itgonglun.com,节点选择", + "DOMAIN-SUFFIX,itun.es,节点选择", + "DOMAIN-SUFFIX,ixquick.com,节点选择", + "DOMAIN-SUFFIX,j.mp,节点选择", + "DOMAIN-SUFFIX,js.revsci.net,节点选择", + "DOMAIN-SUFFIX,jshint.com,节点选择", + "DOMAIN-SUFFIX,jtvnw.net,节点选择", + "DOMAIN-SUFFIX,justgetflux.com,节点选择", + "DOMAIN-SUFFIX,kat.cr,节点选择", + "DOMAIN-SUFFIX,klip.me,节点选择", + "DOMAIN-SUFFIX,libsyn.com,节点选择", + "DOMAIN-SUFFIX,linkedin.com,节点选择", + "DOMAIN-SUFFIX,line-apps.com,节点选择", + "DOMAIN-SUFFIX,linode.com,节点选择", + "DOMAIN-SUFFIX,lithium.com,节点选择", + "DOMAIN-SUFFIX,littlehj.com,节点选择", + "DOMAIN-SUFFIX,live.com,节点选择", + "DOMAIN-SUFFIX,live.net,节点选择", + "DOMAIN-SUFFIX,livefilestore.com,节点选择", + "DOMAIN-SUFFIX,llnwd.net,节点选择", + "DOMAIN-SUFFIX,macid.co,节点选择", + "DOMAIN-SUFFIX,macromedia.com,节点选择", + "DOMAIN-SUFFIX,macrumors.com,节点选择", + "DOMAIN-SUFFIX,mashable.com,节点选择", + "DOMAIN-SUFFIX,mathjax.org,节点选择", + "DOMAIN-SUFFIX,medium.com,节点选择", + "DOMAIN-SUFFIX,mega.co.nz,节点选择", + "DOMAIN-SUFFIX,mega.nz,节点选择", + "DOMAIN-SUFFIX,megaupload.com,节点选择", + "DOMAIN-SUFFIX,microsofttranslator.com,节点选择", + "DOMAIN-SUFFIX,mindnode.com,节点选择", + "DOMAIN-SUFFIX,mobile01.com,节点选择", + "DOMAIN-SUFFIX,modmyi.com,节点选择", + "DOMAIN-SUFFIX,msedge.net,节点选择", + "DOMAIN-SUFFIX,myfontastic.com,节点选择", + "DOMAIN-SUFFIX,name.com,节点选择", + "DOMAIN-SUFFIX,nextmedia.com,节点选择", + "DOMAIN-SUFFIX,nsstatic.net,节点选择", + "DOMAIN-SUFFIX,nssurge.com,节点选择", + "DOMAIN-SUFFIX,nyt.com,节点选择", + "DOMAIN-SUFFIX,nytimes.com,节点选择", + "DOMAIN-SUFFIX,omnigroup.com,节点选择", + "DOMAIN-SUFFIX,onedrive.com,节点选择", + "DOMAIN-SUFFIX,onenote.com,节点选择", + "DOMAIN-SUFFIX,ooyala.com,节点选择", + "DOMAIN-SUFFIX,openvpn.net,节点选择", + "DOMAIN-SUFFIX,openwrt.org,节点选择", + "DOMAIN-SUFFIX,orkut.com,节点选择", + "DOMAIN-SUFFIX,osxdaily.com,节点选择", + "DOMAIN-SUFFIX,outlook.com,节点选择", + "DOMAIN-SUFFIX,ow.ly,节点选择", + "DOMAIN-SUFFIX,paddleapi.com,节点选择", + "DOMAIN-SUFFIX,parallels.com,节点选择", + "DOMAIN-SUFFIX,parse.com,节点选择", + "DOMAIN-SUFFIX,pdfexpert.com,节点选择", + "DOMAIN-SUFFIX,periscope.tv,节点选择", + "DOMAIN-SUFFIX,pinboard.in,节点选择", + "DOMAIN-SUFFIX,pinterest.com,节点选择", + "DOMAIN-SUFFIX,pixelmator.com,节点选择", + "DOMAIN-SUFFIX,pixiv.net,节点选择", + "DOMAIN-SUFFIX,playpcesor.com,节点选择", + "DOMAIN-SUFFIX,playstation.com,节点选择", + "DOMAIN-SUFFIX,playstation.com.hk,节点选择", + "DOMAIN-SUFFIX,playstation.net,节点选择", + "DOMAIN-SUFFIX,playstationnetwork.com,节点选择", + "DOMAIN-SUFFIX,pushwoosh.com,节点选择", + "DOMAIN-SUFFIX,rime.im,节点选择", + "DOMAIN-SUFFIX,servebom.com,节点选择", + "DOMAIN-SUFFIX,sfx.ms,节点选择", + "DOMAIN-SUFFIX,shadowsocks.org,节点选择", + "DOMAIN-SUFFIX,sharethis.com,节点选择", + "DOMAIN-SUFFIX,shazam.com,节点选择", + "DOMAIN-SUFFIX,skype.com,节点选择", + "DOMAIN-SUFFIX,smartdns节点选择.com,节点选择", + "DOMAIN-SUFFIX,smartmailcloud.com,节点选择", + "DOMAIN-SUFFIX,sndcdn.com,节点选择", + "DOMAIN-SUFFIX,sony.com,节点选择", + "DOMAIN-SUFFIX,soundcloud.com,节点选择", + "DOMAIN-SUFFIX,sourceforge.net,节点选择", + "DOMAIN-SUFFIX,spotify.com,节点选择", + "DOMAIN-SUFFIX,squarespace.com,节点选择", + "DOMAIN-SUFFIX,sstatic.net,节点选择", + "DOMAIN-SUFFIX,st.luluku.pw,节点选择", + "DOMAIN-SUFFIX,stackoverflow.com,节点选择", + "DOMAIN-SUFFIX,startpage.com,节点选择", + "DOMAIN-SUFFIX,staticflickr.com,节点选择", + "DOMAIN-SUFFIX,steamcommunity.com,节点选择", + "DOMAIN-SUFFIX,symauth.com,节点选择", + "DOMAIN-SUFFIX,symcb.com,节点选择", + "DOMAIN-SUFFIX,symcd.com,节点选择", + "DOMAIN-SUFFIX,tapbots.com,节点选择", + "DOMAIN-SUFFIX,tapbots.net,节点选择", + "DOMAIN-SUFFIX,tdesktop.com,节点选择", + "DOMAIN-SUFFIX,techcrunch.com,节点选择", + "DOMAIN-SUFFIX,techsmith.com,节点选择", + "DOMAIN-SUFFIX,thepiratebay.org,节点选择", + "DOMAIN-SUFFIX,theverge.com,节点选择", + "DOMAIN-SUFFIX,time.com,节点选择", + "DOMAIN-SUFFIX,timeinc.net,节点选择", + "DOMAIN-SUFFIX,tiny.cc,节点选择", + "DOMAIN-SUFFIX,tinypic.com,节点选择", + "DOMAIN-SUFFIX,tmblr.co,节点选择", + "DOMAIN-SUFFIX,todoist.com,节点选择", + "DOMAIN-SUFFIX,trello.com,节点选择", + "DOMAIN-SUFFIX,trustasiassl.com,节点选择", + "DOMAIN-SUFFIX,tumblr.co,节点选择", + "DOMAIN-SUFFIX,tumblr.com,节点选择", + "DOMAIN-SUFFIX,tweetdeck.com,节点选择", + "DOMAIN-SUFFIX,tweetmarker.net,节点选择", + "DOMAIN-SUFFIX,twitch.tv,节点选择", + "DOMAIN-SUFFIX,txmblr.com,节点选择", + "DOMAIN-SUFFIX,typekit.net,节点选择", + "DOMAIN-SUFFIX,ubertags.com,节点选择", + "DOMAIN-SUFFIX,ublock.org,节点选择", + "DOMAIN-SUFFIX,ubnt.com,节点选择", + "DOMAIN-SUFFIX,ulyssesapp.com,节点选择", + "DOMAIN-SUFFIX,urchin.com,节点选择", + "DOMAIN-SUFFIX,usertrust.com,节点选择", + "DOMAIN-SUFFIX,v.gd,节点选择", + "DOMAIN-SUFFIX,v2ex.com,节点选择", + "DOMAIN-SUFFIX,vimeo.com,节点选择", + "DOMAIN-SUFFIX,vimeocdn.com,节点选择", + "DOMAIN-SUFFIX,vine.co,节点选择", + "DOMAIN-SUFFIX,vivaldi.com,节点选择", + "DOMAIN-SUFFIX,vox-cdn.com,节点选择", + "DOMAIN-SUFFIX,vsco.co,节点选择", + "DOMAIN-SUFFIX,vultr.com,节点选择", + "DOMAIN-SUFFIX,w.org,节点选择", + "DOMAIN-SUFFIX,w3schools.com,节点选择", + "DOMAIN-SUFFIX,webtype.com,节点选择", + "DOMAIN-SUFFIX,wikiwand.com,节点选择", + "DOMAIN-SUFFIX,wikileaks.org,节点选择", + "DOMAIN-SUFFIX,wikimedia.org,节点选择", + "DOMAIN-SUFFIX,wikipedia.com,节点选择", + "DOMAIN-SUFFIX,wikipedia.org,节点选择", + "DOMAIN-SUFFIX,windows.com,节点选择", + "DOMAIN-SUFFIX,windows.net,节点选择", + "DOMAIN-SUFFIX,wire.com,节点选择", + "DOMAIN-SUFFIX,wordpress.com,节点选择", + "DOMAIN-SUFFIX,workflowy.com,节点选择", + "DOMAIN-SUFFIX,wp.com,节点选择", + "DOMAIN-SUFFIX,wsj.com,节点选择", + "DOMAIN-SUFFIX,wsj.net,节点选择", + "DOMAIN-SUFFIX,xda-developers.com,节点选择", + "DOMAIN-SUFFIX,xeeno.com,节点选择", + "DOMAIN-SUFFIX,xiti.com,节点选择", + "DOMAIN-SUFFIX,yahoo.com,节点选择", + "DOMAIN-SUFFIX,yimg.com,节点选择", + "DOMAIN-SUFFIX,ying.com,节点选择", + "DOMAIN-SUFFIX,yoyo.org,节点选择", + "DOMAIN-SUFFIX,ytimg.com,节点选择", + "DOMAIN-SUFFIX,telegra.ph,节点选择", + "DOMAIN-SUFFIX,telegram.org,节点选择", + "IP-CIDR,91.108.4.0/22,节点选择,no-resolve", + "IP-CIDR,91.108.8.0/21,节点选择,no-resolve", + "IP-CIDR,91.108.16.0/22,节点选择,no-resolve", + "IP-CIDR,91.108.56.0/22,节点选择,no-resolve", + "IP-CIDR,149.154.160.0/20,节点选择,no-resolve", + "IP-CIDR6,2001:67c:4e8::/48,节点选择,no-resolve", + "IP-CIDR6,2001:b28:f23d::/48,节点选择,no-resolve", + "IP-CIDR6,2001:b28:f23f::/48,节点选择,no-resolve", + "IP-CIDR,120.232.181.162/32,节点选择,no-resolve", + "IP-CIDR,120.241.147.226/32,节点选择,no-resolve", + "IP-CIDR,120.253.253.226/32,节点选择,no-resolve", + "IP-CIDR,120.253.255.162/32,节点选择,no-resolve", + "IP-CIDR,120.253.255.34/32,节点选择,no-resolve", + "IP-CIDR,120.253.255.98/32,节点选择,no-resolve", + "IP-CIDR,180.163.150.162/32,节点选择,no-resolve", + "IP-CIDR,180.163.150.34/32,节点选择,no-resolve", + "IP-CIDR,180.163.151.162/32,节点选择,no-resolve", + "IP-CIDR,180.163.151.34/32,节点选择,no-resolve", + "IP-CIDR,203.208.39.0/24,节点选择,no-resolve", + "IP-CIDR,203.208.40.0/24,节点选择,no-resolve", + "IP-CIDR,203.208.41.0/24,节点选择,no-resolve", + "IP-CIDR,203.208.43.0/24,节点选择,no-resolve", + "IP-CIDR,203.208.50.0/24,节点选择,no-resolve", + "IP-CIDR,220.181.174.162/32,节点选择,no-resolve", + "IP-CIDR,220.181.174.226/32,节点选择,no-resolve", + "IP-CIDR,220.181.174.34/32,节点选择,no-resolve", + "DOMAIN,injections.adguard.org,DIRECT", + "DOMAIN,local.adguard.org,DIRECT", + "DOMAIN-SUFFIX,local,DIRECT", + "IP-CIDR,127.0.0.0/8,DIRECT", + "IP-CIDR,172.16.0.0/12,DIRECT", + "IP-CIDR,192.168.0.0/16,DIRECT", + "IP-CIDR,10.0.0.0/8,DIRECT", + "IP-CIDR,17.0.0.0/8,DIRECT", + "IP-CIDR,100.64.0.0/10,DIRECT", + "IP-CIDR,224.0.0.0/4,DIRECT", + "IP-CIDR6,fe80::/10,DIRECT", + "DOMAIN-SUFFIX,cn,DIRECT", + "DOMAIN-KEYWORD,-cn,DIRECT", + "GEOIP,CN,DIRECT", + "MATCH,节点选择" + ] +} + +# 解析 Hysteria2 链接 +def parse_hysteria2_link(link): + link = link[14:] + parts = link.split('@') + uuid = parts[0] + server_info = parts[1].split('?') + server = server_info[0].split(':')[0] + port = int(server_info[0].split(':')[1].split('/')[0].strip()) + query_params = urllib.parse.parse_qs(server_info[1] if len(server_info) > 1 else '') + insecure = '1' in query_params.get('insecure', ['0']) + sni = query_params.get('sni', [''])[0] + name = urllib.parse.unquote(link.split('#')[-1].strip()) + + return { + "name": f"🇺🇸 {name}", + "server": server, + "port": port, + "type": "hysteria2", + "password": uuid, + "auth": uuid, + "sni": sni, + "skip-cert-verify": not insecure, + "client-fingerprint": "chrome" + } + +# 解析 Shadowsocks 链接 +def parse_ss_link(link): + link = link[5:] + if "#" in link: + config_part, name = link.split('#') + else: + config_part, name = link, "" + decoded = base64.urlsafe_b64decode(config_part.split('@')[0] + '=' * (-len(config_part.split('@')[0]) % 4)).decode('utf-8') + method_passwd = decoded.split(':') + cipher, password = method_passwd if len(method_passwd) == 2 else (method_passwd[0], "") + server_info = config_part.split('@')[1] + server, port = server_info.split(':') if ":" in server_info else (server_info, "") + + return { + "name": urllib.parse.unquote(name), + "type": "ss", + "server": server, + "port": int(port), + "cipher": cipher, + "password": password, + "udp": True + } + +# 解析 Trojan 链接 +def parse_trojan_link(link): + link = link[9:] + config_part, name = link.split('#') + user_info, host_info = config_part.split('@') + username, password = user_info.split(':') if ":" in user_info else ("", user_info) + host, port_and_query = host_info.split(':') if ":" in host_info else (host_info, "") + port, query = port_and_query.split('?', 1) if '?' in port_and_query else (port_and_query, "") + + return { + "name": urllib.parse.unquote(name), + "type": "trojan", + "server": host, + "port": int(port), + "password": password, + "sni": urllib.parse.parse_qs(query).get("sni", [""])[0], + "skip-cert-verify": urllib.parse.parse_qs(query).get("skip-cert-verify", ["false"])[0] == "true" + } + +# 解析 VLESS 链接 +def parse_vless_link(link): + link = link[8:] + config_part, name = link.split('#') + user_info, host_info = config_part.split('@') + uuid = user_info + host, query = host_info.split('?', 1) if '?' in host_info else (host_info, "") + port = host.split(':')[-1] if ':' in host else "" + host = host.split(':')[0] if ':' in host else "" + + return { + "name": urllib.parse.unquote(name), + "type": "vless", + "server": host, + "port": int(port), + "uuid": uuid, + "security": urllib.parse.parse_qs(query).get("security", ["none"])[0], + "tls": urllib.parse.parse_qs(query).get("security", ["none"])[0] == "tls", + "sni": urllib.parse.parse_qs(query).get("sni", [""])[0], + "skip-cert-verify": urllib.parse.parse_qs(query).get("skip-cert-verify", ["false"])[0] == "true", + "network": urllib.parse.parse_qs(query).get("type", ["tcp"])[0], + "ws-opts": { + "path": urllib.parse.parse_qs(query).get("path", [""])[0], + "headers": { + "Host": urllib.parse.parse_qs(query).get("host", [""])[0] + } + } if urllib.parse.parse_qs(query).get("type", ["tcp"])[0] == "ws" else {} + } + +# 解析 VMESS 链接 +def parse_vmess_link(link): + link = link[8:] + decoded_link = base64.urlsafe_b64decode(link + '=' * (-len(link) % 4)).decode("utf-8") + vmess_info = json.loads(decoded_link) + + return { + "name": urllib.parse.unquote(vmess_info.get("ps", "vmess")), + "type": "vmess", + "server": vmess_info["add"], + "port": int(vmess_info["port"]), + "uuid": vmess_info["id"], + "alterId": int(vmess_info.get("aid", 0)), + "cipher": "auto", + "network": vmess_info.get("net", "tcp"), + "tls": vmess_info.get("tls", "") == "tls", + "sni": vmess_info.get("sni", ""), + "ws-opts": { + "path": vmess_info.get("path", ""), + "headers": { + "Host": vmess_info.get("host", "") + } + } if vmess_info.get("net", "tcp") == "ws" else {} + } + +# 解析爬虫代理池 +def parse_proxypool_data(data): + new_links = [{"name": x['remarks'],"type": "ss","server": x['server'],"port": x['server_port'],"cipher": x['method'],"password": x['password'],"udp": True} for x in data] + return new_links + +def parse_md_link(link): + try: + # 发送请求并获取内容 + response = requests.get(link) + response.raise_for_status() # 检查请求是否成功 + content = response.text + + # 定义正则表达式模式,匹配所需的协议链接 + pattern = r'(hysteria2://|trojan://|ss://|vless://|vmess://[^\s]+)' + + # 使用re.findall()提取所有匹配的链接 + matches = re.findall(pattern, content) + + return matches + + except requests.RequestException as e: + print(f"请求错误: {e}") + return [] + +# js渲染页面 +def js_render(url): + timeout = 4 + if timeout > 15: + timeout = 15 + browser_args = ['--no-sandbox', '--disable-dev-shm-usage', '--disable-gpu', '--disable-software-rasterizer','--disable-setuid-sandbox'] + session = HTMLSession(browser_args=browser_args) + r = session.get(f'{url}', headers=headers, timeout=timeout, verify=False) + # 等待页面加载完成,Requests-HTML 会自动等待 JavaScript 执行完成 + r.html.render(timeout=timeout) + return r + +# je_render返回的text没有缩进,通过正则表达式匹配proxies下的所有代理节点 +def match_nodes(text): + proxy_pattern = r"\{[^}]*name\s*:\s*['\"][^'\"]+['\"][^}]*server\s*:\s*[^,]+[^}]*\}" + nodes = re.findall(proxy_pattern, text, re.DOTALL) + + # 将每个节点字符串转换为字典 + proxies_list = [] + for node in nodes: + # 使用yaml.safe_load来加载每个节点 + node_dict = yaml.safe_load(node) + proxies_list.append(node_dict) + + yaml_data = {"proxies": proxies_list} + return yaml_data + +# link非代理协议时(https),请求url解析 +def process_url(url): + isyaml = False + try: + # 发送GET请求 + response = requests.get(url, headers=headers, verify=False, allow_redirects=True) + if url == "https://proxypool.link/ss/sub": + return parse_proxypool_data(response.json()), True + # 确保响应状态码为200 + if response.status_code == 200: + content = response.text + if 'external-controller' in content: + # YAML格式 + yaml_data = yaml.safe_load(content) + if 'proxies' in yaml_data: + isyaml = True + proxies = yaml_data['proxies'] if yaml_data['proxies'] else [] + return proxies,isyaml + else: + # 尝试Base64解码 + try: + decoded_bytes = base64.b64decode(content) + decoded_content = decoded_bytes.decode('utf-8') + return decoded_content.splitlines(),isyaml + except Exception as e: + try: + res = js_render(url) + if 'external-controller' in res.html.text: + # YAML格式 + try: + yaml_data = yaml.safe_load(res.html.text) + except Exception as e: + yaml_data = match_nodes(res.html.text) + finally: + if 'proxies' in yaml_data: + isyaml = True + return yaml_data['proxies'], isyaml + + else: + pattern = r'([A-Za-z0-9_+/\-]+={0,2})' + matches = re.findall(pattern, res.html.text) + stdout = matches[-1] if matches else [] + decoded_bytes = base64.b64decode(stdout) + decoded_content = decoded_bytes.decode('utf-8') + return decoded_content.splitlines(), isyaml + except Exception as e: + # 如果不是Base64编码,直接按行处理 + return [],isyaml + else: + print(f"Failed to retrieve data from {url}, status code: {response.status_code}") + return [],isyaml + except requests.RequestException as e: + print(f"An error occurred while requesting {url}: {e}") + return [],isyaml + +# 解析不同的代理链接 +def parse_proxy_link(link): + if link.startswith("hysteria2://"): + return parse_hysteria2_link(link) + elif link.startswith("trojan://"): + return parse_trojan_link(link) + elif link.startswith("ss://"): + return parse_ss_link(link) + elif link.startswith("vless://"): + return parse_vless_link(link) + elif link.startswith("vmess://"): + return parse_vmess_link(link) + return None + +# 根据server和port共同约束去重 +def deduplicate_proxies(proxies_list): + unique_proxies = [] + seen = set() + for proxy in proxies_list: + key = (proxy['server'], proxy['port']) + if key not in seen: + seen.add(key) + unique_proxies.append(proxy) + return unique_proxies + +# 出现节点name相同时,加上4位随机字符串 +def add_random_suffix(name, existing_names): + # 生成4位随机字符串 + suffix = ''.join(random.choices(string.ascii_letters + string.digits, k=4)) + new_name = f"{name}-{suffix}" + # 确保生成的新名字不在已存在的名字列表中 + while new_name in existing_names: + suffix = ''.join(random.choices(string.ascii_letters + string.digits, k=4)) + new_name = f"{name}-{suffix}" + return new_name + +# 从指定目录下的txt读取代理链接 +def read_txt_files(folder_path): + all_lines = [] # 用于存储所有文件的行 + + # 使用 glob 获取指定文件夹下的所有 txt 文件 + txt_files = glob.glob(os.path.join(folder_path, '*.txt')) + + for file_path in txt_files: + with open(file_path, 'r', encoding='utf-8') as file: + # 读取文件内容并按行存入数组 + lines = file.readlines() + all_lines.extend(line.strip() for line in lines) # 去除每行的换行符并添加到数组中 + if all_lines: + print(f'加载【{folder_path}】目录下所有txt中节点') + return all_lines + +# 从指定目录下的yaml/yml读取proxies +def read_yaml_files(folder_path): + load_nodes = [] + # 使用 glob 获取指定文件夹下的所有 yaml/yml 文件 + yaml_files = glob.glob(os.path.join(folder_path, '*.yaml')) + yaml_files.extend(glob.glob(os.path.join(folder_path, '*.yml'))) + + for file_path in yaml_files: + try: + with open(file_path, 'r', encoding='utf-8') as file: + # 读取并解析yaml文件 + config = yaml.safe_load(file) + # 如果存在proxies字段,添加到nodes列表 + if config and 'proxies' in config: + load_nodes.extend(config['proxies']) + except Exception as e: + print(f"Error reading {file_path}: {str(e)}") + if load_nodes: + print(f'加载【{folder_path}】目录下yaml/yml中所有节点') + return load_nodes + +# 进行type过滤 +def filter_by_types_alt(allowed_types,nodes): + # 进行过滤 + return [x for x in nodes if x.get('type') in allowed_types] + +# 合并links列表 +def merge_lists(*lists): + return [item for item in chain.from_iterable(lists) if item != ''] + +# 生成 Clash 配置文件 +def generate_clash_config(links,load_nodes): + now = datetime.now() + print(f"当前时间: {now}\n---") + + final_nodes = [] + config = clash_config_template.copy() + existing_names = set() # 存储所有节点名字以检查重复 + for node in load_nodes: + if node["name"] in existing_names: + node["name"] = add_random_suffix(node["name"], existing_names) + existing_names.add(node["name"]) + final_nodes.append(node) + + for link in links: + node = None + if link.startswith(("hysteria2://", "trojan://", "ss://", "vless://", "vmess://")): + node = parse_proxy_link(link) + if node["name"] in existing_names: + node["name"] = add_random_suffix(node["name"], existing_names) + existing_names.add(node["name"]) + final_nodes.append(node) + else: + print(f'当前正在处理link: {link}') + if '{' in link: + link = resolve_template_url(link) + print(f"解析后的URL: {link}") + if '.md' in link: + new_links = parse_md_link(link) + for new_link in new_links: + if new_link.startswith(("hysteria2://", "trojan://", "ss://", "vless://", "vmess://")): + node = parse_proxy_link(new_link) + if node: + if node["name"] in existing_names: + node["name"] = add_random_suffix(node["name"], existing_names) + existing_names.add(node["name"]) + final_nodes.append(node) + else: + print(f"跳过无效或不支持的链接: {new_link}") + # 处理非特定协议的链接 + new_links,isyaml = process_url(link) + if isyaml: + for node in new_links: + if node["name"] in existing_names: + node["name"] = add_random_suffix(node["name"], existing_names) + existing_names.add(node["name"]) + final_nodes.append(node) + else: + for new_link in new_links: + if new_link.startswith(("hysteria2://", "trojan://", "ss://", "vless://", "vmess://")): + node = parse_proxy_link(new_link) + if node: + if node["name"] in existing_names: + node["name"] = add_random_suffix(node["name"], existing_names) + existing_names.add(node["name"]) + final_nodes.append(node) + else: + print(f"跳过无效或不支持的链接: {new_link}") + final_nodes = deduplicate_proxies(final_nodes) + for node in final_nodes: + # 0节点选择 1 自动选择 2故障转移 3手动选择 + config["proxy-groups"][1]["proxies"].append(node["name"]) + config["proxy-groups"][2]["proxies"].append(node["name"]) + config["proxy-groups"][3]["proxies"].append(node["name"]) + config["proxies"] = final_nodes + if config["proxies"]: + with open(CONFIG_FILE, "w", encoding="utf-8") as f: + yaml.dump(config, f, allow_unicode=True, default_flow_style=False) + print(f"已经生成Clash配置文件{CONFIG_FILE}") + else: + print('没有节点数据更新') + +# 自定义 Clash API 异常 +class ClashAPIException(Exception): + """自定义 Clash API 异常""" + pass + +# 代理测试结果类 +class ProxyTestResult: + """代理测试结果类""" + + def __init__(self, name: str, delay: Optional[float] = None): + self.name = name + self.delay = delay if delay is not None else float('inf') + self.status = "ok" if delay is not None else "fail" + self.tested_time = datetime.now() + + @property + def is_valid(self) -> bool: + return self.status == "ok" + + + +def download_file(url, destination): + """ 下载文件,如果文件已存在则跳过 """ + RELEASE_VERSION = 'v1.18.9' + DOWNLOAD_URLS = { + 'windows': f'https://gitdl.cn/https://github.com/fish2018/lib/releases/download/{RELEASE_VERSION}/clash.exe', + 'linux': f'https://gitdl.cn/https://github.com/fish2018/lib/releases/download/{RELEASE_VERSION}/clash-linux', + 'darwin': f'https://gitdl.cn/https://github.com/fish2018/lib/releases/download/{RELEASE_VERSION}/clash-darwin' + } + if os.path.exists(destination): + # print(f"{destination} already exists. Skipping download.") + return + + print(f"Downloading {destination} from {url}...") + response = requests.get(url) + if response.status_code == 200: + with open(destination, 'wb') as f: + f.write(response.content) + print(f"Downloaded {destination} successfully.") + else: + print(f"Failed to download {destination}. Status code: {response.status_code}") + + +def ensure_executable(file_path): + """ 确保文件具有可执行权限(仅适用于 Linux 和 macOS) """ + if platform.system().lower() in ['linux', 'darwin']: + # print(f"Setting executable permissions for {file_path}...") + os.chmod(file_path, 0o755) # 设置文件为可执行 + + +# 启动 Clash +def start_clash(): + # 定义 Clash 的下载地址 + RELEASE_BASE_URL = 'https://gitdl.cn/https://github.com/fish2018/lib/releases/download/v1.18.9' + DOWNLOAD_URLS = { + 'windows': f'{RELEASE_BASE_URL}/clash.exe', + 'linux': f'{RELEASE_BASE_URL}/clash-linux', + 'darwin': f'{RELEASE_BASE_URL}/clash-darwin' + } + system_platform = platform.system().lower() + # 根据操作系统设置 Clash 二进制文件和配置文件路径 + if system_platform == 'windows': + clash_binary = '.\clash.exe' # Windows下的可执行文件 + # 确定 Clash 二进制文件路径 + elif system_platform in DOWNLOAD_URLS: + clash_binary = f'./clash-{system_platform}' + download_file(DOWNLOAD_URLS[system_platform], clash_binary) + ensure_executable(clash_binary) + else: + raise OSError("Unsupported operating system.") + + # print(f"Starting Clash with binary: {clash_binary} and config: {CONFIG_FILE}") + + # 启动 Clash 进程 + clash_process = subprocess.Popen([clash_binary, '-f', CONFIG_FILE], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + return clash_process + +# 调用ClashAPI +class ClashAPI: + def __init__(self, host: str, ports: List[int], secret: str = ""): + self.host = host + self.ports = ports + self.base_url = None # 将在连接检查时设置 + self.headers = { + "Authorization": f"Bearer {secret}" if secret else "", + "Content-Type": "application/json" + } + self.client = httpx.AsyncClient(timeout=TIMEOUT) + self.semaphore = Semaphore(MAX_CONCURRENT_TESTS) + self._test_results_cache: Dict[str, ProxyTestResult] = {} + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await self.client.aclose() + + async def check_connection(self) -> bool: + """检查与 Clash API 的连接状态,自动尝试不同端口""" + for port in self.ports: + try: + test_url = f"http://{self.host}:{port}" + response = await self.client.get(f"{test_url}/version") + if response.status_code == 200: + version = response.json().get('version', 'unknown') + print(f"成功连接到 Clash API (端口 {port}),版本: {version}") + self.base_url = test_url + return True + except httpx.RequestError: + print(f"端口 {port} 连接失败,尝试下一个端口...") + continue + + print("所有端口均连接失败") + print(f"请确保 Clash 正在运行,并且 External Controller 已启用于以下端口之一: {', '.join(map(str, self.ports))}") + return False + + async def get_proxies(self) -> Dict: + """获取所有代理节点信息""" + if not self.base_url: + raise ClashAPIException("未建立与 Clash API 的连接") + + try: + response = await self.client.get( + f"{self.base_url}/proxies", + headers=self.headers + ) + response.raise_for_status() + return response.json() + except httpx.HTTPStatusError as e: + if e.response.status_code == 401: + print("认证失败,请检查 API Secret 是否正确") + raise ClashAPIException(f"HTTP 错误: {e}") + except httpx.RequestError as e: + raise ClashAPIException(f"请求错误: {e}") + + async def test_proxy_delay(self, proxy_name: str) -> ProxyTestResult: + """测试指定代理节点的延迟,使用缓存避免重复测试""" + if not self.base_url: + raise ClashAPIException("未建立与 Clash API 的连接") + + # 检查缓存 + if proxy_name in self._test_results_cache: + cached_result = self._test_results_cache[proxy_name] + # 如果测试结果不超过60秒,直接返回缓存的结果 + if (datetime.now() - cached_result.tested_time).total_seconds() < 60: + return cached_result + + async with self.semaphore: + try: + response = await self.client.get( + f"{self.base_url}/proxies/{proxy_name}/delay", + headers=self.headers, + params={"url": TEST_URL, "timeout": TIMEOUT * 1000} + ) + response.raise_for_status() + delay = response.json().get("delay") + result = ProxyTestResult(proxy_name, delay) + except httpx.HTTPError: + result = ProxyTestResult(proxy_name) + + # 更新缓存 + self._test_results_cache[proxy_name] = result + return result + +# 更新clash配置 +class ClashConfig: + """Clash 配置管理类""" + + def __init__(self, config_path: str): + self.config_path = config_path + self.config = self._load_config() + self.proxy_groups = self._get_proxy_groups() + + def _load_config(self) -> dict: + """加载配置文件""" + try: + with open(self.config_path, 'r', encoding='utf-8') as f: + return yaml.safe_load(f) + except FileNotFoundError: + print(f"找不到配置文件: {self.config_path}") + sys.exit(1) + except yaml.YAMLError as e: + print(f"配置文件格式错误: {e}") + sys.exit(1) + + def _get_proxy_groups(self) -> List[Dict]: + """获取所有代理组信息""" + return self.config.get("proxy-groups", []) + + def get_group_names(self) -> List[str]: + """获取所有代理组名称""" + return [group["name"] for group in self.proxy_groups] + + def get_group_proxies(self, group_name: str) -> List[str]: + """获取指定组的所有代理""" + for group in self.proxy_groups: + if group["name"] == group_name: + return group.get("proxies", []) + return [] + + def remove_invalid_proxies(self, results: List[ProxyTestResult]): + """从配置中完全移除失效的节点""" + # 获取所有失效节点名称 + invalid_proxies = {r.name for r in results if not r.is_valid} + + if not invalid_proxies: + return + + # 从 proxies 部分移除失效节点 + valid_proxies = [] + if "proxies" in self.config: + valid_proxies = [p for p in self.config["proxies"] + if p.get("name") not in invalid_proxies] + self.config["proxies"] = valid_proxies + + # 从所有代理组中移除失效节点 + for group in self.proxy_groups: + if "proxies" in group: + group["proxies"] = [p for p in group["proxies"] if p not in invalid_proxies] + + print(f"已从配置中移除 {len(invalid_proxies)} 个失效节点") + + def update_group_proxies(self, group_name: str, results: List[ProxyTestResult]): + """更新指定组的代理列表,仅保留有效节点并按延迟排序""" + # 移除失效节点 + self.remove_invalid_proxies(results) + + # 获取有效节点并按延迟排序 + valid_results = [r for r in results if r.is_valid] + valid_results = list(set(valid_results)) + valid_results.sort(key=lambda x: x.delay) + + # 更新代理组 + for group in self.proxy_groups: + if group["name"] == group_name: + group["proxies"] = [r.name for r in valid_results] + break + + def save(self): + """保存配置到文件""" + try: + # 保存新配置 + with open(self.config_path, 'w', encoding='utf-8') as f: + yaml.dump(self.config, f, allow_unicode=True, sort_keys=False) + print(f"新配置已保存到: {self.config_path}") + except Exception as e: + print(f"保存配置文件失败: {e}") + sys.exit(1) + +# 打印测试结果摘要 +def print_test_summary(group_name: str, results: List[ProxyTestResult]): + """打印测试结果摘要""" + valid_results = [r for r in results if r.is_valid] + invalid_results = [r for r in results if not r.is_valid] + total = len(results) + valid = len(valid_results) + invalid = len(invalid_results) + + print(f"\n策略组 '{group_name}' 测试结果:") + print(f"总节点数: {total}") + print(f"可用节点数: {valid}") + print(f"失效节点数: {invalid}") + + if valid > 0: + avg_delay = sum(r.delay for r in valid_results) / valid + print(f"平均延迟: {avg_delay:.2f}ms") + + print("\n延迟最低的前5个节点:") + sorted_results = sorted(valid_results, key=lambda x: x.delay) + for i, result in enumerate(sorted_results[:5], 1): + print(f"{i}. {result.name}: {result.delay:.2f}ms") + + # if invalid > 0: + # print("\n失效节点:") + # for i, result in enumerate(invalid_results, 1): + # print(f"{i}. {result.name}") + +# 测试一组代理节点 +async def test_group_proxies(clash_api: ClashAPI, proxies: List[str]) -> List[ProxyTestResult]: + """测试一组代理节点""" + print(f"开始测试 {len(proxies)} 个节点 (最大并发: {MAX_CONCURRENT_TESTS})") + + # 创建所有测试任务 + tasks = [clash_api.test_proxy_delay(proxy_name) for proxy_name in proxies] + + # 使用进度显示执行所有任务 + results = [] + for future in asyncio.as_completed(tasks): + result = await future + results.append(result) + # 显示进度 + done = len(results) + total = len(tasks) + print(f"\r进度: {done}/{total} ({done / total * 100:.1f}%)", end="", flush=True) + + return results + +async def proxy_clean(): + # 更新全局配置 + global MAX_CONCURRENT_TESTS, TIMEOUT, CLASH_API_SECRET + + + print(f"===================节点批量检测基本信息======================") + print(f"配置文件: {CONFIG_FILE}") + print(f"API 端口: {CLASH_API_PORTS[0]}") + print(f"并发数量: {MAX_CONCURRENT_TESTS}") + print(f"超时时间: {TIMEOUT}秒") + + # 加载配置 + config = ClashConfig(CONFIG_FILE) + available_groups = config.get_group_names() + + # 确定要测试的策略组 + groups_to_test = available_groups + invalid_groups = set(groups_to_test) - set(available_groups) + if invalid_groups: + print(f"警告: 以下策略组不存在: {', '.join(invalid_groups)}") + groups_to_test = list(set(groups_to_test) & set(available_groups)) + + if not groups_to_test: + print("错误: 没有找到要测试的有效策略组") + print(f"可用的策略组: {', '.join(available_groups)}") + return + + print(f"\n将测试以下策略组: {', '.join(groups_to_test)}") + + # 开始测试 + start_time = datetime.now() + + # 创建支持多端口的API实例 + async with ClashAPI(CLASH_API_HOST, CLASH_API_PORTS, CLASH_API_SECRET) as clash_api: + if not await clash_api.check_connection(): + return + + try: + all_test_results = [] # 收集所有测试结果 + + # 测试每个策略组 + for group_name in groups_to_test: + print(f"\n======================== 开始测试策略组: {group_name} ====================") + proxies = config.get_group_proxies(group_name) + + if not proxies: + print(f"策略组 '{group_name}' 中没有代理节点") + continue + + # 测试该组的所有节点 + results = await test_group_proxies(clash_api, proxies) + all_test_results.extend(results) + + # 打印测试结果摘要 + print_test_summary(group_name, results) + + print('\n===================移除失效节点并按延迟排序======================\n') + # 一次性移除所有失效节点并更新配置 + config.remove_invalid_proxies(all_test_results) + + # 为每个组更新有效节点的顺序 + for group_name in groups_to_test: + group_proxies = config.get_group_proxies(group_name) + group_results = [r for r in all_test_results if r.name in group_proxies] + config.update_group_proxies(group_name, group_results) + print(f"'{group_name}'已按延迟大小重新排序") + + # 保存更新后的配置 + config.save() + + # 显示总耗时 + total_time = (datetime.now() - start_time).total_seconds() + print(f"\n总耗时: {total_time:.2f} 秒") + + except ClashAPIException as e: + print(f"Clash API 错误: {e}") + except Exception as e: + print(f"发生错误: {e}") + raise + +# 获取当前时间的各个组成部分 +def parse_datetime_variables(): + now = datetime.now() + return { + 'Y': str(now.year), + 'm': str(now.month).zfill(2), + 'd': str(now.day).zfill(2), + 'H': str(now.hour).zfill(2), + 'M': str(now.minute).zfill(2), + 'S': str(now.second).zfill(2) + } + +# 移除URL中的代理前缀 +def strip_proxy_prefix(url): + proxy_pattern = r'^https?://[^/]+/https://' + match = re.match(proxy_pattern, url) + if match: + real_url = re.sub(proxy_pattern, 'https://', url) + proxy_prefix = url[:match.end() - 8] + return real_url, proxy_prefix + return url, None + +# 判断是否为GitHub raw URL +def is_github_raw_url(url): + return 'raw.githubusercontent.com' in url + +# 从URL中提取文件模式,返回占位符前后的部分 +def extract_file_pattern(url): + # 查找形如 {x} 的模式 + match = re.search(r'\{x\}(\.[a-zA-Z0-9]+)(?:/|$)', url) + if match: + return match.group(1) # 返回文件后缀,如 '.yaml', '.txt', '.json' + return None + +# 从GitHub API获取匹配指定后缀的文件名 +def get_github_filename(github_url, file_suffix): + match = re.match(r'https://raw\.githubusercontent\.com/([^/]+)/([^/]+)/[^/]+/[^/]+/([^/]+)', github_url) + if not match: + raise ValueError("无法从URL中提取owner和repo信息") + owner, repo,branch = match.groups() + + # 构建API URL + path_part = github_url.split(f'/refs/heads/{branch}/')[-1] + # 移除 {x} 部分来获取目录路径 + path_part = re.sub(r'\{x\}' + re.escape(file_suffix) + '(?:/|$)', '', path_part) + api_url = f"https://api.github.com/repos/{owner}/{repo}/contents/{path_part}" + + response = requests.get(api_url) + if response.status_code != 200: + raise Exception(f"GitHub API请求失败: {response.status_code}") + + files = response.json() + matching_files = [f['name'] for f in files if f['name'].endswith(file_suffix)] + + if not matching_files: + raise Exception(f"未找到匹配的{file_suffix}文件") + + return matching_files[0] + +# 解析URL模板,支持任意组合的日期时间变量和分隔符 +def parse_template(template_url, datetime_vars): + def replace_template(match): + """替换单个模板块的内容""" + template_content = match.group(1) + if template_content == 'x': + return '{x}' # 保持 {x} 不变,供后续处理 + + result = '' + # 用于临时存储当前字符 + current_char = '' + + # 遍历模板内容中的每个字符 + for char in template_content: + if char in datetime_vars: + # 如果是日期时间变量,替换为对应值 + if current_char: + # 添加之前累积的非变量字符 + result += current_char + current_char = '' + result += datetime_vars[char] + else: + # 如果是其他字符(分隔符),直接保留 + current_char += char + + # 添加最后可能剩余的非变量字符 + if current_char: + result += current_char + + return result + + # 使用正则表达式查找并替换所有模板块 + return re.sub(r'\{([^}]+)\}', replace_template, template_url) + +# 完整解析模板URL +def resolve_template_url(template_url): + # 先处理代理前缀 + url, proxy_prefix = strip_proxy_prefix(template_url) + + # 获取日期时间变量 + datetime_vars = parse_datetime_variables() + + # 替换日期时间变量 + resolved_url = parse_template(url, datetime_vars) + + # 如果是GitHub URL且包含{x},则处理文件名 + if is_github_raw_url(resolved_url) and '{x}' in resolved_url: + # 提取文件后缀 + file_suffix = extract_file_pattern(resolved_url) + if file_suffix: + filename = get_github_filename(resolved_url, file_suffix) + # 替换 {x} 为实际文件名 + resolved_url = re.sub(r'\{x\}' + re.escape(file_suffix), filename, resolved_url) + + # 如果有代理前缀,重新添加上 + if proxy_prefix: + resolved_url = f"{proxy_prefix}{resolved_url}" + + return resolved_url + +def work(links,check=False,allowed_types=[]): + try: + load_nodes = read_yaml_files(folder_path=INPUT) + if allowed_types: + load_nodes = filter_by_types_alt(allowed_types,nodes=load_nodes) + links = merge_lists(read_txt_files(folder_path=INPUT), links) + if links or load_nodes: + generate_clash_config(links,load_nodes) + + if check: + clash_process = None + try: + # 启动clash + clash_process = start_clash() + time.sleep(2) + asyncio.run(proxy_clean()) + except Exception as e: + print("Error calling Clash API:", e) + finally: + if clash_process is not None: + # 关闭 Clash + clash_process.terminate() + clash_process.wait() # 等待进程完全结束 + # print("Clash has been stopped.") + except KeyboardInterrupt: + print("\n用户中断执行") + sys.exit(0) + except Exception as e: + print(f"程序执行失败: {e}") + sys.exit(1) + + +if __name__ == '__main__': + links = [ + "https://proxypool.link/ss/sub", + "https://proxypool.link/vmess/sub", + "https://proxypool.link/trojan/sub", + "https://gitdl.cn/https://raw.githubusercontent.com/Q3dlaXpoaQ/V2rayN_Clash_Node_Getter/refs/heads/main/APIs/sc0.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/Q3dlaXpoaQ/V2rayN_Clash_Node_Getter/refs/heads/main/APIs/sc1.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/Q3dlaXpoaQ/V2rayN_Clash_Node_Getter/refs/heads/main/APIs/sc2.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/Q3dlaXpoaQ/V2rayN_Clash_Node_Getter/refs/heads/main/APIs/sc3.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/Q3dlaXpoaQ/V2rayN_Clash_Node_Getter/refs/heads/main/APIs/sc4.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/snakem982/proxypool/main/source/clash-meta.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/chengaopan/AutoMergePublicNodes/master/list.yml", + "https://gitdl.cn/https://raw.githubusercontent.com/ermaozi/get_subscribe/main/subscribe/clash.yml", + "https://gitdl.cn/https://raw.githubusercontent.com/ripaojiedian/freenode/main/clash", + "https://gitdl.cn/https://raw.githubusercontent.com/vxiaov/free_proxies/main/clash/clash.provider.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/go4sharing/sub/main/sub.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/mfbpn/tg_mfbpn_sub/main/trial.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/free18/v2ray/refs/heads/main/c.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/firefoxmmx2/v2rayshare_subcription/main/subscription/clash_sub.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/Pawdroid/Free-servers/refs/heads/main/sub", + "https://gitdl.cn/https://raw.githubusercontent.com/Roywaller/clash_subscription/refs/heads/main/clash_subscription.txt", + "https://gitdl.cn/https://raw.githubusercontent.com/peasoft/NoMoreWalls/master/list.yml", + "https://gitdl.cn/https://raw.githubusercontent.com/mgit0001/test_clash/refs/heads/main/heima.txt", + "https://gitdl.cn/https://raw.githubusercontent.com/shahidbhutta/Clash/refs/heads/main/Router", + "https://gitdl.cn/https://raw.githubusercontent.com/zhangkaiitugithub/passcro/main/speednodes.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/mfuu/v2ray/master/clash.yaml", + "https://gitdl.cn/https://raw.githubusercontent.com/Ruk1ng001/freeSub/main/clash.yaml", + # "https://gitdl.cn/https://raw.githubusercontent.com/skka3134/test/refs/heads/main/test.yaml", clash.yaml + "https://gitdl.cn/https://raw.githubusercontent.com/wangyingbo/yb_clashgithub_sub/main/clash_sub.yml", + "https://gitdl.cn/https://raw.githubusercontent.com/mai19950/clashgithub_com/refs/heads/main/site", + "https://clashgithub.com/wp-content/uploads/rss/{Ymd}.yml", + "https://gitdl.cn/https://raw.githubusercontent.com/xiaoer8867785/jddy5/refs/heads/main/data/{Y_m_d}/{x}.yaml", + "https://sub.reajason.eu.org/clash.yaml", + "https://clash.llleman.com/clach.yml", + "https://api.mxlweb.xyz/sub?target=clash&url=https://www.xrayvip.com/free.yaml&insert=false", + "https://api.mxlweb.xyz/sub?target=clash&url=https://mxlsub.me/free&insert=false" + "https://mxlsub.me/newfull", + "https://igdux.top/5Hna", + "https://raw.githubusercontent.com/leetomlee123/freenode/refs/heads/main/README.md", + # "https://gitdl.cn/https://raw.githubusercontent.com/tglaoshiji/nodeshare/refs/heads/main/{Y}/9/{Ymd}.yaml", + # "https://v1.mk/hdiKEIf", # "https://gist-collect.fqzs.workers.dev/clach.yml" + ] + + work(links, check=True) diff --git a/README.md b/README.md new file mode 100644 index 0000000..04f0606 --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +# ClashNodeConverter + +## 功能 +- 将`hysteria2://`、`trojan://`、`ss://`、`vless://`、`vmess://`协议链接转换为clash可用的代理节点配置 +- 支持从`input`目录下的所有txt文档中按行读取代理链接(每条代理链接占一行) +- 支持从`input`目录下的所有yaml/yml读取proxies +- 支持指定代理类型过滤,指定参数allowed_types=['ss'] +- 支持从现有的clash订阅地址提取代理节点 +- 支持从某些github的readme.md获取代理节点 +- 支持占位符匹配,Y年m月d日H时M分 例:{Ymd} {Y_m_d} {Y-m-d} +- 支持github文件名模糊匹配,{x}.yaml表示不确定文件名的yaml文件 +- 将所有获取的代理节点汇聚到一个配置文件里,根据server和port进行去重,name重复自动添加随机后缀,分组`自动选择`、`故障转移`、`手动选择`,策略中排除了国内节点 +- 支持全自动批量检测节点有效性,移除失效节点,并按延迟大小排序,无需人工介入(首次执行会自动下载clash二进制) + +配置参考:https://wiki.metacubex.one/config/ +clash二进制:https://github.com/MetaCubeX/mihomo/releases + +--- +# 免费机场 + +网络搜集,仅限于学习研究 + +订阅地址转换:https://proxy.fish2018.us.kg/ + +``` +https://proxypool.link/ss/sub +https://proxypool.link/vmess/sub +https://proxypool.link/trojan/sub +https://gitdl.cn/https://raw.githubusercontent.com/Q3dlaXpoaQ/V2rayN_Clash_Node_Getter/refs/heads/main/APIs/sc0.yaml +https://gitdl.cn/https://raw.githubusercontent.com/Q3dlaXpoaQ/V2rayN_Clash_Node_Getter/refs/heads/main/APIs/sc1.yaml +https://gitdl.cn/https://raw.githubusercontent.com/Q3dlaXpoaQ/V2rayN_Clash_Node_Getter/refs/heads/main/APIs/sc2.yaml +https://gitdl.cn/https://raw.githubusercontent.com/Q3dlaXpoaQ/V2rayN_Clash_Node_Getter/refs/heads/main/APIs/sc3.yaml +https://gitdl.cn/https://raw.githubusercontent.com/Q3dlaXpoaQ/V2rayN_Clash_Node_Getter/refs/heads/main/APIs/sc4.yaml +https://gitdl.cn/https://raw.githubusercontent.com/snakem982/proxypool/main/source/clash-meta.yaml +https://gitdl.cn/https://raw.githubusercontent.com/chengaopan/AutoMergePublicNodes/master/list.yml +https://gitdl.cn/https://raw.githubusercontent.com/ermaozi/get_subscribe/main/subscribe/clash.yml +https://gitdl.cn/https://raw.githubusercontent.com/ripaojiedian/freenode/main/clash +https://gitdl.cn/https://raw.githubusercontent.com/vxiaov/free_proxies/main/clash/clash.provider.yaml +https://gitdl.cn/https://raw.githubusercontent.com/go4sharing/sub/main/sub.yaml +https://gitdl.cn/https://raw.githubusercontent.com/mfbpn/tg_mfbpn_sub/main/trial.yaml +https://gitdl.cn/https://raw.githubusercontent.com/free18/v2ray/refs/heads/main/c.yaml +https://gitdl.cn/https://raw.githubusercontent.com/firefoxmmx2/v2rayshare_subcription/main/subscription/clash_sub.yaml +https://gitdl.cn/https://raw.githubusercontent.com/Pawdroid/Free-servers/refs/heads/main/sub +https://gitdl.cn/https://raw.githubusercontent.com/Roywaller/clash_subscription/refs/heads/main/clash_subscription.txt +https://gitdl.cn/https://raw.githubusercontent.com/peasoft/NoMoreWalls/master/list.yml +https://gitdl.cn/https://raw.githubusercontent.com/mgit0001/test_clash/refs/heads/main/heima.txt +https://gitdl.cn/https://raw.githubusercontent.com/shahidbhutta/Clash/refs/heads/main/Router +https://gitdl.cn/https://raw.githubusercontent.com/zhangkaiitugithub/passcro/main/speednodes.yaml +https://gitdl.cn/https://raw.githubusercontent.com/mfuu/v2ray/master/clash.yaml +https://gitdl.cn/https://raw.githubusercontent.com/Ruk1ng001/freeSub/main/clash.yaml +https://gitdl.cn/https://raw.githubusercontent.com/skka3134/test/refs/heads/main/hk.yaml +https://gitdl.cn/https://raw.githubusercontent.com/skka3134/test/refs/heads/main/test.yaml +https://gitdl.cn/https://raw.githubusercontent.com/wangyingbo/yb_clashgithub_sub/main/clash_sub.yml +https://gitdl.cn/https://raw.githubusercontent.com/mai19950/clashgithub_com/refs/heads/main/site +https://clashgithub.com/wp-content/uploads/rss/{Ymd}.yml +https://gitdl.cn/https://raw.githubusercontent.com/xiaoer8867785/jddy5/refs/heads/main/data/{Y_m_d}/{x}.yaml +https://gitdl.cn/https://raw.githubusercontent.com/leetomlee123/freenode/refs/heads/main/README.md +https://sub.reajason.eu.org/clash.yaml +https://clash.llleman.com/clach.yml +https://api.mxlweb.xyz/sub?target=clash&url=https://www.xrayvip.com/free.yaml&insert=false +https://api.mxlweb.xyz/sub?target=clash&url=https://mxlsub.me/free&insert=false +https://mxlsub.me/newfull +https://igdux.top/5Hna +https://v1.mk/hdiKEIf +https://gitdl.cn/https://raw.githubusercontent.com/tglaoshiji/nodeshare/refs/heads/main/{Y}/9/{Ymd}.yaml +``` diff --git a/clash_config.yaml b/clash_config.yaml new file mode 100644 index 0000000..91e5bae --- /dev/null +++ b/clash_config.yaml @@ -0,0 +1,567 @@ +allow-lan: true +dns: + default-nameserver: + - 223.5.5.5 + - 119.29.29.29 + enable: true + enhanced-mode: fake-ip + fake-ip-range: 198.18.0.1/16 + fallback: + - https://doh.dns.sb/dns-query + - https://dns.cloudflare.com/dns-query + - https://dns.twnic.tw/dns-query + - tls://8.8.4.4:853 + fallback-filter: + geoip: true + ipcidr: + - 240.0.0.0/4 + - 0.0.0.0/32 + ipv6: false + nameserver: + - https://doh.pub/dns-query + - https://dns.alidns.com/dns-query + use-hosts: true +external-controller: 127.0.0.1:9090 +log-level: info +mode: rule +port: 7890 +proxies: [] +proxy-groups: +- name: 节点选择 + proxies: + - DIRECT + type: select +- exclude-filter: (?i)中国|China|CN|电信|移动|联通 + interval: 300 + name: 自动选择 + proxies: [] + type: url-test + url: http://www.gstatic.com/generate_204 +- exclude-filter: (?i)中国|China|CN|电信|移动|联通 + interval: 300 + name: 故障转移 + proxies: [] + type: fallback + url: http://www.gstatic.com/generate_204 +- name: 手动选择 + proxies: [] + type: select +redir-port: 7892 +rules: +- IP-CIDR,80.85.152.22/32,DIRECT,no-resolve +- IP-CIDR,212.87.195.76/32,DIRECT,no-resolve +- DOMAIN,209.200.246.194:7002,DIRECT +- DOMAIN-SUFFIX,services.googleapis.cn,节点选择 +- DOMAIN-SUFFIX,xn--ngstr-lra8j.com,节点选择 +- DOMAIN,safebrowsing.urlsec.qq.com,DIRECT +- DOMAIN,safebrowsing.googleapis.com,DIRECT +- DOMAIN,developer.apple.com,节点选择 +- DOMAIN-SUFFIX,digicert.com,节点选择 +- DOMAIN,ocsp.apple.com,节点选择 +- DOMAIN,ocsp.comodoca.com,节点选择 +- DOMAIN,ocsp.usertrust.com,节点选择 +- DOMAIN,ocsp.sectigo.com,节点选择 +- DOMAIN,ocsp.verisign.net,节点选择 +- DOMAIN-SUFFIX,apple-dns.net,节点选择 +- DOMAIN,testflight.apple.com,节点选择 +- DOMAIN,sandbox.itunes.apple.com,节点选择 +- DOMAIN,itunes.apple.com,节点选择 +- DOMAIN-SUFFIX,apps.apple.com,节点选择 +- DOMAIN-SUFFIX,blobstore.apple.com,节点选择 +- DOMAIN,cvws.icloud-content.com,节点选择 +- DOMAIN-SUFFIX,mzstatic.com,DIRECT +- DOMAIN-SUFFIX,itunes.apple.com,DIRECT +- DOMAIN-SUFFIX,icloud.com,DIRECT +- DOMAIN-SUFFIX,icloud-content.com,DIRECT +- DOMAIN-SUFFIX,me.com,DIRECT +- DOMAIN-SUFFIX,aaplimg.com,DIRECT +- DOMAIN-SUFFIX,cdn20.com,DIRECT +- DOMAIN-SUFFIX,cdn-apple.com,DIRECT +- DOMAIN-SUFFIX,akadns.net,DIRECT +- DOMAIN-SUFFIX,akamaiedge.net,DIRECT +- DOMAIN-SUFFIX,edgekey.net,DIRECT +- DOMAIN-SUFFIX,mwcloudcdn.com,DIRECT +- DOMAIN-SUFFIX,mwcname.com,DIRECT +- DOMAIN-SUFFIX,apple.com,DIRECT +- DOMAIN-SUFFIX,apple-cloudkit.com,DIRECT +- DOMAIN-SUFFIX,apple-mapkit.com,DIRECT +- DOMAIN-SUFFIX,126.com,DIRECT +- DOMAIN-SUFFIX,126.net,DIRECT +- DOMAIN-SUFFIX,127.net,DIRECT +- DOMAIN-SUFFIX,163.com,DIRECT +- DOMAIN-SUFFIX,360buyimg.com,DIRECT +- DOMAIN-SUFFIX,36kr.com,DIRECT +- DOMAIN-SUFFIX,acfun.tv,DIRECT +- DOMAIN-SUFFIX,air-matters.com,DIRECT +- DOMAIN-SUFFIX,aixifan.com,DIRECT +- DOMAIN-KEYWORD,alicdn,DIRECT +- DOMAIN-KEYWORD,alipay,DIRECT +- DOMAIN-KEYWORD,taobao,DIRECT +- DOMAIN-SUFFIX,amap.com,DIRECT +- DOMAIN-SUFFIX,autonavi.com,DIRECT +- DOMAIN-KEYWORD,baidu,DIRECT +- DOMAIN-SUFFIX,bdimg.com,DIRECT +- DOMAIN-SUFFIX,bdstatic.com,DIRECT +- DOMAIN-SUFFIX,bilibili.com,DIRECT +- DOMAIN-SUFFIX,bilivideo.com,DIRECT +- DOMAIN-SUFFIX,caiyunapp.com,DIRECT +- DOMAIN-SUFFIX,clouddn.com,DIRECT +- DOMAIN-SUFFIX,cnbeta.com,DIRECT +- DOMAIN-SUFFIX,cnbetacdn.com,DIRECT +- DOMAIN-SUFFIX,cootekservice.com,DIRECT +- DOMAIN-SUFFIX,csdn.net,DIRECT +- DOMAIN-SUFFIX,ctrip.com,DIRECT +- DOMAIN-SUFFIX,dgtle.com,DIRECT +- DOMAIN-SUFFIX,dianping.com,DIRECT +- DOMAIN-SUFFIX,douban.com,DIRECT +- DOMAIN-SUFFIX,doubanio.com,DIRECT +- DOMAIN-SUFFIX,duokan.com,DIRECT +- DOMAIN-SUFFIX,easou.com,DIRECT +- DOMAIN-SUFFIX,ele.me,DIRECT +- DOMAIN-SUFFIX,feng.com,DIRECT +- DOMAIN-SUFFIX,fir.im,DIRECT +- DOMAIN-SUFFIX,frdic.com,DIRECT +- DOMAIN-SUFFIX,g-cores.com,DIRECT +- DOMAIN-SUFFIX,godic.net,DIRECT +- DOMAIN-SUFFIX,gtimg.com,DIRECT +- DOMAIN,cdn.hockeyapp.net,DIRECT +- DOMAIN-SUFFIX,hongxiu.com,DIRECT +- DOMAIN-SUFFIX,hxcdn.net,DIRECT +- DOMAIN-SUFFIX,iciba.com,DIRECT +- DOMAIN-SUFFIX,ifeng.com,DIRECT +- DOMAIN-SUFFIX,ifengimg.com,DIRECT +- DOMAIN-SUFFIX,ipip.net,DIRECT +- DOMAIN-SUFFIX,iqiyi.com,DIRECT +- DOMAIN-SUFFIX,jd.com,DIRECT +- DOMAIN-SUFFIX,jianshu.com,DIRECT +- DOMAIN-SUFFIX,knewone.com,DIRECT +- DOMAIN-SUFFIX,le.com,DIRECT +- DOMAIN-SUFFIX,lecloud.com,DIRECT +- DOMAIN-SUFFIX,lemicp.com,DIRECT +- DOMAIN-SUFFIX,licdn.com,DIRECT +- DOMAIN-SUFFIX,luoo.net,DIRECT +- DOMAIN-SUFFIX,meituan.com,DIRECT +- DOMAIN-SUFFIX,meituan.net,DIRECT +- DOMAIN-SUFFIX,mi.com,DIRECT +- DOMAIN-SUFFIX,miaopai.com,DIRECT +- DOMAIN-SUFFIX,microsoft.com,DIRECT +- DOMAIN-SUFFIX,microsoftonline.com,DIRECT +- DOMAIN-SUFFIX,miui.com,DIRECT +- DOMAIN-SUFFIX,miwifi.com,DIRECT +- DOMAIN-SUFFIX,mob.com,DIRECT +- DOMAIN-SUFFIX,netease.com,DIRECT +- DOMAIN-SUFFIX,office.com,DIRECT +- DOMAIN-SUFFIX,office365.com,DIRECT +- DOMAIN-KEYWORD,officecdn,DIRECT +- DOMAIN-SUFFIX,oschina.net,DIRECT +- DOMAIN-SUFFIX,ppsimg.com,DIRECT +- DOMAIN-SUFFIX,pstatp.com,DIRECT +- DOMAIN-SUFFIX,qcloud.com,DIRECT +- DOMAIN-SUFFIX,qdaily.com,DIRECT +- DOMAIN-SUFFIX,qdmm.com,DIRECT +- DOMAIN-SUFFIX,qhimg.com,DIRECT +- DOMAIN-SUFFIX,qhres.com,DIRECT +- DOMAIN-SUFFIX,qidian.com,DIRECT +- DOMAIN-SUFFIX,qihucdn.com,DIRECT +- DOMAIN-SUFFIX,qiniu.com,DIRECT +- DOMAIN-SUFFIX,qiniucdn.com,DIRECT +- DOMAIN-SUFFIX,qiyipic.com,DIRECT +- DOMAIN-SUFFIX,qq.com,DIRECT +- DOMAIN-SUFFIX,qqurl.com,DIRECT +- DOMAIN-SUFFIX,rarbg.to,DIRECT +- DOMAIN-SUFFIX,ruguoapp.com,DIRECT +- DOMAIN-SUFFIX,segmentfault.com,DIRECT +- DOMAIN-SUFFIX,sinaapp.com,DIRECT +- DOMAIN-SUFFIX,smzdm.com,DIRECT +- DOMAIN-SUFFIX,snapdrop.net,DIRECT +- DOMAIN-SUFFIX,sogou.com,DIRECT +- DOMAIN-SUFFIX,sogoucdn.com,DIRECT +- DOMAIN-SUFFIX,sohu.com,DIRECT +- DOMAIN-SUFFIX,soku.com,DIRECT +- DOMAIN-SUFFIX,speedtest.net,DIRECT +- DOMAIN-SUFFIX,sspai.com,DIRECT +- DOMAIN-SUFFIX,suning.com,DIRECT +- DOMAIN-SUFFIX,taobao.com,DIRECT +- DOMAIN-SUFFIX,tencent.com,DIRECT +- DOMAIN-SUFFIX,tenpay.com,DIRECT +- DOMAIN-SUFFIX,tianyancha.com,DIRECT +- DOMAIN-SUFFIX,tmall.com,DIRECT +- DOMAIN-SUFFIX,tudou.com,DIRECT +- DOMAIN-SUFFIX,umetrip.com,DIRECT +- DOMAIN-SUFFIX,upaiyun.com,DIRECT +- DOMAIN-SUFFIX,upyun.com,DIRECT +- DOMAIN-SUFFIX,veryzhun.com,DIRECT +- DOMAIN-SUFFIX,weather.com,DIRECT +- DOMAIN-SUFFIX,weibo.com,DIRECT +- DOMAIN-SUFFIX,xiami.com,DIRECT +- DOMAIN-SUFFIX,xiami.net,DIRECT +- DOMAIN-SUFFIX,xiaomicp.com,DIRECT +- DOMAIN-SUFFIX,ximalaya.com,DIRECT +- DOMAIN-SUFFIX,xmcdn.com,DIRECT +- DOMAIN-SUFFIX,xunlei.com,DIRECT +- DOMAIN-SUFFIX,yhd.com,DIRECT +- DOMAIN-SUFFIX,yihaodianimg.com,DIRECT +- DOMAIN-SUFFIX,yinxiang.com,DIRECT +- DOMAIN-SUFFIX,ykimg.com,DIRECT +- DOMAIN-SUFFIX,youdao.com,DIRECT +- DOMAIN-SUFFIX,youku.com,DIRECT +- DOMAIN-SUFFIX,zealer.com,DIRECT +- DOMAIN-SUFFIX,zhihu.com,DIRECT +- DOMAIN-SUFFIX,zhimg.com,DIRECT +- DOMAIN-SUFFIX,zimuzu.tv,DIRECT +- DOMAIN-SUFFIX,zoho.com,DIRECT +- DOMAIN-KEYWORD,amazon,节点选择 +- DOMAIN-KEYWORD,google,节点选择 +- DOMAIN-KEYWORD,gmail,节点选择 +- DOMAIN-KEYWORD,youtube,节点选择 +- DOMAIN-KEYWORD,facebook,节点选择 +- DOMAIN-SUFFIX,fb.me,节点选择 +- DOMAIN-SUFFIX,fbcdn.net,节点选择 +- DOMAIN-KEYWORD,twitter,节点选择 +- DOMAIN-KEYWORD,instagram,节点选择 +- DOMAIN-KEYWORD,dropbox,节点选择 +- DOMAIN-SUFFIX,twimg.com,节点选择 +- DOMAIN-KEYWORD,blogspot,节点选择 +- DOMAIN-SUFFIX,youtu.be,节点选择 +- DOMAIN-KEYWORD,whatsapp,节点选择 +- DOMAIN-KEYWORD,admarvel,REJECT +- DOMAIN-KEYWORD,admaster,REJECT +- DOMAIN-KEYWORD,adsage,REJECT +- DOMAIN-KEYWORD,adsmogo,REJECT +- DOMAIN-KEYWORD,adsrvmedia,REJECT +- DOMAIN-KEYWORD,adwords,REJECT +- DOMAIN-KEYWORD,adservice,REJECT +- DOMAIN-SUFFIX,appsflyer.com,REJECT +- DOMAIN-KEYWORD,domob,REJECT +- DOMAIN-SUFFIX,doubleclick.net,REJECT +- DOMAIN-KEYWORD,duomeng,REJECT +- DOMAIN-KEYWORD,dwtrack,REJECT +- DOMAIN-KEYWORD,guanggao,REJECT +- DOMAIN-KEYWORD,lianmeng,REJECT +- DOMAIN-SUFFIX,mmstat.com,REJECT +- DOMAIN-KEYWORD,mopub,REJECT +- DOMAIN-KEYWORD,omgmta,REJECT +- DOMAIN-KEYWORD,openx,REJECT +- DOMAIN-KEYWORD,partnerad,REJECT +- DOMAIN-KEYWORD,pingfore,REJECT +- DOMAIN-KEYWORD,supersonicads,REJECT +- DOMAIN-KEYWORD,uedas,REJECT +- DOMAIN-KEYWORD,umeng,REJECT +- DOMAIN-KEYWORD,usage,REJECT +- DOMAIN-SUFFIX,vungle.com,REJECT +- DOMAIN-KEYWORD,wlmonitor,REJECT +- DOMAIN-KEYWORD,zjtoolbar,REJECT +- DOMAIN-SUFFIX,9to5mac.com,节点选择 +- DOMAIN-SUFFIX,abpchina.org,节点选择 +- DOMAIN-SUFFIX,adblockplus.org,节点选择 +- DOMAIN-SUFFIX,adobe.com,节点选择 +- DOMAIN-SUFFIX,akamaized.net,节点选择 +- DOMAIN-SUFFIX,alfredapp.com,节点选择 +- DOMAIN-SUFFIX,amplitude.com,节点选择 +- DOMAIN-SUFFIX,ampproject.org,节点选择 +- DOMAIN-SUFFIX,android.com,节点选择 +- DOMAIN-SUFFIX,angularjs.org,节点选择 +- DOMAIN-SUFFIX,aolcdn.com,节点选择 +- DOMAIN-SUFFIX,apkpure.com,节点选择 +- DOMAIN-SUFFIX,appledaily.com,节点选择 +- DOMAIN-SUFFIX,appshopper.com,节点选择 +- DOMAIN-SUFFIX,appspot.com,节点选择 +- DOMAIN-SUFFIX,arcgis.com,节点选择 +- DOMAIN-SUFFIX,archive.org,节点选择 +- DOMAIN-SUFFIX,armorgames.com,节点选择 +- DOMAIN-SUFFIX,aspnetcdn.com,节点选择 +- DOMAIN-SUFFIX,att.com,节点选择 +- DOMAIN-SUFFIX,awsstatic.com,节点选择 +- DOMAIN-SUFFIX,azureedge.net,节点选择 +- DOMAIN-SUFFIX,azurewebsites.net,节点选择 +- DOMAIN-SUFFIX,bing.com,节点选择 +- DOMAIN-SUFFIX,bintray.com,节点选择 +- DOMAIN-SUFFIX,bit.com,节点选择 +- DOMAIN-SUFFIX,bit.ly,节点选择 +- DOMAIN-SUFFIX,bitbucket.org,节点选择 +- DOMAIN-SUFFIX,bjango.com,节点选择 +- DOMAIN-SUFFIX,bkrtx.com,节点选择 +- DOMAIN-SUFFIX,blog.com,节点选择 +- DOMAIN-SUFFIX,blogcdn.com,节点选择 +- DOMAIN-SUFFIX,blogger.com,节点选择 +- DOMAIN-SUFFIX,blogsmithmedia.com,节点选择 +- DOMAIN-SUFFIX,blogspot.com,节点选择 +- DOMAIN-SUFFIX,blogspot.hk,节点选择 +- DOMAIN-SUFFIX,bloomberg.com,节点选择 +- DOMAIN-SUFFIX,box.com,节点选择 +- DOMAIN-SUFFIX,box.net,节点选择 +- DOMAIN-SUFFIX,cachefly.net,节点选择 +- DOMAIN-SUFFIX,chromium.org,节点选择 +- DOMAIN-SUFFIX,cl.ly,节点选择 +- DOMAIN-SUFFIX,cloudflare.com,节点选择 +- DOMAIN-SUFFIX,cloudfront.net,节点选择 +- DOMAIN-SUFFIX,cloudmagic.com,节点选择 +- DOMAIN-SUFFIX,cmail19.com,节点选择 +- DOMAIN-SUFFIX,cnet.com,节点选择 +- DOMAIN-SUFFIX,cocoapods.org,节点选择 +- DOMAIN-SUFFIX,comodoca.com,节点选择 +- DOMAIN-SUFFIX,crashlytics.com,节点选择 +- DOMAIN-SUFFIX,culturedcode.com,节点选择 +- DOMAIN-SUFFIX,d.pr,节点选择 +- DOMAIN-SUFFIX,danilo.to,节点选择 +- DOMAIN-SUFFIX,dayone.me,节点选择 +- DOMAIN-SUFFIX,db.tt,节点选择 +- DOMAIN-SUFFIX,deskconnect.com,节点选择 +- DOMAIN-SUFFIX,disq.us,节点选择 +- DOMAIN-SUFFIX,disqus.com,节点选择 +- DOMAIN-SUFFIX,disquscdn.com,节点选择 +- DOMAIN-SUFFIX,dnsimple.com,节点选择 +- DOMAIN-SUFFIX,docker.com,节点选择 +- DOMAIN-SUFFIX,dribbble.com,节点选择 +- DOMAIN-SUFFIX,droplr.com,节点选择 +- DOMAIN-SUFFIX,duckduckgo.com,节点选择 +- DOMAIN-SUFFIX,dueapp.com,节点选择 +- DOMAIN-SUFFIX,dytt8.net,节点选择 +- DOMAIN-SUFFIX,edgecastcdn.net,节点选择 +- DOMAIN-SUFFIX,edgekey.net,节点选择 +- DOMAIN-SUFFIX,edgesuite.net,节点选择 +- DOMAIN-SUFFIX,engadget.com,节点选择 +- DOMAIN-SUFFIX,entrust.net,节点选择 +- DOMAIN-SUFFIX,eurekavpt.com,节点选择 +- DOMAIN-SUFFIX,evernote.com,节点选择 +- DOMAIN-SUFFIX,fabric.io,节点选择 +- DOMAIN-SUFFIX,fast.com,节点选择 +- DOMAIN-SUFFIX,fastly.net,节点选择 +- DOMAIN-SUFFIX,fc2.com,节点选择 +- DOMAIN-SUFFIX,feedburner.com,节点选择 +- DOMAIN-SUFFIX,feedly.com,节点选择 +- DOMAIN-SUFFIX,feedsportal.com,节点选择 +- DOMAIN-SUFFIX,fiftythree.com,节点选择 +- DOMAIN-SUFFIX,firebaseio.com,节点选择 +- DOMAIN-SUFFIX,flexibits.com,节点选择 +- DOMAIN-SUFFIX,flickr.com,节点选择 +- DOMAIN-SUFFIX,flipboard.com,节点选择 +- DOMAIN-SUFFIX,g.co,节点选择 +- DOMAIN-SUFFIX,gabia.net,节点选择 +- DOMAIN-SUFFIX,geni.us,节点选择 +- DOMAIN-SUFFIX,gfx.ms,节点选择 +- DOMAIN-SUFFIX,ggpht.com,节点选择 +- DOMAIN-SUFFIX,ghostnoteapp.com,节点选择 +- DOMAIN-SUFFIX,git.io,节点选择 +- DOMAIN-KEYWORD,github,节点选择 +- DOMAIN-SUFFIX,globalsign.com,节点选择 +- DOMAIN-SUFFIX,gmodules.com,节点选择 +- DOMAIN-SUFFIX,godaddy.com,节点选择 +- DOMAIN-SUFFIX,golang.org,节点选择 +- DOMAIN-SUFFIX,gongm.in,节点选择 +- DOMAIN-SUFFIX,goo.gl,节点选择 +- DOMAIN-SUFFIX,goodreaders.com,节点选择 +- DOMAIN-SUFFIX,goodreads.com,节点选择 +- DOMAIN-SUFFIX,gravatar.com,节点选择 +- DOMAIN-SUFFIX,gstatic.com,节点选择 +- DOMAIN-SUFFIX,gvt0.com,节点选择 +- DOMAIN-SUFFIX,hockeyapp.net,节点选择 +- DOMAIN-SUFFIX,hotmail.com,节点选择 +- DOMAIN-SUFFIX,icons8.com,节点选择 +- DOMAIN-SUFFIX,ifixit.com,节点选择 +- DOMAIN-SUFFIX,ift.tt,节点选择 +- DOMAIN-SUFFIX,ifttt.com,节点选择 +- DOMAIN-SUFFIX,iherb.com,节点选择 +- DOMAIN-SUFFIX,imageshack.us,节点选择 +- DOMAIN-SUFFIX,img.ly,节点选择 +- DOMAIN-SUFFIX,imgur.com,节点选择 +- DOMAIN-SUFFIX,imore.com,节点选择 +- DOMAIN-SUFFIX,instapaper.com,节点选择 +- DOMAIN-SUFFIX,ipn.li,节点选择 +- DOMAIN-SUFFIX,is.gd,节点选择 +- DOMAIN-SUFFIX,issuu.com,节点选择 +- DOMAIN-SUFFIX,itgonglun.com,节点选择 +- DOMAIN-SUFFIX,itun.es,节点选择 +- DOMAIN-SUFFIX,ixquick.com,节点选择 +- DOMAIN-SUFFIX,j.mp,节点选择 +- DOMAIN-SUFFIX,js.revsci.net,节点选择 +- DOMAIN-SUFFIX,jshint.com,节点选择 +- DOMAIN-SUFFIX,jtvnw.net,节点选择 +- DOMAIN-SUFFIX,justgetflux.com,节点选择 +- DOMAIN-SUFFIX,kat.cr,节点选择 +- DOMAIN-SUFFIX,klip.me,节点选择 +- DOMAIN-SUFFIX,libsyn.com,节点选择 +- DOMAIN-SUFFIX,linkedin.com,节点选择 +- DOMAIN-SUFFIX,line-apps.com,节点选择 +- DOMAIN-SUFFIX,linode.com,节点选择 +- DOMAIN-SUFFIX,lithium.com,节点选择 +- DOMAIN-SUFFIX,littlehj.com,节点选择 +- DOMAIN-SUFFIX,live.com,节点选择 +- DOMAIN-SUFFIX,live.net,节点选择 +- DOMAIN-SUFFIX,livefilestore.com,节点选择 +- DOMAIN-SUFFIX,llnwd.net,节点选择 +- DOMAIN-SUFFIX,macid.co,节点选择 +- DOMAIN-SUFFIX,macromedia.com,节点选择 +- DOMAIN-SUFFIX,macrumors.com,节点选择 +- DOMAIN-SUFFIX,mashable.com,节点选择 +- DOMAIN-SUFFIX,mathjax.org,节点选择 +- DOMAIN-SUFFIX,medium.com,节点选择 +- DOMAIN-SUFFIX,mega.co.nz,节点选择 +- DOMAIN-SUFFIX,mega.nz,节点选择 +- DOMAIN-SUFFIX,megaupload.com,节点选择 +- DOMAIN-SUFFIX,microsofttranslator.com,节点选择 +- DOMAIN-SUFFIX,mindnode.com,节点选择 +- DOMAIN-SUFFIX,mobile01.com,节点选择 +- DOMAIN-SUFFIX,modmyi.com,节点选择 +- DOMAIN-SUFFIX,msedge.net,节点选择 +- DOMAIN-SUFFIX,myfontastic.com,节点选择 +- DOMAIN-SUFFIX,name.com,节点选择 +- DOMAIN-SUFFIX,nextmedia.com,节点选择 +- DOMAIN-SUFFIX,nsstatic.net,节点选择 +- DOMAIN-SUFFIX,nssurge.com,节点选择 +- DOMAIN-SUFFIX,nyt.com,节点选择 +- DOMAIN-SUFFIX,nytimes.com,节点选择 +- DOMAIN-SUFFIX,omnigroup.com,节点选择 +- DOMAIN-SUFFIX,onedrive.com,节点选择 +- DOMAIN-SUFFIX,onenote.com,节点选择 +- DOMAIN-SUFFIX,ooyala.com,节点选择 +- DOMAIN-SUFFIX,openvpn.net,节点选择 +- DOMAIN-SUFFIX,openwrt.org,节点选择 +- DOMAIN-SUFFIX,orkut.com,节点选择 +- DOMAIN-SUFFIX,osxdaily.com,节点选择 +- DOMAIN-SUFFIX,outlook.com,节点选择 +- DOMAIN-SUFFIX,ow.ly,节点选择 +- DOMAIN-SUFFIX,paddleapi.com,节点选择 +- DOMAIN-SUFFIX,parallels.com,节点选择 +- DOMAIN-SUFFIX,parse.com,节点选择 +- DOMAIN-SUFFIX,pdfexpert.com,节点选择 +- DOMAIN-SUFFIX,periscope.tv,节点选择 +- DOMAIN-SUFFIX,pinboard.in,节点选择 +- DOMAIN-SUFFIX,pinterest.com,节点选择 +- DOMAIN-SUFFIX,pixelmator.com,节点选择 +- DOMAIN-SUFFIX,pixiv.net,节点选择 +- DOMAIN-SUFFIX,playpcesor.com,节点选择 +- DOMAIN-SUFFIX,playstation.com,节点选择 +- DOMAIN-SUFFIX,playstation.com.hk,节点选择 +- DOMAIN-SUFFIX,playstation.net,节点选择 +- DOMAIN-SUFFIX,playstationnetwork.com,节点选择 +- DOMAIN-SUFFIX,pushwoosh.com,节点选择 +- DOMAIN-SUFFIX,rime.im,节点选择 +- DOMAIN-SUFFIX,servebom.com,节点选择 +- DOMAIN-SUFFIX,sfx.ms,节点选择 +- DOMAIN-SUFFIX,shadowsocks.org,节点选择 +- DOMAIN-SUFFIX,sharethis.com,节点选择 +- DOMAIN-SUFFIX,shazam.com,节点选择 +- DOMAIN-SUFFIX,skype.com,节点选择 +- DOMAIN-SUFFIX,smartdns节点选择.com,节点选择 +- DOMAIN-SUFFIX,smartmailcloud.com,节点选择 +- DOMAIN-SUFFIX,sndcdn.com,节点选择 +- DOMAIN-SUFFIX,sony.com,节点选择 +- DOMAIN-SUFFIX,soundcloud.com,节点选择 +- DOMAIN-SUFFIX,sourceforge.net,节点选择 +- DOMAIN-SUFFIX,spotify.com,节点选择 +- DOMAIN-SUFFIX,squarespace.com,节点选择 +- DOMAIN-SUFFIX,sstatic.net,节点选择 +- DOMAIN-SUFFIX,st.luluku.pw,节点选择 +- DOMAIN-SUFFIX,stackoverflow.com,节点选择 +- DOMAIN-SUFFIX,startpage.com,节点选择 +- DOMAIN-SUFFIX,staticflickr.com,节点选择 +- DOMAIN-SUFFIX,steamcommunity.com,节点选择 +- DOMAIN-SUFFIX,symauth.com,节点选择 +- DOMAIN-SUFFIX,symcb.com,节点选择 +- DOMAIN-SUFFIX,symcd.com,节点选择 +- DOMAIN-SUFFIX,tapbots.com,节点选择 +- DOMAIN-SUFFIX,tapbots.net,节点选择 +- DOMAIN-SUFFIX,tdesktop.com,节点选择 +- DOMAIN-SUFFIX,techcrunch.com,节点选择 +- DOMAIN-SUFFIX,techsmith.com,节点选择 +- DOMAIN-SUFFIX,thepiratebay.org,节点选择 +- DOMAIN-SUFFIX,theverge.com,节点选择 +- DOMAIN-SUFFIX,time.com,节点选择 +- DOMAIN-SUFFIX,timeinc.net,节点选择 +- DOMAIN-SUFFIX,tiny.cc,节点选择 +- DOMAIN-SUFFIX,tinypic.com,节点选择 +- DOMAIN-SUFFIX,tmblr.co,节点选择 +- DOMAIN-SUFFIX,todoist.com,节点选择 +- DOMAIN-SUFFIX,trello.com,节点选择 +- DOMAIN-SUFFIX,trustasiassl.com,节点选择 +- DOMAIN-SUFFIX,tumblr.co,节点选择 +- DOMAIN-SUFFIX,tumblr.com,节点选择 +- DOMAIN-SUFFIX,tweetdeck.com,节点选择 +- DOMAIN-SUFFIX,tweetmarker.net,节点选择 +- DOMAIN-SUFFIX,twitch.tv,节点选择 +- DOMAIN-SUFFIX,txmblr.com,节点选择 +- DOMAIN-SUFFIX,typekit.net,节点选择 +- DOMAIN-SUFFIX,ubertags.com,节点选择 +- DOMAIN-SUFFIX,ublock.org,节点选择 +- DOMAIN-SUFFIX,ubnt.com,节点选择 +- DOMAIN-SUFFIX,ulyssesapp.com,节点选择 +- DOMAIN-SUFFIX,urchin.com,节点选择 +- DOMAIN-SUFFIX,usertrust.com,节点选择 +- DOMAIN-SUFFIX,v.gd,节点选择 +- DOMAIN-SUFFIX,v2ex.com,节点选择 +- DOMAIN-SUFFIX,vimeo.com,节点选择 +- DOMAIN-SUFFIX,vimeocdn.com,节点选择 +- DOMAIN-SUFFIX,vine.co,节点选择 +- DOMAIN-SUFFIX,vivaldi.com,节点选择 +- DOMAIN-SUFFIX,vox-cdn.com,节点选择 +- DOMAIN-SUFFIX,vsco.co,节点选择 +- DOMAIN-SUFFIX,vultr.com,节点选择 +- DOMAIN-SUFFIX,w.org,节点选择 +- DOMAIN-SUFFIX,w3schools.com,节点选择 +- DOMAIN-SUFFIX,webtype.com,节点选择 +- DOMAIN-SUFFIX,wikiwand.com,节点选择 +- DOMAIN-SUFFIX,wikileaks.org,节点选择 +- DOMAIN-SUFFIX,wikimedia.org,节点选择 +- DOMAIN-SUFFIX,wikipedia.com,节点选择 +- DOMAIN-SUFFIX,wikipedia.org,节点选择 +- DOMAIN-SUFFIX,windows.com,节点选择 +- DOMAIN-SUFFIX,windows.net,节点选择 +- DOMAIN-SUFFIX,wire.com,节点选择 +- DOMAIN-SUFFIX,wordpress.com,节点选择 +- DOMAIN-SUFFIX,workflowy.com,节点选择 +- DOMAIN-SUFFIX,wp.com,节点选择 +- DOMAIN-SUFFIX,wsj.com,节点选择 +- DOMAIN-SUFFIX,wsj.net,节点选择 +- DOMAIN-SUFFIX,xda-developers.com,节点选择 +- DOMAIN-SUFFIX,xeeno.com,节点选择 +- DOMAIN-SUFFIX,xiti.com,节点选择 +- DOMAIN-SUFFIX,yahoo.com,节点选择 +- DOMAIN-SUFFIX,yimg.com,节点选择 +- DOMAIN-SUFFIX,ying.com,节点选择 +- DOMAIN-SUFFIX,yoyo.org,节点选择 +- DOMAIN-SUFFIX,ytimg.com,节点选择 +- DOMAIN-SUFFIX,telegra.ph,节点选择 +- DOMAIN-SUFFIX,telegram.org,节点选择 +- IP-CIDR,91.108.4.0/22,节点选择,no-resolve +- IP-CIDR,91.108.8.0/21,节点选择,no-resolve +- IP-CIDR,91.108.16.0/22,节点选择,no-resolve +- IP-CIDR,91.108.56.0/22,节点选择,no-resolve +- IP-CIDR,149.154.160.0/20,节点选择,no-resolve +- IP-CIDR6,2001:67c:4e8::/48,节点选择,no-resolve +- IP-CIDR6,2001:b28:f23d::/48,节点选择,no-resolve +- IP-CIDR6,2001:b28:f23f::/48,节点选择,no-resolve +- IP-CIDR,120.232.181.162/32,节点选择,no-resolve +- IP-CIDR,120.241.147.226/32,节点选择,no-resolve +- IP-CIDR,120.253.253.226/32,节点选择,no-resolve +- IP-CIDR,120.253.255.162/32,节点选择,no-resolve +- IP-CIDR,120.253.255.34/32,节点选择,no-resolve +- IP-CIDR,120.253.255.98/32,节点选择,no-resolve +- IP-CIDR,180.163.150.162/32,节点选择,no-resolve +- IP-CIDR,180.163.150.34/32,节点选择,no-resolve +- IP-CIDR,180.163.151.162/32,节点选择,no-resolve +- IP-CIDR,180.163.151.34/32,节点选择,no-resolve +- IP-CIDR,203.208.39.0/24,节点选择,no-resolve +- IP-CIDR,203.208.40.0/24,节点选择,no-resolve +- IP-CIDR,203.208.41.0/24,节点选择,no-resolve +- IP-CIDR,203.208.43.0/24,节点选择,no-resolve +- IP-CIDR,203.208.50.0/24,节点选择,no-resolve +- IP-CIDR,220.181.174.162/32,节点选择,no-resolve +- IP-CIDR,220.181.174.226/32,节点选择,no-resolve +- IP-CIDR,220.181.174.34/32,节点选择,no-resolve +- DOMAIN,injections.adguard.org,DIRECT +- DOMAIN,local.adguard.org,DIRECT +- DOMAIN-SUFFIX,local,DIRECT +- IP-CIDR,127.0.0.0/8,DIRECT +- IP-CIDR,172.16.0.0/12,DIRECT +- IP-CIDR,192.168.0.0/16,DIRECT +- IP-CIDR,10.0.0.0/8,DIRECT +- IP-CIDR,17.0.0.0/8,DIRECT +- IP-CIDR,100.64.0.0/10,DIRECT +- IP-CIDR,224.0.0.0/4,DIRECT +- IP-CIDR6,fe80::/10,DIRECT +- DOMAIN-SUFFIX,cn,DIRECT +- DOMAIN-KEYWORD,-cn,DIRECT +- GEOIP,CN,DIRECT +- MATCH,节点选择 +socks-port: 7891 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..51ea9d5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +requests==2.32.3 +httpx==0.27.2 +PyYAML==6.0.2 +requests-html==0.10.0 +lxml_html_clean==0.2.1 +pyppeteer==2.0.0