每个 CAPTCHA 解决都涉及多个 HTTP 请求:一次提交和 3-10 次轮询。如果没有连接重用,每个请求都会付出新的 TCP 握手和 TLS 协商的成本 - 每个连接 100-300 毫秒。本指南展示了如何使用保持活动连接和 HTTP/2 复用来消除该开销CaptchaAI。
为什么连接重用很重要
典型的 reCAPTCHA v2 求解需要:
- 1 向
in.php提交请求 - 4-6 个对
res.php的投票请求 - 总计:5–7 个 HTTP 请求
没有保持活动状态:
- 5 ×(TCP 握手 ~50ms + TLS ~100ms)= 750ms 开销
保持活动状态:
- 1 × (TCP + TLS) + 4 × (~5ms 重用) = 170ms 开销
节省:每次求解约 580 毫秒。 在 10,000 次求解 /day 时,可节省 1.6 小时的延迟。
Python:使用 requests.Session
当您使用 Session 对象时,requests 库默认支持 keep-alive:
# keepalive_solver.py
import os
import time
import requests
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
# Create a session — reuses TCP connections across requests
session = requests.Session()
session.headers.update({"Connection": "keep-alive"})
def solve_captcha(sitekey, pageurl):
"""Solve reCAPTCHA v2 using a persistent connection."""
# Submit — uses existing connection if available
resp = session.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
})
result = resp.json()
if result.get("status") != 1:
raise Exception(f"Submit failed: {result.get('request')}")
task_id = result["request"]
# Poll — reuses the same connection
time.sleep(15)
for _ in range(25):
poll = session.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": "1",
})
poll_result = poll.json()
if poll_result.get("status") == 1:
return poll_result["request"]
if poll_result.get("request") != "CAPCHA_NOT_READY":
raise Exception(f"Error: {poll_result.get('request')}")
time.sleep(5)
raise Exception("Timeout")
# Solve multiple CAPTCHAs reusing the same connection
for i in range(5):
token = solve_captcha(
"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"https://www.google.com/recaptcha/api2/demo"
)
print(f"Solve {i+1}: {token[:30]}...")
Python:带有 httpx 的 HTTP/2
对于 HTTP/2 支持,请使用 httpx:
# http2_solver.py
import os
import time
import httpx
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
BASE_URL = "https://ocr.captchaai.com"
# HTTP/2 client with connection pooling
client = httpx.Client(http2=True, timeout=30.0)
def solve_captcha(sitekey, pageurl):
"""Solve using HTTP/2 multiplexed connections."""
resp = client.get(f"{BASE_URL}/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
})
result = resp.json()
if result.get("status") != 1:
raise Exception(f"Submit failed: {result.get('request')}")
task_id = result["request"]
time.sleep(15)
for _ in range(25):
poll = client.get(f"{BASE_URL}/res.php", params={
"key": API_KEY, "action": "get",
"id": task_id, "json": "1",
})
poll_result = poll.json()
if poll_result.get("status") == 1:
return poll_result["request"]
if poll_result.get("request") != "CAPCHA_NOT_READY":
raise Exception(f"Error: {poll_result.get('request')}")
time.sleep(5)
raise Exception("Timeout")
# Multiple solves over a single HTTP/2 connection
for i in range(5):
token = solve_captcha(
"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"https://www.google.com/recaptcha/api2/demo"
)
print(f"Solve {i+1}: {token[:30]}...")
client.close()
JavaScript:使用具有 Keep-Alive 功能的 Axios 实例
// keepalive_solver.js
const axios = require('axios');
const http = require('http');
const https = require('https');
const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';
// Create agents with keep-alive enabled
const httpAgent = new http.Agent({ keepAlive: true, maxSockets: 10 });
const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 10 });
// Axios instance with persistent connections
const api = axios.create({
baseURL: 'https://ocr.captchaai.com',
httpAgent,
httpsAgent,
timeout: 30000,
});
async function solveCaptcha(sitekey, pageurl) {
// Submit — reuses connection
const submit = await api.get('/in.php', {
params: {
key: API_KEY, method: 'userrecaptcha',
googlekey: sitekey, pageurl, json: '1',
},
});
if (submit.data.status !== 1) throw new Error(submit.data.request);
const taskId = submit.data.request;
// Poll — reuses same connection
await new Promise(r => setTimeout(r, 15000));
for (let i = 0; i < 25; i++) {
const poll = await api.get('/res.php', {
params: { key: API_KEY, action: 'get', id: taskId, json: '1' },
});
if (poll.data.status === 1) return poll.data.request;
if (poll.data.request !== 'CAPCHA_NOT_READY') throw new Error(poll.data.request);
await new Promise(r => setTimeout(r, 5000));
}
throw new Error('Timeout');
}
(async () => {
for (let i = 0; i < 5; i++) {
const token = await solveCaptcha(
'6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
'https://www.google.com/recaptcha/api2/demo'
);
console.log(`Solve ${i + 1}: ${token.slice(0, 30)}...`);
}
// Clean up agents
httpAgent.destroy();
httpsAgent.destroy();
})();
用于验证码解决的 HTTP/2 与 HTTP/1.1
| 特征 | HTTP/1.1 保持活动状态 | HTTP/2 |
|---|---|---|
| 连接复用 | 是(顺序) | 是(多路复用) |
| 并发流 | 每个连接 1 个 | 每个连接最多 100 个以上 |
| 标头压缩 | 不 | HPACK压缩 |
| 减少延迟 | 〜60% | 〜70% |
| 需要浏览器支持 | 不 | 否(API 调用) |
| 最适合 | 顺序求解 | 并行求解 |
对于顺序求解(一次一个验证码),HTTP/1.1 保持活动状态就足够了。对于并行求解(同时进行多个验证码),HTTP/2 多路复用通过共享单个连接提供了额外的好处。
连接池大小调整
将池大小与并发级别相匹配:
| 并发解决 | 建议水池尺寸 |
|---|---|
| 1-5 | 5 个连接 |
| 5-20 | 10 个连接 |
| 20-50 | 25 个连接 |
| 50-100 | 50 个连接 |
| 100+ | 使用 HTTP/2(1 个连接) |
过大的池会浪费内存。过小的池会强制建立新的连接,从而抵消了保持活动的好处。
故障排除
| 问题 | 原因 | 处理方式 |
|---|---|---|
| 连接在轮询之间关闭 | 服务器或代理超时 | 在客户端配置中设置 keep-alive 超时 > 30 秒 |
| 没有性能提升 | 已经使用 keep-alive (某些库中默认) | 使用网络监控工具进行验证 |
| 连接被拒绝错误 | 池已耗尽 | 增加maxSockets或减少并发 |
| HTTP/2 未协商 | 服务器不支持h2 | 回退到 HTTP/1.1 保持活动状态 |
常问问题
CaptchaAI是否支持HTTP/2?
使用curl --http2 https://ocr.captchaai.com/res.php进行测试验证。如果服务器协商 h2,您的 HTTP/2 客户端将受益。如果不是,则退回到 HTTP/1.1 保持活动状态。
我应该在每批之后关闭会话吗?
不可以。如果您正在运行定期求解,请在批次之间保持会话打开。仅当您的应用程序关闭时才关闭。
这适用于代理服务器吗?
是的,但您的代理还必须支持 keep-alive 和 HTTP/2. 某些 SOCKS5 代理不维护持久连接。
相关文章
下一步
减少每个解决方案的连接开销 -获取您的 CaptchaAI API 密钥。
相关指南: