提交-輪詢 API 文檔
概述
本地 Playwright 服務現已支持類似 2captcha 的提交-輪詢 API 模式。
API 端點
1. 提交任務
端點: POST /api/v1/captcha/submit
請求:
{
"url": "https://example.com",
"sitekey": "0x4AAAAAAAxxxxxx",
"timeout": 30000
}
參數:
url(string, 必需) - 包含 Turnstile 的網頁 URLsitekey(string, 必需) - Turnstile sitekeytimeout(integer, 可選) - 超時時間(毫秒),默認 30000
響應 (200 OK):
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"message": "任務已提交,請輪詢查詢結果"
}
示例:
curl -X POST http://localhost:7860/api/v1/captcha/submit \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"sitekey": "0x4AAAAAAAxxxxxx",
"timeout": 30000
}'
2. 查詢結果
端點: GET /api/v1/captcha/result/{task_id}
參數:
task_id(string, 必需) - 任務 ID
響應 (200 OK):
待處理狀態:
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"token": null,
"error": null,
"created_at": "2024-04-04T20:00:00.000000",
"updated_at": "2024-04-04T20:00:00.000000"
}
處理中狀態:
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"token": null,
"error": null,
"created_at": "2024-04-04T20:00:00.000000",
"updated_at": "2024-04-04T20:00:05.000000"
}
完成狀態:
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "ready",
"token": "0.xxxxxxxxxxxxx",
"error": null,
"created_at": "2024-04-04T20:00:00.000000",
"updated_at": "2024-04-04T20:00:30.000000"
}
失敗狀態:
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"token": null,
"error": "無法獲取 Turnstile token",
"created_at": "2024-04-04T20:00:00.000000",
"updated_at": "2024-04-04T20:00:30.000000"
}
示例:
curl http://localhost:7860/api/v1/captcha/result/550e8400-e29b-41d4-a716-446655440000
3. 查詢狀態
端點: GET /api/v1/captcha/status/{task_id}
參數:
task_id(string, 必需) - 任務 ID
響應 (200 OK):
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"message": "處理中"
}
示例:
curl http://localhost:7860/api/v1/captcha/status/550e8400-e29b-41d4-a716-446655440000
4. 獲取統計信息
端點: GET /api/v1/captcha/stats
響應 (200 OK):
{
"total": 10,
"pending": 2,
"processing": 1,
"ready": 5,
"failed": 2
}
示例:
curl http://localhost:7860/api/v1/captcha/stats
5. 刪除任務
端點: DELETE /api/v1/captcha/{task_id}
參數:
task_id(string, 必需) - 任務 ID
響應 (200 OK):
{
"success": true,
"message": "任務已刪除"
}
示例:
curl -X DELETE http://localhost:7860/api/v1/captcha/550e8400-e29b-41d4-a716-446655440000
任務生命週期
提交 → pending → processing → ready/failed
↓ ↓
submit poll poll poll
↓
返回 token
狀態說明
| 狀態 | 說明 | 可操作 |
|---|---|---|
pending |
等待處理 | 輪詢 |
processing |
處理中 | 輪詢 |
ready |
已完成 | 獲取 token |
failed |
已失敗 | 查看錯誤 |
使用示例
Python
import requests
import time
# 1. 提交任務
response = requests.post(
'http://localhost:7860/api/v1/captcha/submit',
json={
'url': 'https://example.com',
'sitekey': '0x4AAAAAAAxxxxxx',
'timeout': 30000
}
)
data = response.json()
task_id = data['task_id']
print(f"任務已提交: {task_id}")
# 2. 輪詢結果
while True:
response = requests.get(
f'http://localhost:7860/api/v1/captcha/result/{task_id}'
)
result = response.json()
status = result['status']
print(f"狀態: {status}")
if status == 'ready':
print(f"Token: {result['token']}")
break
elif status == 'failed':
print(f"錯誤: {result['error']}")
break
time.sleep(2) # 等待 2 秒後重新輪詢
JavaScript
// 1. 提交任務
const response = await fetch('http://localhost:7860/api/v1/captcha/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
url: 'https://example.com',
sitekey: '0x4AAAAAAAxxxxxx',
timeout: 30000
})
});
const data = await response.json();
const taskId = data.task_id;
console.log(`任務已提交: ${taskId}`);
// 2. 輪詢結果
const pollResult = async () => {
while (true) {
const response = await fetch(
`http://localhost:7860/api/v1/captcha/result/${taskId}`
);
const result = await response.json();
const status = result.status;
console.log(`狀態: ${status}`);
if (status === 'ready') {
console.log(`Token: ${result.token}`);
break;
} else if (status === 'failed') {
console.log(`錯誤: ${result.error}`);
break;
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
};
pollResult();
cURL
# 1. 提交任務
TASK_ID=$(curl -s -X POST http://localhost:7860/api/v1/captcha/submit \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"sitekey": "0x4AAAAAAAxxxxxx",
"timeout": 30000
}' | jq -r '.task_id')
echo "任務已提交: $TASK_ID"
# 2. 輪詢結果
while true; do
RESULT=$(curl -s http://localhost:7860/api/v1/captcha/result/$TASK_ID)
STATUS=$(echo $RESULT | jq -r '.status')
echo "狀態: $STATUS"
if [ "$STATUS" = "ready" ]; then
TOKEN=$(echo $RESULT | jq -r '.token')
echo "Token: $TOKEN"
break
elif [ "$STATUS" = "failed" ]; then
ERROR=$(echo $RESULT | jq -r '.error')
echo "錯誤: $ERROR"
break
fi
sleep 2
done
最佳實踐
1. 輪詢間隔
建議輪詢間隔:
- 第一次:立即查詢
- 後續:每 2-5 秒查詢一次
import time
# 指數退避策略
poll_interval = 1
max_interval = 10
while True:
result = query_result(task_id)
if result['status'] in ['ready', 'failed']:
break
time.sleep(poll_interval)
poll_interval = min(poll_interval * 1.5, max_interval)
2. 超時處理
import time
start_time = time.time()
timeout = 60 # 60 秒超時
while time.time() - start_time < timeout:
result = query_result(task_id)
if result['status'] in ['ready', 'failed']:
return result
time.sleep(2)
raise TimeoutError("任務超時")
3. 錯誤處理
try:
# 提交任務
response = requests.post(url, json=payload)
response.raise_for_status()
task_id = response.json()['task_id']
# 輪詢結果
while True:
response = requests.get(f'{url}/{task_id}')
response.raise_for_status()
result = response.json()
if result['status'] == 'ready':
return result['token']
elif result['status'] == 'failed':
raise Exception(result['error'])
time.sleep(2)
except requests.RequestException as e:
print(f"請求失敗: {e}")
except Exception as e:
print(f"錯誤: {e}")
與 2captcha 的相似性
| 功能 | 2captcha | 本地服務 |
|---|---|---|
| 提交任務 | POST /api/captcha | POST /api/v1/captcha/submit |
| 查詢結果 | GET /api/result | GET /api/v1/captcha/result/{id} |
| 任務 ID | captcha_id | task_id |
| 狀態 | 0=pending, 1=ready | pending/processing/ready/failed |
| 費用 | 按次計費 | 免費 |
常見問題
Q: 任務多久過期? A: 默認 30 分鐘後自動過期並刪除。
Q: 可以同時提交多少個任務? A: 無限制,但受系統資源限制。
Q: 輪詢頻率有限制嗎? A: 無限制,但建議每 2-5 秒輪詢一次。
Q: 任務失敗後可以重新提交嗎? A: 可以,直接提交新任務即可。
支持
- 文檔:查看本文件
- 問題:提交 Issue
- 討論:加入社區