如何在 Make.com 中不用代码步骤识别验证码

make.com captcha - How to Solve CAPTCHA in Make.com Without a Code Step

Make.com 里的验证码环节就是三个 HTTP 模块加一个 Sleep,整个场景里没有任何代码。提交挑战,等待,轮询直到 token 回来,再把它和表单一起发出去。真正卡住大家的不是这个循环,而是地址:场景跑在 Make.com 自己的云里,所以那里的 127.0.0.1 是 Make.com 的容器,不是你的桌面;而且 HTTP 模块只会调用 HTTPS 地址,证书还必须是它信得过的。地址弄对了,剩下的就是十五分钟的点击。

你需要什么

  • 一个 Make.com 账号,任何套餐都行。这里用到的每个模块都在内置的 HTTP、Tools 和 Flow control 应用里。
  • CapSkip 以 Server 模式运行在一台你自己掌控的 Windows 机器上,并且能从互联网访问到。
  • 一个指向那台机器的主机名,以及一张为它签发的、公开受信任的 TLS 证书。
  • 受保护表单的页面 URL,以及它的 sitekey。

Local 模式和 Server 模式都写在 连接设置。当你的自动化流程和识别工具共用一台机器时,Local 模式才是对的选择,而这恰恰是云端场景做不到的。

为什么回环地址在这里行不通

Make.com 的场景在 Make.com 自己的基础设施上执行,分布在四个区域里。你的账号落在 us1、us2、eu1 或 eu2 其中之一,每一个出站请求都从该区域已公布的出口地址发出。这条路径上没有一环碰到你的网络,所以一个发往 127.0.0.1 的请求只会解析到运行你场景的那个容器里,什么都不会有人应答。

答案是 Server 模式,而它并不是另一个产品。识别工具依然跑在你自己的硬件上,依然不按次收费,也依然暴露同一套兼容 2captcha 的端点。变的只是它绑定的接口:它不再只回应本机设备,而是监听在你的内网或公网 IP 上,任何拿到地址和密钥的东西都能调用它。固定公网 IP 能让这个地址不在你脚下变来变去。

那份已公布的出口地址列表反过来也有用。Make.com 按区域列出了出站地址,所以你可以在防火墙上只放行你所在区域的地址访问识别工具的端口,其余一律丢弃。Make.com 那一侧的入站地址是动态的,也没有公布,所以别想着把它们固定下来。

给识别工具一个 Make.com 认的地址

这是那个把所有人都绊倒的要求,值得读两遍。HTTP 模块的文档写明它的 URL 字段是一个 HTTPS 端点,而且它会拒绝自己无法验证的证书。自签名证书不够用,明文 HTTP 下 8080 端口上的一个裸 IP 地址同样不够用。

所以在识别工具前面放一个 TLS 终结器。在 Windows 上 Caddy 是最短的路径,因为它会自己申请和续期一张真证书,而且一条命令就是全部配置。先把一个主机名指向这台机器,然后运行它。

# Fronts CapSkip on 8080 with a real certificate for the hostname.
# Ports 80 and 443 must reach this machine for the challenge.
caddy reverse-proxy --from solver.example.com --to 127.0.0.1:8080

在动 Make.com 之前,先从你自己的机器上验证一遍。如果 curl 对这张证书没有意见,场景也不会有意见,你等于把要调试的范围砍掉了一半。

# Submit a reCAPTCHA v2 job. json=1 makes the reply JSON.
curl -s "https://solver.example.com/in.php" \
  -d "key=YOUR_API_KEY" \
  -d "method=userrecaptcha" \
  -d "googlekey=YOUR_SITEKEY" \
  -d "pageurl=https://example.com/page-with-recaptcha" \
  -d "json=1"

# {"status":1,"request":"2122988149"}

第 1 步:提交验证码

添加一个 HTTP 模块,选择发起请求的那个动作。把方法设为 POST,URL 设为你识别工具的 in.php 端点。body 类型选 URL-encoded,然后添加五个字段,就是上面那条 curl 命令发送的同样五个:key、方法名、sitekey、页面 URL 和 JSON 标志。

把解析响应的那个选项打开。不打开的话,回复会以一整个字符串的形式到达,你什么都映射不出来。打开之后你拿到的是一个 status 和一个 request 值,提交成功时 request 值就是任务 ID。

方法名决定了验证码类型。reCAPTCHA v2 用 userrecaptcha,v3 在它基础上加 version=v3,Cloudflare Turnstile 用 turnstile,极验(GeeTest)v3 用 geetest,内联发送的图片验证码用 base64。每一种的完整参数列表见 CapSkip API 文档.

第 2 步:先等待,再轮询

从 Tools 应用里添加一个 Sleep 模块。一次 reCAPTCHA v2 识别通常要十五到四十五秒,所以立刻去轮询只会白白花掉一次操作,换回一句「答案还没准备好」。二十秒是一个合理的首次等待时长。

Sleep 最多能把场景延迟 300 秒,也就是五分钟,而这个上限正是下一步要用循环、而不是一次长等待的原因。它比单次识别所需的时间宽裕得多,但你没法靠它坐等一个未知次数的重试。

第 3 步:轮询直到 token 返回

Make.com 没有「等待直到满足条件」这类模块,所以轮询要用一个 Repeater 加一个过滤器搭出来。Repeater 在 Flow control 应用里,它是一个数据包(bundle)生成器:给它一个初始值和一个重复次数,它就会发出这么多个数据包,每个都带着一个名为 i 的计数器。它下游的一切都会对每个数据包各跑一次,这就是你的循环体。

把重复次数设为十次。在 Repeater 后面放第二个 Sleep,时长五秒,再放第二个 HTTP 模块,用第 1 步拿到的任务 ID 去调用 res.php。

# The poll. Same key, the id from the submit, action=get.
curl -s "https://solver.example.com/res.php?key=YOUR_API_KEY&action=get&id=2122988149&json=1"

# Still working:
# {"status":0,"request":"CAPCHA_NOT_READY"}
#
# Done:
# {"status":1,"request":"03AGdBq24PBCbwiDR..."}

现在给离开这个模块的连线加上一个过滤器,只让 status 等于 1 的数据包通过。这样过滤器之后的一切就只会运行一次,也就是在轮询成功的那一次上,其他尝试都过不去。但要弄清楚它做了什么、又没做什么。Repeater 依然会把你要它发的每一个数据包都发出去,所以循环并不会提前结束;提前结束的是等待,因为只要有一次轮询拿到了 token,token 就会立刻往下走。token 就是那个数据包上的 request 值。

这套 API 有一个特性决定了这个设计,而且很容易被忽略。结果只能读取一次,所以第一次成功的轮询是唯一一次能把 token 交给你的机会。请当场就把它映射进后面的步骤,不要再调一次 res.php 去重新取。

同样的「先提交再轮询」结构在每一个无代码工具里都会出现,差别全在平台强加在它周围的那些限制上。这套流程的自托管版本,也就是自动化流程和识别工具可以共用一台机器的那种,写在 n8n 验证码工作流指南。而决定结构的是步骤运行时长上限、不是 Sleep 上限的那种平台,则写在 Zapier 教程.

这个循环要花掉多少次操作

Make.com 按操作计费,而一次操作就是一个模块对一个数据包运行一次。触发器无论返回多少内容都只算一次,但 Repeater 后面的每一个模块都会对每个数据包各跑一次,所以十次重复的一个 Sleep 加一次 HTTP 调用就是二十次操作,哪怕 token 在第二次尝试时就回来了。过滤器并不会让循环停下来,它只是拦住数据包不让它们往后走。

这个次数是固定的,不是一个「典型值」,正因如此,下面两个习惯才值得养成。第一个 Sleep 要设得够长,长到答案通常在第一次或第二次轮询时就已经就绪,因为这才是你能把重复次数设得很低的前提。另外,重复次数要按现实中的最坏情况来设,而不是按舒服的情况来设:十次重复、每次五秒,会在初始等待之外再加上五十秒,对 v2 来说绰绰有余。

识别本身完全不计量。CapSkip 跑在你自己的机器上,所以一次重试唯一的代价,就是 Make.com 为发起这次重试的那些模块记下的操作数。

第 4 步:把 token 和表单一起发出去

拿到 token 之后怎么用,取决于目标是什么。如果你要提交一个表单,就再加第三个 HTTP 模块,把 token 作为 g-recaptcha-response 字段和真正的表单字段一起带上。Turnstile 的字段名换成 cf-turnstile-response,而且识别工具还会返回它所使用的 user agent,挑战页面会坚持要在请求头里看到这个值。

token 会过期,reCAPTCHA v2 的窗口大约是从识别完成算起两分钟。把提交模块紧挨着放在过滤器后面。任何慢的动作,比如取一条记录或者拼一个请求体,都该放在识别之前,而不是夹在识别和提交之间。两种提交方式以及其中的时间要求,见 reCAPTCHA v2 识别页面.

常见错误及其含义

你所看到的原因修复
第一个模块报连接错误识别工具在回环地址或私有地址上把 CapSkip 切到 Server 模式,改用一个公网主机名
证书或 TLS 报错自签名证书,或者用了明文 HTTP在识别工具前面加一张公开受信任的证书
响应以一整个未解析的字符串返回HTTP 模块上的解析选项没打开把它打开,然后重新映射字段
ERROR_WRONG_USER_KEYkey 字段为空或者格式不对检查映射进请求里的那个值
ERROR_GOOGLEKEY传到识别工具的 sitekey 是空的或者是错的重新从线上页面读一次 sitekey
每一次重复都返回 CAPCHA_NOT_READY循环的时长比识别所需的时间还短把第一个 Sleep 调长,或者增加重复次数
第二次轮询回来时没有带着 token结果只能读取一次在轮询成功的那一次就把它映射出去,不要再取一次
表单拒绝了一个看起来没问题的 token它在提交执行之前就过期了把慢的模块挪到识别之前

常见问题

场景能通过 127.0.0.1 访问到识别工具吗?

Make.com 是托管产品,没有自托管版本,所以在场景里回环地址永远不是你的那台机器。如果你的自动化流程确实和识别工具跑在同一台机器上,那你说的其实是另一种工具。一个自托管的 n8n 实例能把流量留在本机设备上,一个脚本也可以,只要它调用的是 CapSkip SDK.

把识别工具暴露到互联网上安全吗?

只要你收窄能访问它的范围,就是安全的。打开密钥校验,未经认证的请求就会被拒绝;给这个场景单独发一个密钥,这样吊销它不会牵连别处;再把防火墙规则限制到你所在 Make.com 区域已公布的出口地址。前面那个 TLS 终结器意味着密钥永远不会以明文形式穿过网络。

为什么不用一次长 Sleep 代替循环?

因为单个 Sleep 的上限是 300 秒,也因为那样你只是在猜。固定的等待时间,要么每次运行都白白耗掉挂钟时间,要么在慢的那几次里什么都等不到,而且不管哪种情况都不会给你第二次机会。Repeater 给你的正是这些重试,而且只要有一次轮询拿到 token,它就会立刻到达提交模块,通常就是第二次轮询。循环本身仍然会把次数跑满,所以这样换来的是可靠性,而不是更少的账单。

场景做识别时需要代理吗?

通常不需要。reCAPTCHA、Turnstile 和极验(GeeTest)都支持代理,当目标站点把 token 和提交它的那个 IP 绑在一起时,代理才有意义。图片验证码根本不接受代理。代理参数要加在第一个 HTTP 模块上,也就是调用 in.php 的那一个;而且只有当你看到 token 明明及时送到却仍被拒绝时才加。

简短版结论

把 CapSkip 设为 Server 模式,前面加一个主机名和一张受信任的证书,然后在场景里接上四样东西:一个 HTTP 提交、一个 Sleep、一个后面挂着 Sleep 和 HTTP 轮询的 Repeater,以及一个只放行已完成结果的过滤器。整个过程不涉及任何代码步骤。同样这套流程,换成 Python、Node.js、PHP 或 C# 就浓缩成一次调用,这四种写法都在 CapSkip SDK 页面.

在把场景规模扩大之前,有件事值得知道。因为 CapSkip 是一个 验证码识别工具 ,跑在你已经拥有的硬件上,所以识别的次数永远不会出现在账单上。随着量增长的只有 Make.com 为它周围那些模块记下的操作数。