| # API 文檔 |
|
|
| ## 基礎信息 |
|
|
| - **基礎 URL**: `http://localhost:7860` (本地) 或 `https://huggingface.co/spaces/YOUR_USERNAME/turnstile-solver` (HuggingFace) |
| - **內容類型**: `application/json` |
| - **認證**: 無(可選配置) |
|
|
| ## 端點列表 |
|
|
| ### 1. 健康檢查 |
|
|
| 檢查服務是否正常運行。 |
|
|
| **請求:** |
| ```http |
| GET /health |
| ``` |
|
|
| **響應 (200 OK):** |
| ```json |
| { |
| "status": "healthy", |
| "service": "Turnstile Solver" |
| } |
| ``` |
|
|
| **示例:** |
| ```bash |
| curl http://localhost:7860/health |
| ``` |
|
|
| --- |
|
|
| ### 2. 本地求解 |
|
|
| 使用 Playwright 本地求解 Turnstile 驗證碼。 |
|
|
| **請求:** |
| ```http |
| POST /solve |
| Content-Type: application/json |
| |
| { |
| "url": "https://example.com", |
| "sitekey": "0x4AAAAAAAxxxxxx", |
| "timeout": 30000 |
| } |
| ``` |
|
|
| **參數:** |
|
|
| | 參數 | 類型 | 必需 | 說明 | |
| |------|------|------|------| |
| | `url` | string | ✓ | 包含 Turnstile 驗證碼的網頁 URL | |
| | `sitekey` | string | ✓ | Turnstile sitekey | |
| | `timeout` | integer | ✗ | 超時時間(毫秒),默認 30000 | |
|
|
| **響應 (200 OK):** |
| ```json |
| { |
| "token": "0.xxxxxxxxxxxxx", |
| "success": true, |
| "message": "Turnstile 求解成功" |
| } |
| ``` |
|
|
| **錯誤響應 (400/500):** |
| ```json |
| { |
| "detail": "無法獲取 Turnstile token" |
| } |
| ``` |
|
|
| **示例:** |
| ```bash |
| curl -X POST http://localhost:7860/solve \ |
| -H "Content-Type: application/json" \ |
| -d '{ |
| "url": "https://example.com", |
| "sitekey": "0x4AAAAAAAxxxxxx", |
| "timeout": 30000 |
| }' |
| ``` |
|
|
| **Python 示例:** |
| ```python |
| import requests |
| |
| response = requests.post( |
| "http://localhost:7860/solve", |
| json={ |
| "url": "https://example.com", |
| "sitekey": "0x4AAAAAAAxxxxxx", |
| "timeout": 30000 |
| } |
| ) |
| |
| data = response.json() |
| print(f"Token: {data['token']}") |
| ``` |
|
|
| --- |
|
|
| ### 3. 第三方服務求解 |
|
|
| 使用第三方服務(2captcha、Anti-Captcha、CapSolver)求解 Turnstile 驗證碼。 |
|
|
| **請求:** |
| ```http |
| POST /solve-external |
| Content-Type: application/json |
| |
| { |
| "sitekey": "0x4AAAAAAAxxxxxx", |
| "pageurl": "https://example.com", |
| "provider": "2captcha", |
| "api_key": "YOUR_API_KEY", |
| "timeout": 180 |
| } |
| ``` |
|
|
| **參數:** |
|
|
| | 參數 | 類型 | 必需 | 說明 | |
| |------|------|------|------| |
| | `sitekey` | string | ✓ | Turnstile sitekey | |
| | `pageurl` | string | ✓ | 包含驗證碼的頁面 URL | |
| | `provider` | string | ✓ | 服務提供商:`2captcha`、`anti-captcha`、`capsolver` | |
| | `api_key` | string | ✓ | 服務提供商的 API Key | |
| | `timeout` | integer | ✗ | 超時時間(秒),默認 180 | |
|
|
| **響應 (200 OK):** |
| ```json |
| { |
| "token": "0.xxxxxxxxxxxxx", |
| "success": true, |
| "message": "使用 2captcha 求解成功" |
| } |
| ``` |
|
|
| **錯誤響應 (400/500):** |
| ```json |
| { |
| "detail": "不支持的服務提供商: invalid-provider" |
| } |
| ``` |
|
|
| **示例:** |
| ```bash |
| curl -X POST http://localhost:7860/solve-external \ |
| -H "Content-Type: application/json" \ |
| -d '{ |
| "sitekey": "0x4AAAAAAAxxxxxx", |
| "pageurl": "https://example.com", |
| "provider": "2captcha", |
| "api_key": "YOUR_API_KEY", |
| "timeout": 180 |
| }' |
| ``` |
|
|
| **Python 示例:** |
| ```python |
| import requests |
| |
| response = requests.post( |
| "http://localhost:7860/solve-external", |
| json={ |
| "sitekey": "0x4AAAAAAAxxxxxx", |
| "pageurl": "https://example.com", |
| "provider": "2captcha", |
| "api_key": "YOUR_API_KEY", |
| "timeout": 180 |
| } |
| ) |
| |
| data = response.json() |
| print(f"Token: {data['token']}") |
| ``` |
|
|
| --- |
|
|
| ### 4. 獲取服務提供商列表 |
|
|
| 獲取支持的第三方服務提供商信息。 |
|
|
| **請求:** |
| ```http |
| GET /providers |
| ``` |
|
|
| **響應 (200 OK):** |
| ```json |
| { |
| "providers": [ |
| { |
| "name": "2captcha", |
| "url": "https://2captcha.com", |
| "description": "2captcha 驗證碼求解服務", |
| "pricing": "按求解次數計費" |
| }, |
| { |
| "name": "anti-captcha", |
| "url": "https://anti-captcha.com", |
| "description": "Anti-Captcha 驗證碼求解服務", |
| "pricing": "按求解次數計費" |
| }, |
| { |
| "name": "capsolver", |
| "url": "https://www.capsolver.com", |
| "description": "CapSolver 驗證碼求解服務", |
| "pricing": "按求解次數計費" |
| } |
| ] |
| } |
| ``` |
|
|
| **示例:** |
| ```bash |
| curl http://localhost:7860/providers |
| ``` |
|
|
| --- |
|
|
| ## 錯誤處理 |
|
|
| ### 常見錯誤碼 |
|
|
| | 狀態碼 | 說明 | 解決方案 | |
| |--------|------|--------| |
| | 200 | 成功 | - | |
| | 400 | 請求錯誤 | 檢查參數是否正確 | |
| | 500 | 服務器錯誤 | 檢查服務日誌 | |
|
|
| ### 錯誤響應格式 |
|
|
| ```json |
| { |
| "detail": "錯誤信息" |
| } |
| ``` |
|
|
| ### 常見錯誤 |
|
|
| **1. 無效的 sitekey** |
| ```json |
| { |
| "detail": "求解失敗: Invalid sitekey" |
| } |
| ``` |
|
|
| **解決方案:** 確認 sitekey 正確 |
|
|
| **2. 超時** |
| ```json |
| { |
| "detail": "求解失敗: Timeout" |
| } |
| ``` |
|
|
| **解決方案:** 增加 timeout 參數 |
|
|
| **3. API Key 無效** |
| ```json |
| { |
| "detail": "求解失敗: Invalid API key" |
| } |
| ``` |
|
|
| **解決方案:** 檢查 API Key 是否正確 |
|
|
| --- |
|
|
| ## 速率限制 |
|
|
| 目前無速率限制,但建議: |
| - 本地求解:最多 10 req/min |
| - 第三方服務:根據服務提供商限制 |
|
|
| --- |
|
|
| ## 認證 |
|
|
| 目前無認證機制。生產環境建議添加: |
|
|
| ```python |
| from fastapi import Depends, HTTPException |
| from fastapi.security import HTTPBearer |
| |
| security = HTTPBearer() |
| |
| @app.post("/solve") |
| async def solve_turnstile(request: TurnstileRequest, credentials = Depends(security)): |
| # 驗證 token |
| pass |
| ``` |
|
|
| --- |
|
|
| ## 超時設置 |
|
|
| ### 本地求解 |
|
|
| - **最小值**: 5000 ms (5 秒) |
| - **最大值**: 120000 ms (2 分鐘) |
| - **默認值**: 30000 ms (30 秒) |
|
|
| ### 第三方服務 |
|
|
| - **最小值**: 30 秒 |
| - **最大值**: 600 秒 (10 分鐘) |
| - **默認值**: 180 秒 (3 分鐘) |
|
|
| --- |
|
|
| ## 響應時間 |
|
|
| ### 本地求解 |
| - 平均: 10-30 秒 |
| - 最快: 5 秒 |
| - 最慢: 2 分鐘 |
|
|
| ### 第三方服務 |
| - 平均: 3-10 秒 |
| - 最快: 1 秒 |
| - 最慢: 10 分鐘 |
|
|
| --- |
|
|
| ## 使用示例 |
|
|
| ### JavaScript/Node.js |
|
|
| ```javascript |
| const response = await fetch('http://localhost:7860/solve', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json' |
| }, |
| body: JSON.stringify({ |
| url: 'https://example.com', |
| sitekey: '0x4AAAAAAAxxxxxx', |
| timeout: 30000 |
| }) |
| }); |
| |
| const data = await response.json(); |
| console.log(data.token); |
| ``` |
|
|
| ### Python |
|
|
| ```python |
| import requests |
| |
| response = requests.post( |
| 'http://localhost:7860/solve', |
| json={ |
| 'url': 'https://example.com', |
| 'sitekey': '0x4AAAAAAAxxxxxx', |
| 'timeout': 30000 |
| } |
| ) |
| |
| print(response.json()['token']) |
| ``` |
|
|
| ### Go |
|
|
| ```go |
| package main |
| |
| import ( |
| "bytes" |
| "encoding/json" |
| "io/ioutil" |
| "net/http" |
| ) |
| |
| func main() { |
| payload := map[string]interface{}{ |
| "url": "https://example.com", |
| "sitekey": "0x4AAAAAAAxxxxxx", |
| "timeout": 30000, |
| } |
| |
| body, _ := json.Marshal(payload) |
| resp, _ := http.Post( |
| "http://localhost:7860/solve", |
| "application/json", |
| bytes.NewBuffer(body), |
| ) |
| |
| defer resp.Body.Close() |
| data, _ := ioutil.ReadAll(resp.Body) |
| println(string(data)) |
| } |
| ``` |
|
|
| ### cURL |
|
|
| ```bash |
| curl -X POST http://localhost:7860/solve \ |
| -H "Content-Type: application/json" \ |
| -d '{ |
| "url": "https://example.com", |
| "sitekey": "0x4AAAAAAAxxxxxx", |
| "timeout": 30000 |
| }' |
| ``` |
|
|
| --- |
|
|
| ## 最佳實踐 |
|
|
| 1. **使用適當的超時** |
| - 本地求解:30-60 秒 |
| - 第三方服務:180-300 秒 |
|
|
| 2. **實現重試機制** |
| ```python |
| for attempt in range(3): |
| try: |
| result = solve_turnstile() |
| break |
| except Exception as e: |
| if attempt == 2: |
| raise |
| ``` |
|
|
| 3. **監控成功率** |
| - 記錄所有請求 |
| - 追蹤失敗原因 |
| - 定期分析 |
|
|
| 4. **使用連接池** |
| ```python |
| session = requests.Session() |
| response = session.post(url, json=data) |
| ``` |
|
|
| 5. **實現緩存** |
| - 緩存相同 sitekey 的結果 |
| - 減少重複求解 |
|
|
| --- |
|
|
| ## 支持 |
|
|
| - 文檔:https://github.com/your-repo/docs |
| - 問題:https://github.com/your-repo/issues |
| - 討論:https://github.com/your-repo/discussions |
|
|