├── ip.txt ├── .github └── workflows │ ├── main.yml │ └── caijiip.yml ├── collect_ips.py ├── README.md └── bestdomain.py /ip.txt: -------------------------------------------------------------------------------- 1 | 1.2.1.1 2 | 1.0.1.1 3 | 1.0.1.1 4 | 1.2.1.1 5 | 1.2.1.1 6 | 1.0.1.1 7 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Update Cloudflare DNS 2 | 3 | on: 4 | schedule: 5 | - cron: '*/30 * * * *' # 每隔三十分钟运行一次 6 | workflow_dispatch: # 手动触发 7 | # push: # 允许提交触发 8 | 9 | jobs: 10 | update-dns: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v4 16 | 17 | - name: Set up Python 18 | uses: actions/setup-python@v4 19 | with: 20 | python-version: '3.x' # 你可以指定需要的 Python 版本 21 | 22 | - name: Install dependencies 23 | run: | 24 | python -m pip install --upgrade pip 25 | pip install requests 26 | 27 | - name: Run update script 28 | env: 29 | CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }} 30 | run: | 31 | python bestdomain.py 32 | -------------------------------------------------------------------------------- /.github/workflows/caijiip.yml: -------------------------------------------------------------------------------- 1 | name: Update IP List 2 | 3 | on: 4 | schedule: 5 | - cron: '*/30 * * * *' # 每隔三十分钟运行一次 6 | workflow_dispatch: # 手动触发 7 | # push: # 允许提交触发 8 | 9 | jobs: 10 | 11 | update-ip-list: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | 17 | - name: Set up Python 18 | uses: actions/setup-python@v4 19 | with: 20 | python-version: '3.9' 21 | 22 | - name: Install dependencies 23 | run: | 24 | python -m pip install --upgrade pip 25 | pip install requests 26 | pip install beautifulsoup4 27 | 28 | - name: Run script 29 | run: python ${{ github.workspace }}/collect_ips.py 30 | 31 | - name: Commit and push changes 32 | run: | 33 | git config --global user.email "baolw50@gmail.com" 34 | git config --global user.name "jc-lw" 35 | if [ -n "$(git status --porcelain)" ]; then 36 | git add ip.txt 37 | git commit -m "Automatic update" 38 | git push 39 | else 40 | echo "No changes detected, skipping commit." 41 | fi 42 | -------------------------------------------------------------------------------- /collect_ips.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from bs4 import BeautifulSoup 3 | import re 4 | import os 5 | 6 | # 目标URL列表 7 | urls = [ 8 | 'https://ip.164746.xyz/ipTop10.html', 9 | 'https://cf.090227.xyz', 10 | 'https://api.uouin.com/cloudflare.html', 11 | 'https://www.wetest.vip/page/cloudflare/address_v4.html', 12 | 'https://stock.hostmonit.com/CloudFlareYes' 13 | ] 14 | 15 | # 正则表达式用于匹配IP地址 16 | ip_pattern = r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' 17 | 18 | # 检查ip.txt文件是否存在,如果存在则删除它 19 | if os.path.exists('ip.txt'): 20 | os.remove('ip.txt') 21 | 22 | # 创建一个文件来存储IP地址 23 | with open('ip.txt', 'w') as file: 24 | for url in urls: 25 | try: 26 | # 发送HTTP请求获取网页内容 27 | response = requests.get(url, timeout=10) 28 | response.encoding = 'utf-8' 29 | 30 | # 使用BeautifulSoup解析HTML 31 | soup = BeautifulSoup(response.text, 'html.parser') 32 | 33 | # 根据网站的不同结构找到包含IP地址的元素 34 | if url in ['https://ip.164746.xyz/ipTop10.html', 'https://cf.090227.xyz']: 35 | elements = soup.find_all('tr') 36 | elif url == 'https://api.uouin.com/cloudflare.html': 37 | elements = soup.find_all('div', class_='ip') 38 | elif url == 'https://www.wetest.vip/page/cloudflare/address_v4.html': 39 | elements = soup.find_all('p') 40 | elif url == 'https://stock.hostmonit.com/CloudFlareYes': 41 | # 这是一个纯文本页面,不用解析 HTML 42 | ip_matches = re.findall(ip_pattern, response.text) 43 | for ip in ip_matches: 44 | file.write(ip + '\n') 45 | continue 46 | else: 47 | elements = soup.find_all('li') 48 | 49 | # 遍历所有元素,查找IP地址 50 | for element in elements: 51 | element_text = element.get_text() 52 | ip_matches = re.findall(ip_pattern, element_text) 53 | 54 | # 如果找到IP地址,则写入文件 55 | for ip in ip_matches: 56 | file.write(ip + '\n') 57 | 58 | except Exception as e: 59 | print(f"处理 {url} 时出错:{e}") 60 | 61 | print('IP地址已保存到 ip.txt 文件中。') 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # github项目 2 | - 原github作者[ tianshipapa ](https://github.com/tianshipapa)和 3 | [ymyuuu ](https://github.com/ymyuuu/BestDomain) 4 | - 老王只是合并两个项目 5 | - github项目地址 6 | ## 优选域名 , IP 取决于抓取的 网站 7 | - bestcf.cfcs.us.kg 8 | - api.cfcs.us.kg 9 | 10 | ![image.png](https://img.lwxpz.me/file/1736315762020_image.png) 11 | 12 | https://github.com/jc-lw/youxuanyuming 13 | 14 | ![image.png](https://img.kjzl.me/images/18b0be4bca205491b1aaf70983319fe504bef426.png) 15 | 16 | 17 | 18 | 19 | # cfipcaiji 原理和需要修改的地方 20 | 21 | - 每3小时自动抓取 https://ip.164746.xyz 的优选ip,形成ip.txt 22 | - 还有js自动生成的https://cf.090227.xyz 23 | ![image.png](https://img.kjzl.me/images/51e6dd9bbb99f98d3241509b804d98a4fc1fa5db.png) 24 | 25 | - `caijiip.yml `文件夹里面改成你自己的,否则报错 26 | ![image.png](https://img.kjzl.me/images/0ddaaecae1242f12aadaa847662d56a23398cda5.png) 27 | - `collect_ips.py`文件 这里是抓取优选IP的网站,如需要可自行修改 28 | ![image.png](https://img.kjzl.me/images/38a3d57288da468b17964664e54da54a4175ba0e.png) 29 | 30 | # BestDomain 需要Cloudflare API令牌 31 | 32 | - 这里修改你的二级域名开头 33 | ![image.png](https://img.kjzl.me/images/85362a2f5680355d4d73a2293ce82099c42e3308.png) 34 | ![image.png](https://img.kjzl.me/images/5def5f757d7a63978358e5a950714bed3dc6c213.png) 35 | - 把上面的链接 修改成 你自己的链接,因为你抓取优选ip可能跟我不一样。 36 | ![image.png](https://img.kjzl.me/images/52f07d0b88279fb13694e1071d3184082408cf3d.png) 37 | 38 | 39 | 40 | 1. 创建 Cloudflare API 令牌 41 | 访问 [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens) 42 | 43 | 2. 选择需要解析的域名,创建编辑 DNS 权限的` CF_API_TOKEN` 44 | ![image.png](https://img.kjzl.me/images/35feefcde1ed0cc08e430e419de73b892157d35c.png) 45 | 46 | 47 | 3. 在你的 GitHub 仓库中,设置 `CF_API_TOKEN `为你的 Cloudflare API 令牌 48 | ![image.png](https://img.kjzl.me/images/004eb6d2c8441cfa266129b3906e43e60bf99090.png) 49 | 50 | 51 | 4. 配置 GitHub Actions 定时任务 52 | - 编辑 [.github/workflows/main.yml](.github/workflows/main.yml) 文件,设置 `cron` 表达式以定义任务运行时间 53 | "# youxuanyuming" 54 | 55 | # 设置完成 56 | ![image.png](https://img.kjzl.me/images/defa31617244ae82e89f05480be397eb3938f15e.png) 57 | 这里就是 运行完成,去ping出来的优选IP 58 | ![image.png](https://img.kjzl.me/images/8816d5204054629815ecf6add95e9e244849e85b.png) 59 | 60 | 61 | # 开源协议 62 | 欢迎使用、修改和传播这个脚本!如果你觉得它对你有帮助,记得来点个 Star ⭐ 哦~ 63 | 64 | - 💡 免责声明: 本脚本由作者热爱 Linux 的灵魂驱动编写,虽尽力确保安全,但任何使用问题请自负风险! 65 | 66 | 赞助声明 67 | 本项目由 的「开源项目免费 VPS 计划」提供算力支持。 68 | 感谢 对开源社区的支持! 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /bestdomain.py: -------------------------------------------------------------------------------- 1 | import os 2 | import requests 3 | 4 | def get_ip_list(url): 5 | response = requests.get(url) 6 | response.raise_for_status() 7 | return response.text.strip().split('\n') 8 | 9 | def get_cloudflare_zone(api_token): 10 | headers = { 11 | 'Authorization': f'Bearer {api_token}', 12 | 'Content-Type': 'application/json', 13 | } 14 | response = requests.get('https://api.cloudflare.com/client/v4/zones', headers=headers) 15 | response.raise_for_status() 16 | zones = response.json().get('result', []) 17 | if not zones: 18 | raise Exception("No zones found") 19 | return zones[0]['id'], zones[0]['name'] 20 | 21 | def delete_existing_dns_records(api_token, zone_id, subdomain, domain): 22 | headers = { 23 | 'Authorization': f'Bearer {api_token}', 24 | 'Content-Type': 'application/json', 25 | } 26 | record_name = domain if subdomain == '@' else f'{subdomain}.{domain}' 27 | while True: 28 | response = requests.get(f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records?type=A&name={record_name}', headers=headers) 29 | response.raise_for_status() 30 | records = response.json().get('result', []) 31 | if not records: 32 | break 33 | for record in records: 34 | delete_response = requests.delete(f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{record["id"]}', headers=headers) 35 | delete_response.raise_for_status() 36 | print(f"Del {subdomain}:{record['id']}") 37 | 38 | def update_cloudflare_dns(ip_list, api_token, zone_id, subdomain, domain): 39 | headers = { 40 | 'Authorization': f'Bearer {api_token}', 41 | 'Content-Type': 'application/json', 42 | } 43 | record_name = domain if subdomain == '@' else f'{subdomain}.{domain}' 44 | for ip in ip_list: 45 | data = { 46 | "type": "A", 47 | "name": record_name, 48 | "content": ip, 49 | "ttl": 1, 50 | "proxied": False 51 | } 52 | response = requests.post(f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records', json=data, headers=headers) 53 | if response.status_code == 200: 54 | print(f"Add {subdomain}:{ip}") 55 | else: 56 | print(f"Failed to add A record for IP {ip} to subdomain {subdomain}: {response.status_code} {response.text}") 57 | 58 | if __name__ == "__main__": 59 | api_token = os.getenv('CF_API_TOKEN') 60 | 61 | # 示例URL和子域名对应的IP列表 62 | subdomain_ip_mapping = { 63 | 'bestcf': 'https://ipdb.030101.xyz/api/bestcf.txt', # #域名一,bestcf.域名.com 64 | 'api': 'https://raw.githubusercontent.com/jc-lw/youxuanyuming/refs/heads/main/ip.txt', #域名二,api.域名.com 65 | # 添加更多子域名和对应的IP列表URL 66 | } 67 | 68 | try: 69 | # 获取Cloudflare域区ID和域名 70 | zone_id, domain = get_cloudflare_zone(api_token) 71 | 72 | for subdomain, url in subdomain_ip_mapping.items(): 73 | # 获取IP列表 74 | ip_list = get_ip_list(url) 75 | # 删除现有的DNS记录 76 | delete_existing_dns_records(api_token, zone_id, subdomain, domain) 77 | # 更新Cloudflare DNS记录 78 | update_cloudflare_dns(ip_list, api_token, zone_id, subdomain, domain) 79 | 80 | except Exception as e: 81 | print(f"Error: {e}") 82 | --------------------------------------------------------------------------------