
Ethan Collins
Pattern Recognition Specialist

Skyvern 负责打开网页、填写表单并推进业务流程,而 CapSolver 负责返回 CAPTCHA 令牌。
直接安装官方 capsolver SDK 并调用 capsolver.solve() 以避免自行实现 createTask 和轮询逻辑。
一旦获得令牌,将其返回到当前浏览器页面,然后让 Skyvern 提交表单并验证结果。
Skyvern 是一个基于 Playwright、视觉模型和大型语言模型(LLMs)的 AI 浏览器自动化平台。Skyvern 可以理解网页中的文本、表单和交互元素,根据自然语言指令完成页面导航、按钮点击、内容输入、文件上传、信息提取和多步骤工作流等任务。这种方法降低了因页面结构变化导致的脚本维护成本,非常适合登录、表单提交、后台操作和数据收集等场景。
当自动化工作流遇到 CAPTCHA 挑战时,可以通过提供当前页面 URL、站点密钥和 CAPTCHA 类型等参数调用官方 CapSolver Python SDK。CapSolver 完成任务后,会返回相应的验证令牌。程序随后使用 Playwright 将此令牌写入当前页面的响应字段、JavaScript 回调或业务请求中。验证通过后,Skyvern 可以继续执行原始用户授权的任务,例如提交表单、进入下一页或检查最终操作结果。
Skyvern 当前需要 Python 3.11、3.12 或 3.13。安装 Skyvern、CapSolver SDK 和 Chromium:
pip install "skyvern[local]"
pip install --upgrade capsolver
python -m playwright install chromium
# pip install --upgrade capsolver
# export CAPSOLVER_API_KEY='...'
import capsolver
# capsolver.api_key = "..."
solution = capsolver.solve({
"type": "ReCaptchaV2TaskProxyLess",
"websiteURL": "https://www.google.com/recaptcha/api2/demo",
"websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
})
print(solution)
成功后,返回结果主要使用:
token = solution["gRecaptchaResponse"]
参数的作用:
websiteURL 和 websiteKey 必须与当前页面的实际配置一致。
以下是最小集成示例。Skyvern 首先打开页面并填写表单,然后通过官方 SDK 获取令牌,最后将令牌返回到页面以进行提交。
import asyncio
import capsolver
from skyvern import Skyvern
TARGET_URL = "https://www.google.com/recaptcha/api2/demo"
WEBSITE_KEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
async def inject_token(page, token: str):
await page.evaluate(
"""
(token) => {
const textarea = document.getElementById('g-recaptcha-response');
if (textarea) {
textarea.value = token;
}
}
""",
token,
)
async def main():
skyvern = Skyvern.local()
browser = await skyvern.launch_local_browser(headless=False)
page = await browser.get_working_page()
try:
await page.goto(TARGET_URL)
solution = await asyncio.to_thread(
capsolver.solve,
{
"type": "ReCaptchaV2TaskProxyLess",
"websiteURL": TARGET_URL,
"websiteKey": WEBSITE_KEY,
},
)
token = solution["gRecaptchaResponse"]
await inject_token(page, token)
await page.act("Submit")
await page.validate("Verification successful... Great!")
finally:
await browser.close()
CapSolver 仅负责返回令牌;它不会自动提交目标网站的业务表单。不同网站处理令牌的方式各不相同,常见方法包括:
写入 g-recaptcha-response 隐藏字段;
调用页面上配置的 JavaScript 回调;
将令牌作为业务接口参数提交。
示例中的 inject_token() 尝试同时处理隐藏字段和测试回调。在实际使用中,应根据您网站的前端实现调整此代码片段。
检查以下参数:
websiteURL 是否是当前页面地址?
websiteKey 是否来自当前站点?
获取令牌后页面是否刷新?
是否将令牌传递给了正确的页面回调或业务接口?
除了 reCAPTCHA,Skyvern 还可以与 CapSolver 配合处理标准的图像到文本 CAPTCHA。以 BotDetect CAPTCHA Demo 为例:CAPTCHA 图像元素 ID 是 demoCaptcha_CaptchaImage,结果输入框 ID 是 captchaCode,验证按钮 ID 是 validateCaptchaButton。

ImageToTextTask 需要将 CAPTCHA 图像转换为 Base64 并通过 body 参数提交。如果图像 src 是 Data URL,例如:
data:image/png;base64,iVBORw0KGgoAAA...
传递给 CapSolver 时,仅保留逗号后的 Base64 内容,不包括 data:image/...;base64, 前缀。与令牌类型任务不同,ImageToTextTask 直接返回识别结果,无需额外轮询 getTaskResult。
以下是完整的 Skyvern 集成示例:
import asyncio
import capsolver
from skyvern import Skyvern
TARGET_URL = "https://captcha.com/demos/features/captcha-demo.aspx"
async def main():
skyvern = Skyvern.local()
browser = await skyvern.launch_local_browser(headless=False)
page = await browser.get_working_page()
try:
await page.goto(TARGET_URL)
await page.locator("#demoCaptcha_CaptchaImage").wait_for()
# 读取 CAPTCHA 图像 Data URL。
image_src = await page.locator(
"#demoCaptcha_CaptchaImage"
).get_attribute("src")
if not image_src or "," not in image_src:
raise RuntimeError("未找到有效的 Base64 CAPTCHA 图像")
# 移除 Data URL 前缀,仅保留 Base64 数据。
base64_image = image_src.split(",", 1)[1]
solution = await asyncio.to_thread(
capsolver.solve,
{
"type": "ImageToTextTask",
"websiteURL": TARGET_URL,
"module": "common",
"body": base64_image,
},
)
captcha_text = solution["text"]
print("识别结果:", captcha_text)
await page.locator("#captchaCode").fill(captcha_text)
await page.locator("#validateCaptchaButton").click()
await page.wait_for_timeout(5000)
finally:
await browser.close()
if __name__ == "__main__":
asyncio.run(main())
代码执行过程可总结为:
Skyvern 打开 CAPTCHA 页面
-> 定位 #demoCaptcha_CaptchaImage
-> 提取并清理 Base64 图像数据
-> 调用 capsolver.solve(ImageToTextTask)
-> 读取 solution["text"]
-> 填入 #captchaCode
-> 点击 #validateCaptchaButton
module 是一个可选参数;默认使用 common。如果 CAPTCHA 仅包含数字,可以使用 number;对于某些特殊样式,也可以根据 CapSolver 文档选择相应的独立模型以提高识别准确率。

例如,当仅识别数字 CAPTCHA 时,可以将任务参数更改为:
solution = capsolver.solve({
"type": "ImageToTextTask",
"module": "number",
"images": [base64_image],
})
answers = solution["answers"]
number 模型支持一次性提交多张图像,images 可以包含最多 9 个 Base64 字符串。有关其他模型名称和适用图像类型的详细信息,请参阅 官方 CapSolver ImageToTextTask 文档。
选择适合 AI 浏览器自动化的技术方案取决于任务复杂度、页面变化频率以及目标网站的验证机制。传统的工具如 Selenium 和 Playwright 适用于结构稳定、操作路径清晰的自动化工作流。Skyvern 在此基础上引入了视觉模型和 LLM,使其更适合页面结构频繁变化、需要语义理解或涉及多步骤操作的网页任务。由于 Skyvern 基于 Playwright 控制浏览器,可以通过自然语言完成页面导航、表单填写、按钮点击和数据提取。当流程遇到 CAPTCHA 挑战时,开发者可以结合官方 CapSolver SDK 获取验证令牌,然后将结果填写回当前页面,使 Skyvern 能够继续后续操作,如表单提交、页面跳转和结果验证。通过结合 Skyvern 和 CapSolver,开发者可以构建更灵活、可维护且可扩展的浏览器自动化工作流,降低传统选择器的维护成本,同时提高复杂网页任务的执行效率和稳定性。明确授权范围、保护 API 密钥以及验证和记录自动化结果是相关项目稳定运行的重要前提。
领取 CapSolver 奖励代码
立即提升您的自动化预算!
在充值 CapSolver 账户时使用奖励代码 CAP26,每次充值可额外获得 5% 奖励——无限制。
立即在您的 CapSolver 仪表板 中领取
Q1: 如何处理 iframe 中的 CAPTCHA?
A1: 在注入令牌前,先使用 page.frame_locator('iframe_selector') 切换到 iframe 上下文。确保发送给 CapSolver 的 websiteURL 是父页面地址,而不是 iframe 地址。
Q2: 如果网站使用自定义 JavaScript 回调怎么办?
A2: 识别回调函数名(例如 onCaptchaResolved),然后通过 Playwright 执行:await page.evaluate("onCaptchaResolved(token)", token)。
Q3: 如何提高 ImageToText 识别率?
A3: 使用特定的 module 参数(如数字 CAPTCHA 使用 number),并确保提取的 Base64 图像清晰且分辨率高。
Q4: 如何处理 API 密钥安全?
A4: 千万不要硬编码 API 密钥。使用环境变量(例如 os.getenv("CAPSOLVER_API_KEY"))安全加载。
Q5: 是否应该实现重试机制?
A5: 是的,使用 tenacity 等库实现 capsolver.solve() 的指数退避重试,以处理临时网络或服务问题。
Q6: 令牌会过期吗?
A6: CAPTCHA 令牌会快速过期(例如 2 分钟)。在从 CapSolver 接收令牌后立即注入并提交。
Q7: Skyvern 能否自动处理不同类型的 CAPTCHA?
A7: 可以,您可以使用 Skyvern 的视觉能力首先识别 CAPTCHA 类型,然后动态构建适当的 CapSolver 负载(例如在 ReCaptchaV2TaskProxyLess 和 ImageToTextTask 之间切换)。
Q8: Skyvern 的视觉能力还有哪些其他用途?
A8: 它可以实现动态元素定位(无需固定 ID 找到 CAPTCHA)、视觉后提交验证(检查成功消息)以及视觉错误检测,以实现更智能的重试。