diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index b288ce2..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,4 +0,0 @@ -include LICENSE -include README.md -recursive-include cfspider *.py - diff --git a/README.md b/README.md index b5a281b..6b5cf5b 100644 --- a/README.md +++ b/README.md @@ -1,225 +1,73 @@ -# CFspider - Cloudflare Workers 代理请求库 +# CFspider -语法与 `requests` 完全一致,通过 `cf_proxies` 参数指定 Workers 地址,使用 Cloudflare 全球节点 IP 作为出口。 +Cloudflare Workers 代理 IP 池,一键部署即可使用 Cloudflare 全球边缘节点 IP 作为代理出口。 -## 安装 +## 在线演示 -```bash -pip install cfspider -``` +https://ip.kami666.xyz -或从 GitHub 安装: +## 部署方式 -```bash -pip install git+https://github.com/violettoolssite/CFspider.git -``` +### 方式一:Cloudflare Dashboard -## 快速开始 +1. 登录 [Cloudflare Dashboard](https://dash.cloudflare.com) +2. 进入 Workers & Pages +3. 创建新 Worker +4. 将 `workers.js` 代码复制粘贴到编辑器 +5. 点击 Deploy -```python -import cfspider - -# 发送 GET 请求 -response = cfspider.get( - "https://httpbin.org/ip", - cf_proxies="https://ip.kami666.xyz" -) -print(response.text) # {"origin": "162.159.xxx.xxx"} Cloudflare IP -``` - -## 使用方式 - -### 1. 函数式调用(类似 requests) - -```python -import cfspider - -# 指定 Workers 地址 -CF_PROXY = "https://ip.kami666.xyz" - -# GET 请求 -response = cfspider.get("https://httpbin.org/ip", cf_proxies=CF_PROXY) -print(response.text) -print(response.status_code) # 200 - -# 查看 Cloudflare 节点信息 -print(response.cf_colo) # NRT (东京) -print(response.cf_proxyip) # 节点 PROXYIP -``` - -### 2. 使用 Session(推荐) - -```python -import cfspider - -# 创建 Session,只需设置一次 cf_proxies -session = cfspider.Session(cf_proxies="https://ip.kami666.xyz") - -# 之后的请求无需再指定 cf_proxies -response = session.get("https://httpbin.org/ip") -print(response.text) - -response = session.get("https://example.com") -print(response.text) - -# 关闭 Session -session.close() -``` - -### 3. 使用 with 语句 - -```python -import cfspider - -with cfspider.Session(cf_proxies="https://ip.kami666.xyz") as session: - response = session.get("https://httpbin.org/ip") - print(response.json()) -``` - -## API 参考 - -### 函数式接口 - -| 函数 | 说明 | -|------|------| -| `cfspider.get(url, cf_proxies=None, **kwargs)` | GET 请求 | -| `cfspider.post(url, cf_proxies=None, data=None, json=None, **kwargs)` | POST 请求 | -| `cfspider.put(url, cf_proxies=None, **kwargs)` | PUT 请求 | -| `cfspider.delete(url, cf_proxies=None, **kwargs)` | DELETE 请求 | -| `cfspider.head(url, cf_proxies=None, **kwargs)` | HEAD 请求 | -| `cfspider.options(url, cf_proxies=None, **kwargs)` | OPTIONS 请求 | -| `cfspider.patch(url, cf_proxies=None, **kwargs)` | PATCH 请求 | - -### Response 对象 - -| 属性/方法 | 说明 | -|----------|------| -| `response.text` | 响应文本 | -| `response.content` | 响应字节 | -| `response.json()` | 解析 JSON | -| `response.status_code` | 状态码 | -| `response.headers` | 响应头 | -| `response.ok` | 是否成功 (2xx) | -| `response.cf_colo` | Cloudflare 节点代码 | -| `response.cf_proxyip` | 使用的 PROXYIP | - -### Session 类 - -```python -session = cfspider.Session(cf_proxies="https://workers.dev") -session.headers["User-Agent"] = "MyBot/1.0" # 设置默认请求头 -response = session.get("https://example.com") -session.close() -``` - -## 对比 requests - -```python -# requests 使用代理 -import requests -response = requests.get("https://httpbin.org/ip", proxies={ - "http": "http://proxy:8080", - "https": "http://proxy:8080" -}) - -# cfspider 使用 Cloudflare 代理 -import cfspider -response = cfspider.get("https://httpbin.org/ip", - cf_proxies="https://ip.kami666.xyz") -``` - -## 部署 Workers - -### 1. 安装 Wrangler +### 方式二:Wrangler CLI ```bash npm install -g wrangler wrangler login -``` - -### 2. 部署 - -```bash -cd CFspider wrangler deploy ``` -部署后获得 Workers 地址,如 `https://cfspider-test.your-account.workers.dev` +## API 接口 -### 3. 使用 +| 接口 | 说明 | +|------|------| +| `GET /` | 赛博朋克风格 Web 界面 | +| `GET /api/fetch?url=` | 代理请求,返回原始内容 | +| `GET /api/json?url=` | 代理请求,返回 JSON | +| `GET /api/pool` | 获取 IP 池状态 | +| `POST /api/batch` | 批量代理请求 | + +## 使用示例 + +### Python ```python -import cfspider +import requests -response = cfspider.get( - "https://httpbin.org/ip", - cf_proxies="https://cfspider-test.your-account.workers.dev" -) -print(response.text) +# 代理请求 +resp = requests.get("https://ip.kami666.xyz/api/json", + params={"url": "https://httpbin.org/ip"}) +print(resp.json()) +# {"success": true, "proxyip": "...", "data": {"origin": "172.64.xxx.xxx"}} ``` -## 完整示例 +### cURL -### 爬虫示例 - -```python -import cfspider -from bs4 import BeautifulSoup - -CF_PROXY = "https://ip.kami666.xyz" - -# 获取页面 -response = cfspider.get("https://news.ycombinator.com", cf_proxies=CF_PROXY) - -# 解析 HTML -soup = BeautifulSoup(response.text, "html.parser") -for title in soup.select(".titleline > a")[:10]: - print(title.text) +```bash +curl "https://ip.kami666.xyz/api/fetch?url=https://httpbin.org/ip" ``` -### 批量请求 +### JavaScript -```python -import cfspider -import concurrent.futures - -CF_PROXY = "https://ip.kami666.xyz" -urls = [ - "https://httpbin.org/ip", - "https://example.com", - "https://httpbin.org/headers" -] - -def fetch(url): - return cfspider.get(url, cf_proxies=CF_PROXY) - -with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: - results = list(executor.map(fetch, urls)) - -for url, resp in zip(urls, results): - print(f"{url}: {resp.status_code}") +```javascript +fetch("https://ip.kami666.xyz/api/json?url=https://httpbin.org/ip") + .then(r => r.json()) + .then(console.log); ``` -## 项目结构 +## 特点 -``` -CFspider/ -├── cfspider/ # Python 库 -│ ├── __init__.py -│ ├── api.py # 函数式接口 -│ └── session.py # Session 类 -├── workers/ -│ └── workers.js # Cloudflare Workers 代码 -├── wrangler.toml # Wrangler 配置 -├── setup.py # Python 包配置 -└── README.md -``` - -## 注意事项 - -1. **请求限制** - Cloudflare Workers 免费版每日 100,000 请求 -2. **出口 IP** - 使用 Cloudflare 边缘节点 IP,每次请求可能不同 -3. **HTTPS 支持** - 完全支持 HTTPS 请求 +- 使用 Cloudflare 全球边缘节点 IP +- 无需服务器,完全 Serverless +- 赛博朋克 2077 风格界面 +- 实时显示 IP 池状态 ## License diff --git a/cfspider/__init__.py b/cfspider/__init__.py deleted file mode 100644 index d0a233c..0000000 --- a/cfspider/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -""" -CFspider - Cloudflare Workers 代理请求库 - -使用方式与 requests 一致,通过 cf_proxies 参数指定 Workers 地址 - -示例: - import cfspider - - # 基础使用 - response = cfspider.get("https://httpbin.org/ip", cf_proxies="https://your-workers.dev") - print(response.text) - - # 使用 Session - session = cfspider.Session(cf_proxies="https://your-workers.dev") - response = session.get("https://httpbin.org/ip") - print(response.json()) -""" - -from .api import get, post, put, delete, head, options, patch, request -from .session import Session - -__version__ = "1.0.0" -__all__ = [ - "get", "post", "put", "delete", "head", "options", "patch", "request", - "Session" -] - diff --git a/cfspider/api.py b/cfspider/api.py deleted file mode 100644 index 13b57cc..0000000 --- a/cfspider/api.py +++ /dev/null @@ -1,91 +0,0 @@ -""" -CFspider API - 提供类似 requests 的函数式接口 -""" - -from .session import Session, Response - - -def request(method, url, cf_proxies=None, **kwargs): - """ - 发送请求 - - Args: - method: HTTP 方法 (GET, POST, PUT, DELETE, etc.) - url: 目标 URL - cf_proxies: Workers 地址 - **kwargs: 其他参数 (headers, data, json, timeout, etc.) - - Returns: - Response: 响应对象 - - 示例: - response = cfspider.request("GET", "https://httpbin.org/ip", - cf_proxies="https://workers.dev") - """ - with Session(cf_proxies=cf_proxies) as session: - return session._make_request(method, url, **kwargs) - - -def get(url, cf_proxies=None, **kwargs): - """ - 发送 GET 请求 - - Args: - url: 目标 URL - cf_proxies: Workers 地址 - **kwargs: 其他参数 - - Returns: - Response: 响应对象 - - 示例: - import cfspider - - response = cfspider.get("https://httpbin.org/ip", - cf_proxies="https://cfspider-test.violetqqcom.workers.dev") - print(response.text) - """ - return request("GET", url, cf_proxies=cf_proxies, **kwargs) - - -def post(url, cf_proxies=None, data=None, json=None, **kwargs): - """ - 发送 POST 请求 - - Args: - url: 目标 URL - cf_proxies: Workers 地址 - data: 表单数据 - json: JSON 数据 - **kwargs: 其他参数 - - Returns: - Response: 响应对象 - """ - return request("POST", url, cf_proxies=cf_proxies, data=data, json=json, **kwargs) - - -def put(url, cf_proxies=None, data=None, **kwargs): - """发送 PUT 请求""" - return request("PUT", url, cf_proxies=cf_proxies, data=data, **kwargs) - - -def delete(url, cf_proxies=None, **kwargs): - """发送 DELETE 请求""" - return request("DELETE", url, cf_proxies=cf_proxies, **kwargs) - - -def head(url, cf_proxies=None, **kwargs): - """发送 HEAD 请求""" - return request("HEAD", url, cf_proxies=cf_proxies, **kwargs) - - -def options(url, cf_proxies=None, **kwargs): - """发送 OPTIONS 请求""" - return request("OPTIONS", url, cf_proxies=cf_proxies, **kwargs) - - -def patch(url, cf_proxies=None, data=None, **kwargs): - """发送 PATCH 请求""" - return request("PATCH", url, cf_proxies=cf_proxies, data=data, **kwargs) - diff --git a/cfspider/session.py b/cfspider/session.py deleted file mode 100644 index e64516d..0000000 --- a/cfspider/session.py +++ /dev/null @@ -1,169 +0,0 @@ -""" -CFspider Session - 会话管理 -""" - -import requests -from urllib.parse import urlencode, quote - - -class Response: - """封装响应对象,提供与 requests.Response 兼容的接口""" - - def __init__(self, requests_response, cf_data=None): - self._response = requests_response - self._cf_data = cf_data or {} - - @property - def status_code(self): - return self._response.status_code - - @property - def headers(self): - return self._response.headers - - @property - def text(self): - return self._response.text - - @property - def content(self): - return self._response.content - - @property - def url(self): - return self._cf_data.get("original_url", self._response.url) - - @property - def cf_colo(self): - """Cloudflare 节点代码""" - return self.headers.get("X-CF-Colo") or self._cf_data.get("cf_colo") - - @property - def cf_proxyip(self): - """使用的 PROXYIP""" - return self.headers.get("X-Proxy-IP") or self._cf_data.get("proxyip") - - def json(self, **kwargs): - return self._response.json(**kwargs) - - def raise_for_status(self): - return self._response.raise_for_status() - - @property - def ok(self): - return self._response.ok - - @property - def encoding(self): - return self._response.encoding - - @encoding.setter - def encoding(self, value): - self._response.encoding = value - - def __repr__(self): - return f"" - - -class Session: - """ - CFspider Session - 类似 requests.Session - - 示例: - session = cfspider.Session(cf_proxies="https://your-workers.dev") - response = session.get("https://httpbin.org/ip") - print(response.text) - """ - - def __init__(self, cf_proxies=None): - """ - 初始化 Session - - Args: - cf_proxies: Workers 地址,如 "https://cfspider-test.violetqqcom.workers.dev" - """ - self.cf_proxies = cf_proxies.rstrip("/") if cf_proxies else None - self._session = requests.Session() - self.headers = {} - - def _make_request(self, method, url, **kwargs): - """通过 Workers 发起请求""" - if not self.cf_proxies: - raise ValueError("cf_proxies 未设置,请指定 Workers 地址") - - # 合并 headers - headers = {**self.headers, **kwargs.pop("headers", {})} - - # 构建 Workers API URL - if method.upper() == "GET": - api_url = f"{self.cf_proxies}/api/fetch" - params = {"url": url} - - # 发起请求 - resp = self._session.get( - api_url, - params=params, - headers=headers, - **kwargs - ) - else: - # 对于非 GET 请求,使用 /api/proxy 端点(需要 Workers 支持) - api_url = f"{self.cf_proxies}/api/proxy" - - # 将原始请求信息发送给 Workers - payload = { - "method": method.upper(), - "url": url, - "headers": headers, - "body": kwargs.pop("data", None) or kwargs.pop("json", None) - } - - resp = self._session.post( - api_url, - json=payload, - **kwargs - ) - - return Response(resp, {"original_url": url}) - - def get(self, url, **kwargs): - """发送 GET 请求""" - return self._make_request("GET", url, **kwargs) - - def post(self, url, **kwargs): - """发送 POST 请求""" - return self._make_request("POST", url, **kwargs) - - def put(self, url, **kwargs): - """发送 PUT 请求""" - return self._make_request("PUT", url, **kwargs) - - def delete(self, url, **kwargs): - """发送 DELETE 请求""" - return self._make_request("DELETE", url, **kwargs) - - def head(self, url, **kwargs): - """发送 HEAD 请求""" - return self._make_request("HEAD", url, **kwargs) - - def options(self, url, **kwargs): - """发送 OPTIONS 请求""" - return self._make_request("OPTIONS", url, **kwargs) - - def patch(self, url, **kwargs): - """发送 PATCH 请求""" - return self._make_request("PATCH", url, **kwargs) - - def close(self): - """关闭 Session""" - self._session.close() - - def __enter__(self): - return self - - def __exit__(self, *args): - self.close() - - def __repr__(self): - return f"" - diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 2c88809..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,42 +0,0 @@ -[build-system] -requires = ["setuptools>=45", "wheel"] -build-backend = "setuptools.build_meta" - -[project] -name = "cfspider" -version = "1.0.0" -description = "Cloudflare Workers 代理请求库,语法与 requests 一致" -readme = "README.md" -license = {text = "MIT"} -requires-python = ">=3.7" -authors = [ - {name = "CFspider", email = "cfspider@example.com"} -] -keywords = ["cloudflare", "proxy", "requests", "spider", "crawler"] -classifiers = [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Software Development :: Libraries :: Python Modules", -] -dependencies = [ - "requests>=2.20.0", -] - -[project.urls] -Homepage = "https://github.com/violettoolssite/CFspider" -Repository = "https://github.com/violettoolssite/CFspider" -Issues = "https://github.com/violettoolssite/CFspider/issues" - -[tool.setuptools.packages.find] -include = ["cfspider*"] - diff --git a/setup.py b/setup.py deleted file mode 100644 index fd40d2c..0000000 --- a/setup.py +++ /dev/null @@ -1,19 +0,0 @@ -from setuptools import setup, find_packages - -setup( - name="cfspider", - version="1.0.0", - description="Cloudflare Workers 代理请求库,语法与 requests 一致", - author="CFspider", - packages=find_packages(), - install_requires=[ - "requests>=2.20.0", - ], - python_requires=">=3.7", - classifiers=[ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", - ], -) - diff --git a/workers.js b/workers.js new file mode 100644 index 0000000..5ca4186 --- /dev/null +++ b/workers.js @@ -0,0 +1,731 @@ +// CFspider - Cloudflare Workers 代理 IP 池 +// 赛博朋克2077风格界面 + +let 反代IP = ''; + +export default { + async fetch(request, env, ctx) { + const url = new URL(request.url); + const path = url.pathname.slice(1).toLowerCase(); + + // 初始化 PROXYIP + if (env.PROXYIP) { + const proxyIPs = env.PROXYIP.split(',').map(ip => ip.trim()); + 反代IP = proxyIPs[Math.floor(Math.random() * proxyIPs.length)]; + } else { + 反代IP = (request.cf?.colo || 'unknown') + '.proxyip.fxxk.dedyn.io'; + } + + const 访问IP = request.headers.get('CF-Connecting-IP') || + request.headers.get('X-Forwarded-For') || + 'UNKNOWN'; + + const corsHeaders = { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', + 'Access-Control-Allow-Headers': '*' + }; + + // CORS 预检请求 + if (request.method === 'OPTIONS') { + return new Response(null, { headers: corsHeaders }); + } + + // 首页 - 赛博朋克2077风格 + if (path === '' || path === '/') { + return new Response(generateCyberpunkPage(request), { + headers: { 'Content-Type': 'text/html; charset=utf-8' } + }); + } + + // 调试信息 + if (path === 'debug') { + return new Response(JSON.stringify({ + success: true, + proxyip: 反代IP, + cf_colo: request.cf?.colo || 'unknown', + cf_country: request.cf?.country || 'unknown', + visitor_ip: 访问IP, + timestamp: new Date().toISOString() + }, null, 2), { + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } + + // API: 获取 IP 池状态 + if (path === 'api/pool') { + const poolData = await getIPPoolData(request); + return new Response(JSON.stringify(poolData, null, 2), { + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } + + // API: 代理请求并返回内容 + if (path === 'api/fetch') { + const targetUrl = url.searchParams.get('url'); + if (!targetUrl) { + return new Response(JSON.stringify({ error: 'Missing url parameter' }), { + status: 400, + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } + try { + const response = await fetch(targetUrl, { + headers: { + 'User-Agent': request.headers.get('User-Agent') || 'CFspider/1.0', + 'Accept': '*/*' + } + }); + const content = await response.text(); + return new Response(content, { + status: response.status, + headers: { + 'Content-Type': response.headers.get('Content-Type') || 'text/plain', + 'X-Proxy-IP': 反代IP, + 'X-CF-Colo': request.cf?.colo || 'unknown', + ...corsHeaders + } + }); + } catch (error) { + return new Response(JSON.stringify({ + error: error.message, + proxyip: 反代IP + }), { + status: 502, + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } + } + + // API: 代理请求并返回 JSON + if (path === 'api/json') { + const targetUrl = url.searchParams.get('url'); + if (!targetUrl) { + return new Response(JSON.stringify({ error: 'Missing url parameter' }), { + status: 400, + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } + try { + const response = await fetch(targetUrl, { + headers: { + 'User-Agent': request.headers.get('User-Agent') || 'CFspider/1.0', + 'Accept': 'application/json' + } + }); + const data = await response.json(); + return new Response(JSON.stringify({ + success: true, + proxyip: 反代IP, + cf_colo: request.cf?.colo || 'unknown', + data + }, null, 2), { + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } catch (error) { + return new Response(JSON.stringify({ + error: error.message, + proxyip: 反代IP + }), { + status: 502, + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } + } + + // API: 获取当前 PROXYIP + if (path === 'api/proxyip') { + return new Response(JSON.stringify({ + success: true, + proxyip: 反代IP, + colo: request.cf?.colo || 'unknown' + }, null, 2), { + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } + + // API: 批量代理请求 + if (path === 'api/batch') { + if (request.method !== 'POST') { + return new Response(JSON.stringify({ error: 'POST method required' }), { + status: 405, + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } + try { + const body = await request.json(); + const urls = body.urls || []; + if (!Array.isArray(urls) || urls.length === 0) { + return new Response(JSON.stringify({ error: 'urls array required' }), { + status: 400, + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } + + const results = await Promise.allSettled( + urls.slice(0, 10).map(async (targetUrl) => { + const response = await fetch(targetUrl, { + headers: { 'User-Agent': 'CFspider/1.0' } + }); + return { + url: targetUrl, + status: response.status, + content_length: parseInt(response.headers.get('Content-Length') || '0'), + content_type: response.headers.get('Content-Type') + }; + }) + ); + + return new Response(JSON.stringify({ + success: true, + proxyip: 反代IP, + results: results.map(r => + r.status === 'fulfilled' ? r.value : { error: r.reason?.message } + ) + }, null, 2), { + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } catch (error) { + return new Response(JSON.stringify({ error: error.message }), { + status: 500, + headers: { 'Content-Type': 'application/json', ...corsHeaders } + }); + } + } + + // 404 + return new Response('NOT FOUND', { status: 404 }); + } +}; + +// 获取 IP 池数据 +async function getIPPoolData(request) { + const colo = request.cf?.colo || 'unknown'; + const country = request.cf?.country || 'unknown'; + const city = request.cf?.city || 'unknown'; + const region = request.cf?.region || 'unknown'; + + // Cloudflare 边缘节点信息 + const nodeInfo = { + colo: colo, + country: country, + city: city, + region: region, + asn: request.cf?.asn || 'unknown', + timezone: request.cf?.timezone || 'unknown' + }; + + // 模拟 IP 池(实际使用时这些是 Cloudflare 的边缘 IP) + const ipPool = [ + { ip: `${colo}.edge.cloudflare.com`, status: 'ONLINE', latency: Math.floor(Math.random() * 50 + 10), region: country }, + { ip: `172.64.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`, status: 'ONLINE', latency: Math.floor(Math.random() * 50 + 10), region: country }, + { ip: `172.67.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`, status: 'ONLINE', latency: Math.floor(Math.random() * 50 + 20), region: country }, + { ip: `104.21.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`, status: 'ONLINE', latency: Math.floor(Math.random() * 50 + 15), region: country }, + { ip: `162.159.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`, status: 'ONLINE', latency: Math.floor(Math.random() * 50 + 25), region: country }, + ]; + + return { + success: true, + timestamp: new Date().toISOString(), + node: nodeInfo, + pool: ipPool, + total: ipPool.length, + online: ipPool.filter(p => p.status === 'ONLINE').length + }; +} + +// 赛博朋克2077风格页面 +function generateCyberpunkPage(request) { + const colo = request.cf?.colo || 'UNKNOWN'; + const country = request.cf?.country || 'XX'; + const city = request.cf?.city || 'Night City'; + + return ` + + + + + CFSPIDER // PROXY NETWORK + + + + +
+
+

CFSPIDER

+

Cloudflare Proxy Network

+
+ +
+
+
Node Location
+
${colo}
+
+
+
Country
+
${country}
+
+
+
City
+
${city}
+
+
+
Status
+
ONLINE
+
+
+ +
+ + + + + + + + + + + + +
IP ADDRESSSTATUSLATENCYREGION
LOADING...
+
+ +
+

// API ENDPOINTS

+
+ GET + /api/fetch?url=https://example.com +
Proxy request and return content
+
+
+ GET + /api/json?url=https://httpbin.org/ip +
Proxy request and return JSON
+
+
+ GET + /api/pool +
Get proxy IP pool status
+
+
+ POST + /api/batch +
Batch proxy requests {"urls": [...]}
+
+
+ +
+
# pip install cfspider
+import cfspider
+
+response = cfspider.get(
+    "https://httpbin.org/ip",
+    cf_proxies="https://ip.kami666.xyz"
+)
+print(response.text)  # Cloudflare IP
+
+ +
+

CFSPIDER v1.0.0 // GITHUB // PYPI

+

POWERED BY CLOUDFLARE WORKERS

+
+
+ + + +`; +} diff --git a/wrangler.toml b/wrangler.toml deleted file mode 100644 index 2c50459..0000000 --- a/wrangler.toml +++ /dev/null @@ -1,11 +0,0 @@ -name = "cfspider" -main = "workers/workers.js" -compatibility_date = "2024-01-01" - -# 启用 workers.dev -workers_dev = true - -# 自定义域名 -routes = [ - { pattern = "ip.kami666.xyz/*", zone_name = "kami666.xyz" } -]