{"id":237,"date":"2025-02-28T10:42:30","date_gmt":"2025-02-28T02:42:30","guid":{"rendered":"https:\/\/feiyangblog.eu.org\/?p=237"},"modified":"2025-11-17T12:26:05","modified_gmt":"2025-11-17T04:26:05","slug":"cloudflare-ip%e4%bc%98%e9%80%89-%e5%b9%b6%e8%87%aa%e5%8a%a8%e8%a7%a3%e6%9e%90%e5%88%b0cloudflare%ef%bc%88python%e5%ae%9e%e7%8e%b0%ef%bc%89","status":"publish","type":"post","link":"https:\/\/feiyangblog.eu.org\/?p=237","title":{"rendered":"cloudflare IP\u4f18\u9009 \u5e76\u81ea\u52a8\u89e3\u6790\u5230cloudflare\uff08Python\u5b9e\u73b0\uff09"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>import requests\nimport json\nfrom datetime import datetime, timedelta, timezone\n\n# Cloudflare API \u53c2\u6570\napi_token = \"api_token\"\nzone_id = \"zone_id\"\ndomain = \"domain\"\n\n# Telegram Bot \u53c2\u6570\ntg_bot_token = \"tg_bot_token\"\ntg_chat_id = \"tg_chat_id\"\n\n# Cloudflare API \u7aef\u70b9\napi_url = f\"https:\/\/api.cloudflare.com\/client\/v4\/zones\/{zone_id}\/dns_records\"\n\n# \u8bf7\u6c42\u5934\nheaders = {\n    \"Authorization\": f\"Bearer {api_token}\",\n    \"Content-Type\": \"application\/json\"\n}\n\n# \u83b7\u53d6 Cloudflare IP \u7684\u63a5\u53e3\ndef get_cloudflare_ips():\n    try:\n        response = requests.post(\"https:\/\/www.wetest.vip\/api\/cf2dns\/get_cloudflare_ip\", json={\n            \"key\": \"o1zrmHAF\",\n            \"type\": \"v4\"\n        }, timeout=30)\n        if response.status_code == 200:\n            data = response.json()\n            if data.get(\"status\") and \"info\" in data:\n                return data&#91;\"info\"]\n        return None\n    except requests.exceptions.RequestException as e:\n        print(f\"\u83b7\u53d6 Cloudflare IP \u65f6\u53d1\u751f\u9519\u8bef: {e}\")\n        return None\n\n# \u6dfb\u52a0 DNS \u8bb0\u5f55\ndef add_dns_record(ip):\n    data = {\n        \"type\": \"A\",\n        \"name\": domain,\n        \"content\": ip,\n        \"ttl\": 1,\n        \"proxied\": False\n    }\n    try:\n        response = requests.post(api_url, headers=headers, json=data, timeout=30)\n        return response.json()\n    except requests.exceptions.RequestException as e:\n        print(f\"\u6dfb\u52a0 DNS \u8bb0\u5f55\u65f6\u53d1\u751f\u9519\u8bef: {e}\")\n        return {\"success\": False, \"errors\": &#91;str(e)]}\n\n# \u5220\u9664 DNS \u8bb0\u5f55\ndef delete_dns_record(record_id):\n    try:\n        response = requests.delete(f\"{api_url}\/{record_id}\", headers=headers, timeout=30)\n        return response.json()\n    except requests.exceptions.RequestException as e:\n        print(f\"\u5220\u9664 DNS \u8bb0\u5f55\u65f6\u53d1\u751f\u9519\u8bef: {e}\")\n        return {\"success\": False, \"errors\": &#91;str(e)]}\n\n# \u83b7\u53d6\u73b0\u6709 DNS \u8bb0\u5f55\ndef get_existing_dns_records():\n    try:\n        response = requests.get(api_url, headers=headers, timeout=30)\n        return response.json()\n    except requests.exceptions.RequestException as e:\n        print(f\"\u83b7\u53d6 DNS \u8bb0\u5f55\u65f6\u53d1\u751f\u9519\u8bef: {e}\")\n        return {\"success\": False, \"errors\": &#91;str(e)]}\n\n# \u683c\u5f0f\u5316\u65f6\u95f4\u6233\u4e3a\u5317\u4eac\u65f6\u95f4 (UTC+8)\ndef format_timestamp(timestamp):\n    \"\"\"\u5c06\u65f6\u95f4\u6233\u683c\u5f0f\u5316\u4e3a\u5317\u4eac\u65f6\u95f4\"\"\"\n    # \u521b\u5efa UTC \u65f6\u533a\u7684\u65f6\u95f4\u5bf9\u8c61\n    utc_time = datetime.fromtimestamp(timestamp, timezone.utc)\n    # \u8f6c\u6362\u4e3a UTC+8 \u65f6\u533a\uff08\u5317\u4eac\u65f6\u95f4\uff09\n    beijing_timezone = timezone(timedelta(hours=8))\n    beijing_time = utc_time.astimezone(beijing_timezone)\n    return beijing_time.strftime('%Y-%m-%d %H:%M:%S')\n\n# \u683c\u5f0f\u5316\u8f93\u51fa IP \u4fe1\u606f\ndef format_ip_info(ip_info):\n    results = &#91;]\n    for line_code, ips in ip_info.items():\n        for ip_entry in ips:\n            ip = ip_entry&#91;'ip']\n            bandwidth = f\"{ip_entry&#91;'bandwidth']} MB\"\n            speed = f\"{ip_entry&#91;'speed']} kB\/s\"\n            delay = f\"{ip_entry&#91;'delay']} \u6beb\u79d2\"\n            colo = ip_entry&#91;'colo']\n            uptime = format_timestamp(ip_entry&#91;'uptime'])\n            line_name = ip_entry&#91;'line_name']\n            result = f\"{line_name}\\t{ip}\\t{bandwidth}\\t{speed}\\t{delay}\\t{colo}\\t{uptime}\"\n            results.append(result)\n    return results\n\n# \u53d1\u9001\u6d88\u606f\u5230 Telegram\ndef send_to_telegram(message):\n    try:\n        url = f\"https:\/\/api.telegram.org\/bot{tg_bot_token}\/sendMessage\"\n        data = {\n            \"chat_id\": tg_chat_id,\n            \"text\": message,\n            \"parse_mode\": \"Markdown\"\n        }\n        response = requests.post(url, json=data, timeout=30)\n        return response.json()\n    except requests.exceptions.RequestException as e:\n        print(f\"\u53d1\u9001 Telegram \u6d88\u606f\u65f6\u53d1\u751f\u9519\u8bef: {e}\")\n        return {\"ok\": False, \"description\": str(e)}\n\n# \u6e05\u7406\u65e7\u7684 DNS \u8bb0\u5f55\ndef cleanup_old_records():\n    \"\"\"\u5220\u9664\u6307\u5b9a\u57df\u540d\u7684\u6240\u6709 A \u8bb0\u5f55\"\"\"\n    existing_records = get_existing_dns_records()\n    deleted_count = 0\n    \n    if existing_records.get('success'):\n        for record in existing_records&#91;'result']:\n            if record&#91;'name'] == domain and record&#91;'type'] == 'A':\n                print(f\"\u5220\u9664\u65e7\u7684 DNS \u8bb0\u5f55: {record&#91;'content']} (ID: {record&#91;'id']})\")\n                delete_response = delete_dns_record(record&#91;'id'])\n                if delete_response.get('success'):\n                    deleted_count += 1\n                else:\n                    print(f\"\u5220\u9664\u8bb0\u5f55\u5931\u8d25: {delete_response.get('errors', '\u672a\u77e5\u9519\u8bef')}\")\n    \n    return deleted_count\n\n# \u4e3b\u7a0b\u5e8f\ndef main():\n    print(\"\u5f00\u59cb\u6267\u884c Cloudflare IP \u4f18\u9009\u811a\u672c...\")\n    \n    # \u6e05\u7406\u65e7\u7684 DNS \u8bb0\u5f55\n    print(\"\u6e05\u7406\u65e7\u7684 DNS \u8bb0\u5f55...\")\n    deleted_count = cleanup_old_records()\n    print(f\"\u5df2\u5220\u9664 {deleted_count} \u6761\u65e7\u7684 DNS \u8bb0\u5f55\")\n    \n    # \u83b7\u53d6\u65b0\u7684 Cloudflare IP\n    print(\"\u83b7\u53d6\u65b0\u7684 Cloudflare IP \u5730\u5740...\")\n    cloudflare_data = get_cloudflare_ips()\n    \n    if not cloudflare_data:\n        print(\"\u83b7\u53d6 Cloudflare IP \u5931\u8d25\")\n        send_to_telegram(\"\u274c \u83b7\u53d6 Cloudflare IP \u5931\u8d25\uff0c\u8bf7\u68c0\u67e5 API \u63a5\u53e3\u72b6\u6001\")\n        return\n    \n    # \u6253\u5370 cloudflare_data \u6765\u8c03\u8bd5\n    print(\"Cloudflare \u6570\u636e:\", json.dumps(cloudflare_data, indent=4, ensure_ascii=False))\n    \n    # \u68c0\u67e5\u8fd4\u56de\u7684\u6570\u636e\u662f\u5426\u5305\u542b IP \u4fe1\u606f\n    if any(key in cloudflare_data for key in &#91;'CM', 'CU', 'CT']):\n        ip_info = cloudflare_data\n        added_count = 0\n        \n        # \u6dfb\u52a0\u6807\u9898\u548c\u683c\u5f0f\u5316 IP \u4fe1\u606f\n        title = \"\u2705 Cloudflare IP \u4f18\u9009\u7ed3\u679c\\n\"\n        header = \"\u7ebf\u8def\\tIP\u5730\u5740\\t\u5e26\u5bbd\\t\u901f\u5ea6\\t\u5ef6\u8fdf\\t\u6570\u636e\u4e2d\u5fc3\\t\u66f4\u65b0\u65f6\u95f4\\n\"\n        formatted_info = format_ip_info(ip_info)\n        message = title + header + \"\\n\".join(formatted_info)\n        # \u904d\u5386\u6bcf\u4e2a\u8fd0\u8425\u5546\u7684 IP \u5730\u5740\u5e76\u6dfb\u52a0\u5230 DNS \u8bb0\u5f55\n        print(\"\u6dfb\u52a0\u65b0\u7684 DNS \u8bb0\u5f55...\")\n        for line in ip_info.keys():\n            for ip_entry in ip_info&#91;line]:\n                ip = ip_entry&#91;'ip']\n                print(f\"\u6dfb\u52a0 IP: {ip}\")\n                add_response = add_dns_record(ip)\n                if add_response.get('success'):\n                    added_count += 1\n                    print(f\"\u6210\u529f\u6dfb\u52a0 IP: {ip}\")\n                else:\n                    print(f\"\u6dfb\u52a0 IP \u5931\u8d25: {add_response.get('errors', '\u672a\u77e5\u9519\u8bef')}\")\n        \n        # \u53d1\u9001\u6d88\u606f\n        print(\"\u53d1\u9001\u6d88\u606f\u5230 Telegram...\")\n        summary = f\"\\n\ud83d\udcca \u64cd\u4f5c\u8bb0\u5f55:\\n\u5220\u9664\u65e7\u8bb0\u5f55: {deleted_count} \u6761\\n\u6dfb\u52a0\u65b0\u8bb0\u5f55: {added_count} \u6761\"\n        send_response = send_to_telegram(message + \"\\n\" + summary)\n        if send_response.get('ok'):\n            print(\"Telegram \u6d88\u606f\u53d1\u9001\u6210\u529f\")\n        else:\n            print(f\"Telegram \u6d88\u606f\u53d1\u9001\u5931\u8d25: {send_response.get('description', '\u672a\u77e5\u9519\u8bef')}\")\n        print(f\"\u811a\u672c\u6267\u884c\u5b8c\u6210\u3002\u5220\u9664 {deleted_count} \u6761\u8bb0\u5f55\uff0c\u6dfb\u52a0 {added_count} \u6761\u8bb0\u5f55\u3002\")\n        \n    else:\n        error_msg = \"\u274c \u83b7\u53d6 Cloudflare IP \u5931\u8d25\u6216\u8fd4\u56de\u683c\u5f0f\u4e0d\u7b26\u5408\u9884\u671f\"\n        print(error_msg)\n        send_to_telegram(error_msg)\n\nif __name__ == \"__main__\":\n    main()<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_total_topic_count_hidden":0,"_bbp_total_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"wpai_generated_summary":"","wpai_meta_description":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-237","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"views":628,"_links":{"self":[{"href":"https:\/\/feiyangblog.eu.org\/index.php?rest_route=\/wp\/v2\/posts\/237","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/feiyangblog.eu.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/feiyangblog.eu.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/feiyangblog.eu.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/feiyangblog.eu.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=237"}],"version-history":[{"count":3,"href":"https:\/\/feiyangblog.eu.org\/index.php?rest_route=\/wp\/v2\/posts\/237\/revisions"}],"predecessor-version":[{"id":338,"href":"https:\/\/feiyangblog.eu.org\/index.php?rest_route=\/wp\/v2\/posts\/237\/revisions\/338"}],"wp:attachment":[{"href":"https:\/\/feiyangblog.eu.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=237"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/feiyangblog.eu.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=237"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/feiyangblog.eu.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=237"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}