站点检查
当目标在访问请求页面的过程中运行 Bot 检查时,FourA 会通知您。每个遇到检查的 request 都会返回一个字段,指明该防护系统、检查是否已通过,以及(在通过时)可供重放以跳过下次调用的凭证。
本页是这些字段的参考文档。有关策略,请参阅 受保护站点。
字段所在位置
| Endpoint | Field | Present when |
|---|---|---|
POST /api/single/ |
defense (object) |
响应中识别出 Bot 检查 |
POST /api/proxy/ |
defense (object) |
同上,由响应的尝试所报告 |
POST /api/browser/ |
defenseSolved (boolean) 和 defenses (object) |
始终存在于已加载的页面上。未识别出任何内容时,defenseSolved 为 false 且 defenses 为空。 |
POST /api/auto/ |
meta.solved (boolean) |
阶梯策略启动后的每个应答中均存在。在阶梯策略中某处通过检查时为 true。校验失败的 body 或无法解析的 host 会在阶梯策略前应答,不包含 meta。 |
字段不存在表示未识别到任何内容。请勿将缺失的 defense 视为失败。
在 Single 和 Proxy 上,报告功能需要 unblocker(默认开启)。使用 unblocker: false 时,您请求的是原样返回的页面,因此 Single 会原样返回质询,而 Browser 会在不解决质询的情况下进行渲染。
Single 和 Proxy 上的 defense
{
"status": 200,
"data": "<!doctype html>...",
"total_time": 3.61,
"defense": {
"vendor": "sgcaptcha",
"solved": true,
"present": ["sgcaptcha"],
"ms": 3412,
"hashes": 1048576,
"complexity": 20,
"cookie": "_I_=<clearance>"
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
vendor |
string | 此记录对应的系统:已通过验证的系统,或遇到的主要系统。请参阅下方的供应商列表。 |
solved |
boolean | true 表示已通过检查,且 data 为真实页面。false 表示 data 可能是质询页面。 |
present |
string[] | 此 response 中识别到的所有系统。包含的名称可能多于 vendor,且可能包含目前尚无法通过验证的系统名称。 |
ms |
number | 通过检查所花费的毫秒数。仅在通过验证时提供。 |
hashes |
number | 质询要求的计算工作量。仅在通过验证时提供。 |
complexity |
number | 质询声明的难度。仅在通过验证且质询报告了难度时提供。 |
answers |
number | 已提供的有效答案数量,适用于需要多个答案而非单个答案的质询。仅在通过验证时提供。 |
retry |
string | 当 body 来自重试而非通过验证时出现。目前唯一的值为 refusal-cookies。详见下文。 |
cookie |
string | 用于重放的 jar:通过验证获得的通行凭证,或拒绝访问时分配的 session。 |
solved: false 是值得进行分支处理的情况。FourA 绝不会将质询页面作为内容呈现,因此该标志表明 body 需要升级处理而不是直接解析。
retry: "refusal-cookies"
某些网站不运行解题质询。它们会拒绝首次 request,在拒绝响应中设置 cookie,并向回传这些 cookie 的请求返回真实页面。eBay 的商品页面就是典型案例。
发生这种情况时,FourA 会自动代您回传 cookie 并向您提供页面。此时 response 会包含 retry: "refusal-cookies":
{
"status": 200,
"data": "<!doctype html>...",
"defense": {
"vendor": "akamai",
"solved": false,
"present": ["akamai"],
"retry": "refusal-cookies",
"cookie": "bm_sv=...; dp1=..."
}
}
按以下方式理解:
- **
solved保持为false。**响应握手不等于通过质询,且绝不会改变调用的费用。计费仅基于你发起的 request。 data是真实内容,而非质询页面。这是solved: false不代表响应体需要升级处理的唯一情况,这也是该字段存在的原因。- **
cookie是目标站点分发的会话。**像重放通行凭证一样重放它,后续页面即可跳过拒绝访问。 - 一次 request 中可能同时发生重试与清除操作。若重试返回的内容是 FourA 能够清除的质询,你将收到包含供应商自身字段的
solved: true,以及并列的retry: "refusal-cookies"。
当重试成功获取内容且过程中未识别出任何系统时,vendor 为 unknown。此时 present 为空数组。
浏览器上的 defenses
{
"status": 200,
"body": "<!doctype html>...",
"userAgent": "Mozilla/5.0...",
"defenseSolved": true,
"defenses": {
"present": ["cloudflare"],
"cleared": ["cloudflare"]
}
}
| 字段 | 类型 | 描述 |
|---|---|---|
defenseSolved |
boolean | 当页面加载过程中遇到防护系统且最终页面保留其 clearance 时为 true。该标志决定此调用扣除 5 还是 10 个点数。 |
defenses.present |
string[] | 页面加载期间任何时刻识别出的所有系统,不仅限于最终 response。检查属于已发生事件,当真实页面返回时挑战 response 早已结束。 |
defenses.cleared |
string[] | 最终页面保留其 clearance 的系统列表。 |
仅出现在 present 但未进入 cleared 的名称代表 FourA 能够识别但暂无法通过的系统。这些系统绝不会增加调用的扣费。
供应商
vendor 值 |
系统 |
|---|---|
cloudflare |
Cloudflare 挑战与 bot 管理 |
sgcaptcha |
SiteGround 站点检查 |
datadome |
DataDome |
perimeterx |
PerimeterX |
akamai |
Akamai Bot Manager |
incapsula |
Imperva Incapsula |
awswaf |
AWS WAF 挑战 |
ebay-splashui |
eBay 自定义挑战 |
reddit |
Reddit 自定义检查与拦截页面 |
amazon |
Amazon 机器人检查 |
google |
Google Search 的 JavaScript 检查 |
hcaptcha |
hCaptcha |
recaptcha |
reCAPTCHA |
unknown |
未识别出任何系统。仅在出现 retry 时展示,此时该记录用于报告重试而非供应商。 |
当前支持清除的类型
| Endpoint | 支持清除 |
|---|---|
| Single, Proxy | sgcaptcha, ebay-splashui。两者均属于计算型验证而非视觉验证,因此无需浏览器参与。 |
| Browser | cloudflare, sgcaptcha |
列表中其余所有项仅供识别与报告,不做进一步处理。随着 FourA 支持清除更多类型,该划分会随之变动,因此请读取 solved 而非仅依赖本表推断。
边缘情况的两点说明:
hcaptcha和recaptcha也可作为常规表单组件。仅当 response 实际产生拦截(403、429 或 503)时才会报告,因此结账页面表单中包含的验证组件不会被视作防御进行报告。- 位于 Cloudflare 之后并不等同于存在防御。
cloudflare仅在 response 中存在实际挑战或 bot 管理特征时出现,而非仅因网站使用了 Cloudflare。
重放 Clearance
defense.cookie 是该字段的核心意义所在。Clearance 绑定至获取它时所用的出口 IP 和 User-Agent,因此通过相同的出口与 User-Agent 组合进行重放即可避免再次触发检查。
import requests
API = "https://eu.api.foura.ai"
H = {"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"}
# 1) First call pays for the clear.
first = requests.post(f"{API}/api/proxy/", headers=H, json={
"maxTries": 5,
"request": {"method": "GET", "url": "https://example.com/catalog"},
}).json()
defense = first.get("defense", {})
if defense.get("solved"):
clearance = defense["cookie"]
exit_id = first["proxy"]
# 2) Follow-up pages skip the check: same exit, same clearance.
for page in range(2, 6):
r = requests.post(f"{API}/api/single/", headers=H, json={
"method": "GET",
"url": f"https://example.com/catalog?page={page}",
"proxy": exit_id,
"headers": [["Cookie", clearance]],
}).json()
print(page, r["status"])
首次调用包含绕过验证的成本。后续每次重放都是按普通价格计费的常规 request。
导致重放失效的三种情况:
- 出口节点改变。 绑定清除验证响应所返回的 proxy ID。参见 跨请求复用 Proxy。
- User-Agent 改变。 Browser 响应会返回其使用的
userAgent。请将其与 cookie 一同回传。 - 过期。 验证通行证(Clearance)有其自身的生命周期,由目标网站设定。SiteGround 针对全站的有效期约为 30 天;Cloudflare 的有效期通常短得多。将通行证视为缓存:当重放开始重新触发验证时,发起一次新的调用并获取新通行证。
费用说明
成功绕过验证仅会改变 Browser 的价格:
| 引擎 | 基础价格 | 绕过防御价格 |
|---|---|---|
| Single | 1(包含 unblocker 时为 2) |
无变化 |
| Proxy | 2(包含 unblocker 时为 4) |
无变化 |
| Browser | 5 | 10 |
Browser 仅在求解器开启且成功绕过系统验证时收取 10。若识别到系统但未成功绕过,则收费 5,与完全没有验证的页面费用相同。
返回 HTTP 200 且被 FourA 识别为验证页面的请求(例如 Amazon 的机器人检查、Reddit 的验证页面或 Google Search 的 JavaScript 检查)在任何 endpoint 上均不计费;响应会在 X-FourA-Check-Page 中注明该类型。
与 validate 搭配使用
defense 用于告知遇到了验证。validate 用于告知 FourA 真实页面的特征,从而使 request 在遇到恰好返回 HTTP 200 的过渡拦截页时直接失败,而不是将其作为成功结果返回。
{
"method": "GET",
"url": "https://example.com/product/42",
"validate": {
"data": {"accept": ["Add to cart"], "fail": ["Just a moment"]}
}
}
在 POST /api/auto/ 上,validate 可以防止阶梯策略误将质询页面视为成功请求。
相关内容
- 受保护站点:各防护级别适用的引擎选择
- API 端点:全部 4 个 endpoint 的 request 和 response 参考
- 跨 Request 复用 Proxy:固定 clearance 绑定的出口
- Smart Fetch (Auto):
meta.solved如何融入阶梯策略 - Response Headers:调用额度消耗的显示位置