DEV Community

luisgustvo
luisgustvo

Posted on

Add a Controlled CapSolver Step to a Skyvern Browser Workflow

Skyvern can navigate a page and act from natural-language instructions. CapSolver can return a CAPTCHA result through its SDK. The clean integration is a small deterministic bridge between them.

Use this only for systems you own or are explicitly authorized to automate.

1. Install the SDKs

Skyvern’s current pip quickstart supports Python 3.11–3.13:

python -m venv .venv
source .venv/bin/activate

pip install "skyvern[all]"
pip install --upgrade capsolver
python -m playwright install chromium
Enter fullscreen mode Exit fullscreen mode

Load credentials outside source control:

export CAPSOLVER_API_KEY="set-this-in-your-secret-manager"
Enter fullscreen mode Exit fullscreen mode

2. Understand the boundary

Skyvern should own:

  • navigation;
  • semantic element interaction;
  • natural-language actions;
  • result validation.

Application code should own:

  • target authorization;
  • CapSolver credentials;
  • task parameters;
  • browser-session continuity;
  • token or text handoff;
  • retry limits;
  • final assertions.

3. Call the documented reCAPTCHA v2 task

import capsolver

solution = capsolver.solve({
    "type": "ReCaptchaV2TaskProxyLess",
    "websiteURL": "https://www.google.com/recaptcha/api2/demo",
    "websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
})

token = solution["gRecaptchaResponse"]
Enter fullscreen mode Exit fullscreen mode

Replace the demo values only with parameters from your authorized page.

4. Hand the token to the current page

async def inject_token(page, token: str) -> None:
    await page.evaluate(
        """
        (token) => {
            const textarea = document.getElementById('g-recaptcha-response');
            if (!textarea) {
                throw new Error('g-recaptcha-response field not found');
            }
            textarea.value = token;
            textarea.dispatchEvent(new Event('change', { bubbles: true }));
        }
        """,
        token,
    )
Enter fullscreen mode Exit fullscreen mode

Not every frontend uses this field. Some owned applications use a configured callback or application request. Implement the method expected by that application rather than asking the model to guess.

5. Continue with Skyvern

Skyvern’s current SDK documents AI-assisted page commands such as:

await page.act("Submit the form")
passed = await page.validate(
    "The authorized test reached the expected successful result"
)
if not passed:
    raise RuntimeError("Final validation failed")
Enter fullscreen mode Exit fullscreen mode

The final validation is mandatory. A returned token is an intermediate result.

6. Add ImageToTextTask

image_src = await page.locator("#demoCaptcha_CaptchaImage").get_attribute("src")
if not image_src or "," not in image_src:
    raise RuntimeError("A valid Base64 CAPTCHA image was not found")

base64_image = image_src.split(",", 1)[1]

solution = capsolver.solve({
    "type": "ImageToTextTask",
    "websiteURL": TARGET_URL,
    "module": "common",
    "body": base64_image,
})

captcha_text = solution["text"]
Enter fullscreen mode Exit fullscreen mode

Then fill the expected input, submit, and verify:

await page.locator("#captchaCode").fill(captcha_text)
await page.locator("#validateCaptchaButton").click()
Enter fullscreen mode Exit fullscreen mode

Check the current ImageToTextTask documentation before selecting optional recognition modules.

7. Handle failures deliberately

If the page rejects the result:

  1. confirm the page URL and site key;
  2. check whether navigation changed the page;
  3. verify the expected field or callback;
  4. preserve the same browser session;
  5. inspect the final assertion;
  6. stop when the retry budget is exhausted.

Never log the API key, cookies, or raw verification result.

8. Put it together

Skyvern navigation
→ authorization check
→ CapSolver SDK
→ deterministic page handoff
→ Skyvern action
→ application verification
Enter fullscreen mode Exit fullscreen mode

This structure lets the AI layer handle changing interfaces without giving it control over secrets or unrestricted challenge handling.

Resources:

Top comments (0)