API Tutorials

使用 CaptchaAI calc 参数进行数学验证码求解

数学验证码考的是算数,不是认字:页面显示 "3 + 7 = ?",正确答案是 10,不是算式本身。普通 OCR 只读出算式原文,还得自己写代码再算一遍。CaptchaAI 的 calc 参数省掉这一步,接口直接把算式算完返回结果。下面用可运行的 Python 示例说明怎么接。


先判断要不要用 calc 参数

满足以下任意一条,直接加 calc=1

  • 只要最终数字,不关心算式原文。
  • 不想自己维护一套算式解析逻辑。
  • 算式偶尔是文字描述(比如 "three plus five")。

带括号、指数或多步运算的算式,calc 力不从心,见后文"复杂算式"一节。


calc 参数的两种取值

calc=0 是默认值,原样返回识别到的算式文字,例如 "3+7"calc=1 直接算出结果返回,例如 "10"


数学验证码识别基础用法:提交任务并轮询结果

import requests
import base64
import time
import os

API_KEY = os.environ["CAPTCHAAI_API_KEY"]


def solve_math_captcha(image_b64):
    """Solve a math CAPTCHA — returns the computed result."""
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "base64",
        "body": image_b64,
        "calc": 1,          # Compute the math
        "numeric": 1,       # Result will be a number
        "json": 1,
    }, timeout=30)

    result = resp.json()
    if result.get("status") != 1:
        raise RuntimeError(result.get("request"))

    task_id = result["request"]

    time.sleep(8)
    for _ in range(24):
        resp = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get",
            "id": task_id, "json": 1,
        }, timeout=15)
        data = resp.json()
        if data.get("status") == 1:
            return data["request"]
        if data["request"] != "CAPCHA_NOT_READY":
            raise RuntimeError(data["request"])
        time.sleep(5)

    raise TimeoutError("Solve timeout")


# Example: Image shows "3 + 7 = ?"
# With calc=0: Returns "3+7"
# With calc=1: Returns "10"

calc=1 建议和 numeric=1 一起提交,双保险防止误判。示例先等 8 秒再轮询,每 5 秒一次、最多 24 次,约 2 分钟超时,复杂算式可适当调大重试次数。


常见的算式格式一览

Format              Example        Result
─────────────────────────────────────────
Addition            3 + 7 = ?      10
Subtraction         15 - 8 = ?     7
Multiplication      4 × 6 = ?      24
Division            20 ÷ 5 = ?     4
Mixed               3 + 4 × 2 = ?  11
Text-based          "three plus five"  8

calc 覆盖的运算范围:

  • 加、减、乘、除四则运算
  • 先乘除后加减的混合运算
  • 文字型算式(比如 "three plus five")——识别难度更高,建议单独测试一批样本再上生产

复杂算式:搭配 textinstructions 参数

有些算式格式比较特殊,光靠 calc=1 未必能猜对怎么算,这时加一个 textinstructions 参数,用一句话告诉 CaptchaAI 该怎么处理这张图:

def solve_text_math_captcha(image_b64, instructions):
    """Solve a math CAPTCHA with custom instructions."""
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "base64",
        "body": image_b64,
        "calc": 1,
        "textinstructions": instructions,
        "json": 1,
    }, timeout=30)
    return resp.json()


# Example instructions:
# "Solve the math expression and enter the number"
# "What is the result of the equation shown?"
# "Enter the sum of the two numbers"

textinstructions 非必填,只在默认识别不稳定时加,一次只描述一件事,识别更稳定。


处理异常与结果校验

返回值可能带空格、负数或小数,都要在校验函数里处理掉,别指望接口每次都干净返回。

# edge_cases.py


def validate_math_result(answer):
    """Validate and clean math CAPTCHA result."""
    if not answer:
        return None

    # Remove spaces
    answer = answer.strip()

    # Handle negative results
    if answer.startswith("-"):
        try:
            return str(int(answer))
        except ValueError:
            return answer

    # Handle decimal results
    try:
        num = float(answer)
        if num == int(num):
            return str(int(num))
        return str(num)
    except ValueError:
        return answer


def solve_math_with_fallback(image_b64):
    """Try calc=1, fall back to manual parsing if needed."""
    # Try with calc
    result = solve_math_captcha(image_b64)

    # Validate result is actually a number
    try:
        float(result)
        return result
    except (ValueError, TypeError):
        pass

    # Fallback: solve without calc and compute locally
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "base64",
        "body": image_b64,
        "calc": 0,      # Get the expression text
        "json": 1,
    }, timeout=30)

    # ... poll for result ...
    expression = "3+7"  # Example OCR result

    # Safely evaluate
    return str(safe_eval(expression))


def safe_eval(expression):
    """Safely evaluate a simple math expression."""
    # Only allow digits and basic operators
    import re
    cleaned = expression.replace("×", "*").replace("÷", "/").replace("=", "").replace("?", "")
    cleaned = cleaned.strip()

    if not re.match(r'^[\d\s+\-*/().]+$', cleaned):
        raise ValueError(f"Unsafe expression: {expression}")

    return eval(cleaned)  # Safe because we validated the pattern

别默认相信返回值一定干净:validate_math_result 先处理空格、负数和小数;solve_math_with_fallback 更进一步,校验不通过就自动切回 calc=0,本地用 safe_eval 重新算,不会因一次识别失误就卡死整条流水线。


完整流程:截图 → 识别 → 自动填表

# full_flow.py
from selenium import webdriver
from selenium.webdriver.common.by import By
import base64
import os


def solve_math_captcha_on_page(driver, captcha_selector, input_selector, submit_selector):
    """Complete flow: capture math CAPTCHA, solve, enter answer."""

    # Capture CAPTCHA image
    captcha_el = driver.find_element(By.CSS_SELECTOR, captcha_selector)
    image_b64 = captcha_el.screenshot_as_base64

    # Solve with calc=1
    answer = solve_math_captcha(image_b64)
    print(f"Math answer: {answer}")

    # Enter the computed result
    input_el = driver.find_element(By.CSS_SELECTOR, input_selector)
    input_el.clear()
    input_el.send_keys(answer)

    # Submit
    driver.find_element(By.CSS_SELECTOR, submit_selector).click()


# Usage
driver = webdriver.Chrome()
driver.get("https://example.com/form")

solve_math_captcha_on_page(
    driver,
    captcha_selector="#captcha-image",
    input_selector="#captcha-answer",
    submit_selector="#submit-btn",
)

这段代码把前面几步串起来,接入时把三个 CSS 选择器换成你自己表单的元素即可:

  1. 截图——拿到验证码图片的 base64。
  2. 识别——调 solve_math_captcha,拿到计算结果。
  3. 填表——把结果写进输入框。
  4. 提交——点击提交按钮。

常见故障排查

现象 可能原因 处理方式
返回算式文本而非得数 漏了 calc=1 检查参数,补上 calc=1
得数不对 运算符识别错误(× 看成 +) textinstructions 说明算式格式
整数算式返回小数 浮点精度问题 转整数:str(int(float(result)))
报错 ERROR_CAPTCHA_UNSOLVABLE 算式图片扭曲太严重 先预处理图片(提升对比度、去噪)

国内开发环境的两个小提示

国内教务系统、政务平台、部分电商注册页也常见类似算术题,不只是海外站点才有。

场景 建议
pip install 网络慢 加国内镜像:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests
首次接入 先在有权限访问的表单或 staging 环境跑通,再上生产

常见问题

calc 和 numeric 两个参数一起提交,谁说了算?

calc=1 算出数字;numeric=1 只是校验结果是纯数字。只传 numeric=1 不加 calc=1,接口仍只识别文字。

轮询时一直收到 CAPCHA_NOT_READY,要一直等吗?

正常状态,任务还在队列里。示例每 5 秒轮询一次、最多 24 次,约 2 分钟超时;不建议无限轮询,超时就判定失败并重试。

calc 能处理带括号、指数这类复杂算式吗?

不能,calc 只覆盖加减乘除。遇到括号、指数或多步表达式,把 calc 设为 0 取回算式文本,本地用 safe_eval 计算。

结果是负数,calc 返回的准确吗?

准确,"5 - 8 = ?" 会返回 "-3"。下游代码用正则或 int() 处理返回值时记得兼容负号。

怎么确认 calc 返回的确实是数字?

别默认相信返回值是数字,尤其图片模糊时。像上文 validate_math_result 一样先用 float() 校验,失败就回退到 calc=0 兜底。


相关阅读


自动完成数学验证码识别——从 CaptchaAI 开始接入

该文章已禁用评论。