Tutorials

连接保持活动和 HTTP/2 可实现更快的 CAPTCHA API 调用

验证码识别脚本变慢,锅不一定在 CaptchaAI,可能是 HTTP 客户端每次都重新握手。一次 reCAPTCHA v2 识别要发 5-7 次请求(1 次提交 + 多次轮询),不复用连接的话,TCP 握手和 TLS 协商就吃掉大半时间。

国内服务器访问海外接口延迟更高,复用连接的收益也更明显。下面用代码教你在调用 CaptchaAI API 时用 keep-alive 和 HTTP/2 压低开销。

延迟都花在了哪里

一次典型的 reCAPTCHA v2 识别包含:

请求类型 次数 目标接口
提交 1 次 in.php
轮询 4-6 次 res.php
合计 5-7 次

不复用连接时:

  • 5 ×(TCP 握手 ~50ms + TLS 协商 ~100ms)= 750ms 开销

复用连接后:

  • 1 ×(TCP + TLS)+ 4 ×(~5ms 复用)= 170ms 开销

每次识别大约能省 580 毫秒。 按每天 10,000 次识别算,一天能省下 1.6 小时的等待时间。

HTTP/2 该不该换掉 HTTP/1.1 keep-alive

先定方案,再看代码——两种连接复用方式该怎么选:

特性 HTTP/1.1 keep-alive HTTP/2
连接复用 有(顺序执行) 有(多路复用)
并发流 每连接 1 个 每连接可达 100+ 个
请求头压缩 HPACK 压缩
延迟降幅 约 60% 约 70%
是否需要浏览器支持 否(纯 API 调用)
最适合场景 顺序识别 并行识别

顺序识别用 HTTP/1.1 keep-alive 就够了;并行处理多个验证码时,HTTP/2 多路复用能共享一条连接,收益更明显。

连接池该配多大

把连接池大小对齐你的并发量:

并发识别数 建议连接池大小
1-5 5 个连接
5-20 10 个连接
20-50 25 个连接
50-100 50 个连接
100+ 直接上 HTTP/2(1 个连接)

池子太大浪费内存,太小又会频繁建新连接,白搭了 keep-alive 的好处。

方案一:Python requests.Session 长连接

requests 库只要用 Session 对象,就默认支持 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]}...")

进阶:用 httpx 开启 HTTP/2

想要 HTTP/2 支持,换成 httpx

服务器在国内的话,装依赖建议带上镜像更稳:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 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()

方案二:Node.js 用 Axios + Keep-Alive Agent

Node.js 里同样的思路——把 http.Agent / https.Agent 设成 keepAlive: true,再交给 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();
})();

常见故障排查

问题 原因 处理方式
轮询之间连接总断开 服务器或代理超时设置太短 客户端把 keep-alive 超时设到 > 30 秒
开了 keep-alive 但没提速 库里其实已经默认开启,重复设置无效 用抓包或网络监控工具实际核实一下
出现连接被拒绝的报错 连接池被打满 调大 maxSockets,或者降低并发数
HTTP/2 协商不成功 服务器不支持 h2 自动回退到 HTTP/1.1 keep-alive 即可

常见问题

CaptchaAI 支持 HTTP/2 吗?

支持。用 curl --http2 https://ocr.captchaai.com/res.php 验证;协商成功就走 HTTP/2,不成功会自动回退到 HTTP/1.1 keep-alive,不影响识别结果。

为什么开了 keep-alive,速度却没明显变化?

多半是库里本来就默认开着,你的配置没起到额外作用;也可能瓶颈根本不在连接层,而在轮询间隔或识别本身耗时。先用网络监控工具确认连接是否真的被复用了。

每批识别完要不要手动关闭 session?

不用。批量识别时让 session 在批次之间保持打开,只在程序整体退出时再关闭;频繁开关等于放弃了 keep-alive 的好处。

HTTP/2 一定比 HTTP/1.1 keep-alive 快吗?

不一定。单队列顺序识别(一次只处理一个验证码)时两者差距很小;只有并发识别多个验证码时,HTTP/2 多路复用的优势才真正体现出来。

相关文章

下一步

给每次识别都省下一段连接开销——获取你的 CaptchaAI API 密钥

相关指南:

该文章已禁用评论。