文字问答验证码(无图,纯文本题)
文字问答验证码(无图,纯文本题) 是 通用题型 · 无单一厂商(由论坛/CMS 自带的问答验证产生) 的文字问答。表单里多出一行纯文字的题——「3 + 5 = ?」「天空是什么颜色?」「本站创始人姓什么?」——下面跟一个普通文本框。没有图片、没有滑块、没有第三方 iframe,整道题就是一句话加一个 input。
接口规格
| 项目 | 值 |
|---|---|
| type | text_captcha |
| 必填参数 | question |
| 可选参数 | language |
| 返回 | 一段文字(solution.text) |
| 怎么用这个解 | 答案文本 |
| 价格 | $0.83 / 1K 次 —— 按成功计费,没解出来退款 |
参数去页面哪里取
下面全部是可以直接照做的定位方法 —— DOM 属性名、JS 全局变量名、script 上的 query 参数。
没有 sitekey,也没有图。你要抄的只有两样:题面原文,和一个把这道题绑定到你这次会话的 id/hash——两者必须从同一次页面响应里取,回填时一起 POST,还要保持同一个 cookie jar。分开取(先抓题、再另开一个干净请求提交)必失败。
phpBB 3.x(Q&A CAPTCHA):答案框是 <input name="qa_answer" id="answer">;从它往上找到所在的 <dl>,题面就在同一个 <dl> 的 <dt><label> 里(模板 captcha_qa.html,模板变量 {QA_CONFIRM_QUESTION})。必须一起回传隐藏域 <input type="hidden" name="qa_confirm_id" id="qa_confirm_id">。选题按 lang_iso 跟随用户语言。
MediaWiki(ConfirmEdit + QuestyCaptcha):题面就是 <label for="wpCaptchaWord"> 的文本内容(document.querySelector('label[for=wpCaptchaWord]').textContent)。答案填 <input name="wpCaptchaWord" id="wpCaptchaWord">,一起提交隐藏域 <input name="wpCaptchaId">。走 action API 时字段名换成小写的 captchaid / captchaword。题库配置项是 $wgCaptchaQuestions。
Discuz! X(问答验证 / secqaa):⚠ 题面不在初始 HTML 里。页面只渲染一个空容器 <span id="secqaa_<idhash>"></span>,然后调 updatesecqaa('<idhash>'),真正的题目由 GET /misc.php?mod=secqaa&action=update&idhash=<idhash> 返回一段 JS 注入进去。注入完成后的 DOM 里才有 <input type="hidden" name="secqaahash" value="<idhash>"> 和 <input name="secanswer" id="secqaaverify_<idhash>">。⚠ 那个端点会校验 Referer 的 host 必须等于站点自身 host,裸请求会直接拿到 Access Denied。另有一个即时校验端点 GET /misc.php?mod=secqaa&action=check&secverify=<答案>&idhash=<idhash>,返回 succeed 或 invalid——提交整张表单之前可以先用它验一次。
Drupal(CAPTCHA 模块):题面在 captcha_response 字段的 <label> 里,形如 Math question (3 + 5 =)。答案填 <input name="captcha_response">(HTML id 通常是 edit-captcha-response),并且必须同时带上 <input type="hidden" name="captcha_sid"> 与 <input type="hidden" name="captcha_token">,少任何一个都判失败。这三个名字是平的、不带表单前缀——模块源码里显式写了 $element['#tree'] = FALSE;,注释是「即使宿主表单 #tree=true 也这样」。
WordPress / Contact Form 7 的 `[quiz]`:题面在 <span class="wpcf7-quiz-label"> 里,答案填同一个 <label> 内的 <input>(name 是表单作者起的 tag 名)。⚠ 旁边那个 <input type="hidden" name="_wpcf7_quiz_answer_<字段名>"> 装的是 wp_hash() 之后的答案,不是明文、读它拿不到答案,但必须原样回传。
SMF 2.x(Verification questions):题面是 <div id="verification_control_N" class="verification_control"> 里 <div class="smalltext"> 的纯文本,答案填 <input name="<verify_id>_vv[q][<问题id>]">(verify_id 随场景变,注册页是 register)。⚠ 同一块里还有一个 <div class="smalltext vv_special"> 包着的、名字随机生成的文本框——那是蜜罐,必须留空。
通用判据:页面上出现「一个纯文字问句 + 一个文本框 + 一个 hidden 的 id/hash/token,且完全没有图片和 iframe」,就是这一类。实在找不到 hidden 字段就先看 cookie——有的实现把题目 id 只放在 session 里,那种保持同一个 cookie jar 就够。
调用示例
一个端点解全部验证码类型 —— 换一种验证码只改 type 这一个字段。
curl -X POST https://api.everyinfra.com/api/v1/captcha \ -H "Authorization: Bearer omg_你的KEY" \ -H "Content-Type: application/json" \ -d '{"type":"text_captcha","question":"<question>"}'
{ "solution": { "text": "…" }, "billing": { "charged": true, "credits": 60 }}
怎么确认目标站用的就是它
赌的是「一句自然语言问句需要常识或本站上下文才能答对」,而灌水脚本只会照抄输入框、不会读题。答案在服务端与站长自己配置的答案表比对,多数实现先 trim + 转小写再比(phpBB 默认走 utf8_clean_string,MediaWiki 是 lowercase+trim)。安全性来自「题库是这个站自定义的、外人猜不到」,不来自密码学强度——MediaWiki 官方文档自己写明:因为单站题库很小,一个人把所有题答一遍是很容易的,而且常识类问题「能被 LLM 轻易解掉」。
容易搞混的
最容易和「图形文字识别」混——那种是把扭曲字母画成图片让你读出来。区分只看一件事:有没有图。有图就不是这条,question 参数收的是题面原文,不是图片。特别注意有些站会把 3+5=? 这个算式渲染成一张图片,看着也是道数学题,但那要走图形识别,不走这条。另一个混淆点是「点选文字」——那个也有文字提示,但要交付的是坐标不是答案文本。
常见部署场景
- phpBB 3.x 论坛的注册页(Q&A CAPTCHA 是它自带的 spambot countermeasure 之一,可按语言分题库)
- MediaWiki 站点的建号 / 编辑 / 加外链环节(ConfirmEdit 的 QuestyCaptcha 模块,题目写在 LocalSettings.php 里)
- Discuz! X 中文论坛的注册、发帖、找回密码(后台「防灌水 → 验证设置 → 验证问答设置」,内部代号 secqaa)
- Drupal 站点的注册与联系表单(CAPTCHA 模块的 Math 题,label 上直接写着 Math question (3 + 5 =))
- WordPress 自建站的联系表单:Contact Form 7 的 [quiz] 字段,以及各类 math captcha 插件
- SMF(Simple Machines Forum)的注册与发帖(后台 Anti-Spam Verification 的 Verification questions)
- 共同画像是「流量不大、没有专职安全团队、不愿引第三方 JS 的老论坛与自建站」——MediaWiki 官方文档的原话是:如果你的站又小又冷门,垃圾发布者一般懒得管你
已知的坑
题目与会话强绑定:题面、hidden id 和 cookie 必须在同一次请求里取,回填时一起送。先抓题、再另起一个干净请求提交,必失败。
Discuz! 的题不在 HTML 里,要打 misc.php?mod=secqaa&action=update&idhash=;而且该端点校验 Referer 的 host 必须与站点 host 相同,裸 curl 会拿到 Access Denied。
Contact Form 7 的 _wpcf7_quiz_answer_* 是 wp_hash() 后的值,不是明文答案;读它没用,但漏传就提交失败。
SMF 页面里有一个随机命名的蜜罐输入框(vv_special 那个),自动化填表时必须跳过它、保持为空。
Drupal 要 captcha_response + captcha_sid + captcha_token 三个字段齐全,只填答案不带另外两个照样失败。
判分通常是 trim + 转小写后比对,所以大小写和首尾空格一般不影响;但 phpBB 可以对单道题勾 strict,勾了之后就是严格逐字匹配。
同一个站的题库通常很小且长期不变(MediaWiki 官方文档明确承认这一点)。值得在本地缓存「题面 → 答案」,命中就不用再调——这是这条能力最容易被忽略的省钱点。
这条按人工作答处理,延迟在十几秒量级。别当 OCR 用,也别放在同步阻塞的用户请求链路里干等。
language 参数目前只有 en 与 ru 两个取值,它影响的是派给谁答,不改变题面——题面永远照抄原文传入。
phpBB 会按 lang_iso 给不同语言的用户出不同题库,所以同一个论坛用不同 Accept-Language 访问可能拿到完全不同的题。
这是真人答题,不是识别 —— 延迟通常在十几秒,别拿它当 OCR 用
常见问题
文字问答验证码(无图,纯文本题) 要传哪些参数?
必填 question;可选 language。请求里 type 传 text_captcha。
解出来的东西怎么用?
返回一段文字,取 solution.text。答案文本
edit-captcha-response 要去页面的哪里找?
重点找 edit-captcha-response、captcha_qa.html、captchaword。本页「参数去页面哪里取」一节写了全部位置与取法,含可直接粘进控制台的一行命令。
怎么确认目标站用的就是 文字问答验证码(无图,纯文本题)?
最容易和「图形文字识别」混——那种是把扭曲字母画成图片让你读出来。区分只看一件事:有没有图。有图就不是这条,question 参数收的是题面原文,不是图片。特别注意有些站会把 3+5=? 这个算式渲染成一张图片,看着也是道数学题,但那要走图形识别,不走这条。另一个混淆点是「点选文字」——那个也有文字提示,但要交付的是坐标不是答案文本。
有什么容易踩的坑?
题目与会话强绑定:题面、hidden id 和 cookie 必须在同一次请求里取,回填时一起送。先抓题、再另起一个干净请求提交,必失败。
多少钱一次,失败扣不扣?
$0.83 / 1K 次。按成功计费 —— 没解出来一律退款,所以失败不花钱。账单按次记,标价按每千次是为了让量级读得出来。