{
  "schemaVersion": "1.0",
  "item": {
    "slug": "capmonster",
    "name": "CapMonster CAPTCHA Solver",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/EasonC13/capmonster",
    "canonicalUrl": "https://clawhub.ai/EasonC13/capmonster",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/capmonster",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=capmonster",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "detect-captcha.js",
      "inject-token.js",
      "solve-recaptcha.sh"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/capmonster"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/capmonster",
    "agentPageUrl": "https://openagent3.xyz/skills/capmonster/agent",
    "manifestUrl": "https://openagent3.xyz/skills/capmonster/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/capmonster/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "CapMonster Cloud CAPTCHA Solver",
        "body": "Solve CAPTCHAs programmatically via CapMonster Cloud API during browser automation."
      },
      {
        "title": "API Info",
        "body": "Base URL: https://api.capmonster.cloud\nAPI Key: ${CAPMONSTER_API_KEY}\nDocs: https://docs.capmonster.cloud/\nPython Client: tools/capmonster-cloud/capmonster_api.py"
      },
      {
        "title": "Pricing (per 1000 solves)",
        "body": "TypePriceAvg TimereCAPTCHA v2$0.6010-30sreCAPTCHA v3$0.905-15shCaptcha$1.5010-30sCloudflare Turnstile$1.205-15sImage CAPTCHA$0.042-5s"
      },
      {
        "title": "Check Balance",
        "body": "curl -s -X POST https://api.capmonster.cloud/getBalance \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"clientKey\": \"${CAPMONSTER_API_KEY}\"}' | jq .balance"
      },
      {
        "title": "Using Python Client",
        "body": "import sys\nsys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')\nfrom capmonster_api import CapMonsterClient\n\nclient = CapMonsterClient(\"${CAPMONSTER_API_KEY}\")\n\n# Check balance\nprint(f\"Balance: ${client.get_balance()}\")\n\n# Solve reCAPTCHA v2\ntoken = client.solve_recaptcha_v2(\n    website_url=\"https://example.com/page-with-captcha\",\n    website_key=\"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-\"\n)"
      },
      {
        "title": "Step 1: Detect CAPTCHA on Page",
        "body": "Take a browser snapshot and check for CAPTCHA indicators:\n\n// Via browser action=act evaluate\nbrowser action=act profile=chrome request={\n  \"kind\": \"evaluate\",\n  \"fn\": \"(() => {\n    const indicators = {\n      recaptchaV2: !!document.querySelector('.g-recaptcha, [data-sitekey], iframe[src*=\\\"recaptcha\\\"]'),\n      recaptchaV3: !!document.querySelector('script[src*=\\\"recaptcha/api.js?render=\\\"]'),\n      hcaptcha: !!document.querySelector('.h-captcha, [data-hcaptcha-sitekey], iframe[src*=\\\"hcaptcha\\\"]'),\n      turnstile: !!document.querySelector('.cf-turnstile, [data-sitekey], iframe[src*=\\\"turnstile\\\"]')\n    };\n    return JSON.stringify(indicators);\n  })()\"\n}"
      },
      {
        "title": "Step 2: Extract Site Key",
        "body": "reCAPTCHA v2:\n\n// Option A: From data-sitekey attribute\ndocument.querySelector('[data-sitekey]')?.dataset.sitekey\n\n// Option B: From iframe src\ndocument.querySelector('iframe[src*=\"recaptcha\"]')?.src.match(/k=([^&]+)/)?.[1]\n\n// Option C: From grecaptcha object\nwindow.___grecaptcha_cfg?.clients?.[0]?.Y?.Y?.sitekey\n\nreCAPTCHA v3:\n\n// From script src\ndocument.querySelector('script[src*=\"recaptcha/api.js?render=\"]')?.src.match(/render=([^&]+)/)?.[1]\n\n// Or from grecaptcha config\nwindow.___grecaptcha_cfg?.clients?.[0]?.Y?.Y?.sitekey\n\nhCaptcha:\n\ndocument.querySelector('[data-hcaptcha-sitekey], .h-captcha[data-sitekey]')?.dataset.sitekey ||\ndocument.querySelector('[data-hcaptcha-sitekey]')?.getAttribute('data-hcaptcha-sitekey')\n\nCloudflare Turnstile:\n\ndocument.querySelector('.cf-turnstile[data-sitekey], [data-turnstile-sitekey]')?.dataset.sitekey"
      },
      {
        "title": "Step 3: Submit to CapMonster API",
        "body": "Using curl (shell):\n\n# Create task\nTASK_ID=$(curl -s -X POST https://api.capmonster.cloud/createTask \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"clientKey\": \"${CAPMONSTER_API_KEY}\",\n    \"task\": {\n      \"type\": \"RecaptchaV2TaskProxyless\",\n      \"websiteURL\": \"https://scholar.google.com/\",\n      \"websiteKey\": \"SITEKEY_HERE\"\n    }\n  }' | jq -r .taskId)\n\necho \"Task ID: $TASK_ID\"\n\nUsing Python:\n\nimport sys\nsys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')\nfrom capmonster_api import CapMonsterClient\n\nclient = CapMonsterClient(\"${CAPMONSTER_API_KEY}\")\n\n# For reCAPTCHA v2\ntoken = client.solve_recaptcha_v2(\n    website_url=\"https://scholar.google.com/\",\n    website_key=\"EXTRACTED_SITEKEY\"\n)\n\n# For reCAPTCHA v3\ntoken = client.solve_recaptcha_v3(\n    website_url=\"https://example.com/\",\n    website_key=\"EXTRACTED_SITEKEY\",\n    min_score=0.7,\n    page_action=\"submit\"  # Check page source for action name\n)\n\n# For hCaptcha\ntoken = client.solve_hcaptcha(\n    website_url=\"https://example.com/\",\n    website_key=\"EXTRACTED_SITEKEY\"\n)\n\n# For Turnstile\ntoken = client.solve_turnstile(\n    website_url=\"https://example.com/\",\n    website_key=\"EXTRACTED_SITEKEY\"\n)"
      },
      {
        "title": "Step 4: Poll for Solution",
        "body": "Using curl:\n\n# Poll until ready (max 120 seconds)\nfor i in {1..60}; do\n  RESULT=$(curl -s -X POST https://api.capmonster.cloud/getTaskResult \\\n    -H \"Content-Type: application/json\" \\\n    -d \"{\\\"clientKey\\\": \\\"${CAPMONSTER_API_KEY}\\\", \\\"taskId\\\": $TASK_ID}\")\n  \n  STATUS=$(echo \"$RESULT\" | jq -r .status)\n  \n  if [ \"$STATUS\" = \"ready\" ]; then\n    TOKEN=$(echo \"$RESULT\" | jq -r '.solution.gRecaptchaResponse // .solution.token')\n    echo \"Token: $TOKEN\"\n    break\n  fi\n  \n  echo \"Status: $STATUS, waiting...\"\n  sleep 2\ndone\n\nThe Python client handles polling automatically with solve_and_wait()."
      },
      {
        "title": "Step 5: Inject Solution into Page",
        "body": "reCAPTCHA v2/v3:\n\n// Via browser evaluate\nbrowser action=act profile=chrome request={\n  \"kind\": \"evaluate\",\n  \"fn\": \"(() => {\n    const token = 'CAPMONSTER_TOKEN_HERE';\n    \n    // Method 1: Set textarea value (most common)\n    const textarea = document.querySelector('#g-recaptcha-response, [name=\\\"g-recaptcha-response\\\"]');\n    if (textarea) {\n      textarea.value = token;\n      textarea.style.display = 'block';  // Some sites hide it\n    }\n    \n    // Method 2: Also set any iframe response\n    document.querySelectorAll('iframe[src*=\\\"recaptcha\\\"]').forEach(iframe => {\n      try {\n        const doc = iframe.contentDocument || iframe.contentWindow.document;\n        const ta = doc.querySelector('#g-recaptcha-response');\n        if (ta) ta.value = token;\n      } catch(e) {}\n    });\n    \n    // Method 3: Trigger callback if exists\n    if (typeof ___grecaptcha_cfg !== 'undefined') {\n      const clients = ___grecaptcha_cfg.clients;\n      for (let cid in clients) {\n        const client = clients[cid];\n        // Find callback\n        const callback = client?.Y?.Y?.callback || client?.Y?.callback;\n        if (typeof callback === 'function') {\n          callback(token);\n        }\n      }\n    }\n    \n    return 'Token injected';\n  })()\"\n}\n\nhCaptcha:\n\nbrowser action=act profile=chrome request={\n  \"kind\": \"evaluate\",\n  \"fn\": \"(() => {\n    const token = 'CAPMONSTER_TOKEN_HERE';\n    \n    // Set response textarea\n    const textarea = document.querySelector('[name=\\\"h-captcha-response\\\"], [name=\\\"g-recaptcha-response\\\"]');\n    if (textarea) textarea.value = token;\n    \n    // Trigger callback\n    if (typeof hcaptcha !== 'undefined') {\n      // Find widget ID\n      const widget = document.querySelector('.h-captcha');\n      const widgetId = widget?.dataset.hcaptchaWidgetId || 0;\n      // Some sites have custom callbacks\n    }\n    \n    return 'hCaptcha token injected';\n  })()\"\n}\n\nCloudflare Turnstile:\n\nbrowser action=act profile=chrome request={\n  \"kind\": \"evaluate\",\n  \"fn\": \"(() => {\n    const token = 'CAPMONSTER_TOKEN_HERE';\n    \n    // Set the hidden input\n    const input = document.querySelector('[name=\\\"cf-turnstile-response\\\"]');\n    if (input) input.value = token;\n    \n    // Also set any callback data attribute\n    const container = document.querySelector('.cf-turnstile');\n    if (container && container.dataset.callback) {\n      const callbackName = container.dataset.callback;\n      if (typeof window[callbackName] === 'function') {\n        window[callbackName](token);\n      }\n    }\n    \n    return 'Turnstile token injected';\n  })()\"\n}"
      },
      {
        "title": "Step 6: Submit the Form",
        "body": "After injecting the token, submit the form:\n\n// Click submit button\nbrowser action=act profile=chrome request={\"kind\":\"click\",\"ref\":\"submit button ref\"}\n\n// Or trigger form submission\nbrowser action=act profile=chrome request={\n  \"kind\": \"evaluate\",\n  \"fn\": \"document.querySelector('form').submit()\"\n}"
      },
      {
        "title": "Google Scholar Specific",
        "body": "Google Scholar uses invisible reCAPTCHA v2 that triggers on suspicious activity."
      },
      {
        "title": "Detection",
        "body": "// Check if blocked\nconst isBlocked = document.body.textContent.includes('unusual traffic') ||\n                  document.body.textContent.includes('我們的系統') ||\n                  !!document.querySelector('iframe[src*=\"recaptcha\"]');"
      },
      {
        "title": "Extract Site Key",
        "body": "// Scholar's recaptcha iframe\nconst iframe = document.querySelector('iframe[src*=\"recaptcha\"]');\nconst sitekey = iframe?.src.match(/k=([^&]+)/)?.[1];\n// Usually: 6LfwuyUTAAAAAOAmoS0fdqijC2PbbdH4kjq62Y1b"
      },
      {
        "title": "Solve and Submit",
        "body": "import sys\nsys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')\nfrom capmonster_api import CapMonsterClient\n\nclient = CapMonsterClient(\"${CAPMONSTER_API_KEY}\")\n\n# Scholar's known sitekey (may change)\ntoken = client.solve_recaptcha_v2(\n    website_url=\"https://scholar.google.com/scholar?q=test\",\n    website_key=\"6LfwuyUTAAAAAOAmoS0fdqijC2PbbdH4kjq62Y1b\"\n)\n\nprint(f\"Token: {token[:50]}...\")\n\nThen inject via browser automation."
      },
      {
        "title": "Image CAPTCHA",
        "body": "For traditional image CAPTCHAs (text recognition):\n\nimport base64\nimport sys\nsys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')\nfrom capmonster_api import CapMonsterClient\n\nclient = CapMonsterClient(\"${CAPMONSTER_API_KEY}\")\n\n# From file\ntext = client.solve_image_captcha(image_path=\"/tmp/captcha.png\")\n\n# From base64\nwith open(\"/tmp/captcha.png\", \"rb\") as f:\n    b64 = base64.b64encode(f.read()).decode()\ntext = client.solve_image_captcha(image_base64=b64)\n\nprint(f\"CAPTCHA text: {text}\")"
      },
      {
        "title": "All-in-One Shell Script",
        "body": "Save as solve-recaptcha.sh:\n\n#!/bin/bash\n# Usage: ./solve-recaptcha.sh <website_url> <sitekey>\n\nAPI_KEY=\"${CAPMONSTER_API_KEY}\"\nWEBSITE_URL=\"$1\"\nSITEKEY=\"$2\"\n\n# Create task\necho \"Creating task...\"\nRESPONSE=$(curl -s -X POST https://api.capmonster.cloud/createTask \\\n  -H \"Content-Type: application/json\" \\\n  -d \"{\n    \\\"clientKey\\\": \\\"$API_KEY\\\",\n    \\\"task\\\": {\n      \\\"type\\\": \\\"RecaptchaV2TaskProxyless\\\",\n      \\\"websiteURL\\\": \\\"$WEBSITE_URL\\\",\n      \\\"websiteKey\\\": \\\"$SITEKEY\\\"\n    }\n  }\")\n\nTASK_ID=$(echo \"$RESPONSE\" | jq -r .taskId)\nERROR_ID=$(echo \"$RESPONSE\" | jq -r .errorId)\n\nif [ \"$ERROR_ID\" != \"0\" ]; then\n  echo \"Error: $(echo \"$RESPONSE\" | jq -r .errorDescription)\"\n  exit 1\nfi\n\necho \"Task ID: $TASK_ID\"\n\n# Poll for result\necho \"Waiting for solution...\"\nfor i in {1..60}; do\n  RESULT=$(curl -s -X POST https://api.capmonster.cloud/getTaskResult \\\n    -H \"Content-Type: application/json\" \\\n    -d \"{\\\"clientKey\\\": \\\"$API_KEY\\\", \\\"taskId\\\": $TASK_ID}\")\n  \n  STATUS=$(echo \"$RESULT\" | jq -r .status)\n  \n  if [ \"$STATUS\" = \"ready\" ]; then\n    TOKEN=$(echo \"$RESULT\" | jq -r '.solution.gRecaptchaResponse')\n    COST=$(echo \"$RESULT\" | jq -r '.cost')\n    echo \"✅ Solved! Cost: \\$$COST\"\n    echo \"\"\n    echo \"TOKEN:\"\n    echo \"$TOKEN\"\n    exit 0\n  fi\n  \n  printf \".\"\n  sleep 2\ndone\n\necho \"\"\necho \"❌ Timeout after 120 seconds\"\nexit 1"
      },
      {
        "title": "Token Invalid / Expired",
        "body": "Tokens expire in ~2 minutes\nInject and submit immediately after receiving\nMake sure websiteURL matches the actual page URL"
      },
      {
        "title": "ERROR_CAPTCHA_UNSOLVABLE",
        "body": "Retry 2-3 times\nCheck if sitekey is correct\nPage may have additional protections"
      },
      {
        "title": "ERROR_RECAPTCHA_TIMEOUT",
        "body": "Network issue between CapMonster and target\nTry again, or use proxy version (RecaptchaV2Task)"
      },
      {
        "title": "Token Injected but Form Fails",
        "body": "Site may validate token server-side with IP check\nTry using proxy version with your IP\nSome sites need callback to be triggered"
      },
      {
        "title": "Finding the Callback",
        "body": "// Check grecaptcha config for callback\nJSON.stringify(___grecaptcha_cfg, (k, v) => typeof v === 'function' ? '[Function]' : v, 2)\n\n// Or check data-callback attribute\ndocument.querySelector('[data-callback]')?.dataset.callback"
      },
      {
        "title": "Best Practices",
        "body": "Extract sitekey fresh - Don't hardcode, sites may rotate\nUse correct URL - Must match the page showing CAPTCHA\nInject quickly - Tokens expire in ~120 seconds\nCheck for v3 - Some sites use v3 (invisible), need pageAction\nMonitor balance - Set up low-balance alerts\nRetry on failure - CapMonster may fail occasionally"
      },
      {
        "title": "Cost Estimation",
        "body": "Use CaseCAPTCHAs/dayMonthly CostLight (research)10~$0.18Medium (scraping)100~$1.80Heavy (automation)1000~$18.00\n\nCurrent balance is ~$10, good for ~16,000 reCAPTCHA v2 solves."
      }
    ],
    "body": "CapMonster Cloud CAPTCHA Solver\n\nSolve CAPTCHAs programmatically via CapMonster Cloud API during browser automation.\n\nAPI Info\nBase URL: https://api.capmonster.cloud\nAPI Key: ${CAPMONSTER_API_KEY}\nDocs: https://docs.capmonster.cloud/\nPython Client: tools/capmonster-cloud/capmonster_api.py\nPricing (per 1000 solves)\nType\tPrice\tAvg Time\nreCAPTCHA v2\t$0.60\t10-30s\nreCAPTCHA v3\t$0.90\t5-15s\nhCaptcha\t$1.50\t10-30s\nCloudflare Turnstile\t$1.20\t5-15s\nImage CAPTCHA\t$0.04\t2-5s\nQuick Reference\nCheck Balance\ncurl -s -X POST https://api.capmonster.cloud/getBalance \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"clientKey\": \"${CAPMONSTER_API_KEY}\"}' | jq .balance\n\nUsing Python Client\nimport sys\nsys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')\nfrom capmonster_api import CapMonsterClient\n\nclient = CapMonsterClient(\"${CAPMONSTER_API_KEY}\")\n\n# Check balance\nprint(f\"Balance: ${client.get_balance()}\")\n\n# Solve reCAPTCHA v2\ntoken = client.solve_recaptcha_v2(\n    website_url=\"https://example.com/page-with-captcha\",\n    website_key=\"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-\"\n)\n\nComplete Workflow: Browser Automation + CAPTCHA Solving\nStep 1: Detect CAPTCHA on Page\n\nTake a browser snapshot and check for CAPTCHA indicators:\n\n// Via browser action=act evaluate\nbrowser action=act profile=chrome request={\n  \"kind\": \"evaluate\",\n  \"fn\": \"(() => {\n    const indicators = {\n      recaptchaV2: !!document.querySelector('.g-recaptcha, [data-sitekey], iframe[src*=\\\"recaptcha\\\"]'),\n      recaptchaV3: !!document.querySelector('script[src*=\\\"recaptcha/api.js?render=\\\"]'),\n      hcaptcha: !!document.querySelector('.h-captcha, [data-hcaptcha-sitekey], iframe[src*=\\\"hcaptcha\\\"]'),\n      turnstile: !!document.querySelector('.cf-turnstile, [data-sitekey], iframe[src*=\\\"turnstile\\\"]')\n    };\n    return JSON.stringify(indicators);\n  })()\"\n}\n\nStep 2: Extract Site Key\n\nreCAPTCHA v2:\n\n// Option A: From data-sitekey attribute\ndocument.querySelector('[data-sitekey]')?.dataset.sitekey\n\n// Option B: From iframe src\ndocument.querySelector('iframe[src*=\"recaptcha\"]')?.src.match(/k=([^&]+)/)?.[1]\n\n// Option C: From grecaptcha object\nwindow.___grecaptcha_cfg?.clients?.[0]?.Y?.Y?.sitekey\n\n\nreCAPTCHA v3:\n\n// From script src\ndocument.querySelector('script[src*=\"recaptcha/api.js?render=\"]')?.src.match(/render=([^&]+)/)?.[1]\n\n// Or from grecaptcha config\nwindow.___grecaptcha_cfg?.clients?.[0]?.Y?.Y?.sitekey\n\n\nhCaptcha:\n\ndocument.querySelector('[data-hcaptcha-sitekey], .h-captcha[data-sitekey]')?.dataset.sitekey ||\ndocument.querySelector('[data-hcaptcha-sitekey]')?.getAttribute('data-hcaptcha-sitekey')\n\n\nCloudflare Turnstile:\n\ndocument.querySelector('.cf-turnstile[data-sitekey], [data-turnstile-sitekey]')?.dataset.sitekey\n\nStep 3: Submit to CapMonster API\n\nUsing curl (shell):\n\n# Create task\nTASK_ID=$(curl -s -X POST https://api.capmonster.cloud/createTask \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"clientKey\": \"${CAPMONSTER_API_KEY}\",\n    \"task\": {\n      \"type\": \"RecaptchaV2TaskProxyless\",\n      \"websiteURL\": \"https://scholar.google.com/\",\n      \"websiteKey\": \"SITEKEY_HERE\"\n    }\n  }' | jq -r .taskId)\n\necho \"Task ID: $TASK_ID\"\n\n\nUsing Python:\n\nimport sys\nsys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')\nfrom capmonster_api import CapMonsterClient\n\nclient = CapMonsterClient(\"${CAPMONSTER_API_KEY}\")\n\n# For reCAPTCHA v2\ntoken = client.solve_recaptcha_v2(\n    website_url=\"https://scholar.google.com/\",\n    website_key=\"EXTRACTED_SITEKEY\"\n)\n\n# For reCAPTCHA v3\ntoken = client.solve_recaptcha_v3(\n    website_url=\"https://example.com/\",\n    website_key=\"EXTRACTED_SITEKEY\",\n    min_score=0.7,\n    page_action=\"submit\"  # Check page source for action name\n)\n\n# For hCaptcha\ntoken = client.solve_hcaptcha(\n    website_url=\"https://example.com/\",\n    website_key=\"EXTRACTED_SITEKEY\"\n)\n\n# For Turnstile\ntoken = client.solve_turnstile(\n    website_url=\"https://example.com/\",\n    website_key=\"EXTRACTED_SITEKEY\"\n)\n\nStep 4: Poll for Solution\n\nUsing curl:\n\n# Poll until ready (max 120 seconds)\nfor i in {1..60}; do\n  RESULT=$(curl -s -X POST https://api.capmonster.cloud/getTaskResult \\\n    -H \"Content-Type: application/json\" \\\n    -d \"{\\\"clientKey\\\": \\\"${CAPMONSTER_API_KEY}\\\", \\\"taskId\\\": $TASK_ID}\")\n  \n  STATUS=$(echo \"$RESULT\" | jq -r .status)\n  \n  if [ \"$STATUS\" = \"ready\" ]; then\n    TOKEN=$(echo \"$RESULT\" | jq -r '.solution.gRecaptchaResponse // .solution.token')\n    echo \"Token: $TOKEN\"\n    break\n  fi\n  \n  echo \"Status: $STATUS, waiting...\"\n  sleep 2\ndone\n\n\nThe Python client handles polling automatically with solve_and_wait().\n\nStep 5: Inject Solution into Page\n\nreCAPTCHA v2/v3:\n\n// Via browser evaluate\nbrowser action=act profile=chrome request={\n  \"kind\": \"evaluate\",\n  \"fn\": \"(() => {\n    const token = 'CAPMONSTER_TOKEN_HERE';\n    \n    // Method 1: Set textarea value (most common)\n    const textarea = document.querySelector('#g-recaptcha-response, [name=\\\"g-recaptcha-response\\\"]');\n    if (textarea) {\n      textarea.value = token;\n      textarea.style.display = 'block';  // Some sites hide it\n    }\n    \n    // Method 2: Also set any iframe response\n    document.querySelectorAll('iframe[src*=\\\"recaptcha\\\"]').forEach(iframe => {\n      try {\n        const doc = iframe.contentDocument || iframe.contentWindow.document;\n        const ta = doc.querySelector('#g-recaptcha-response');\n        if (ta) ta.value = token;\n      } catch(e) {}\n    });\n    \n    // Method 3: Trigger callback if exists\n    if (typeof ___grecaptcha_cfg !== 'undefined') {\n      const clients = ___grecaptcha_cfg.clients;\n      for (let cid in clients) {\n        const client = clients[cid];\n        // Find callback\n        const callback = client?.Y?.Y?.callback || client?.Y?.callback;\n        if (typeof callback === 'function') {\n          callback(token);\n        }\n      }\n    }\n    \n    return 'Token injected';\n  })()\"\n}\n\n\nhCaptcha:\n\nbrowser action=act profile=chrome request={\n  \"kind\": \"evaluate\",\n  \"fn\": \"(() => {\n    const token = 'CAPMONSTER_TOKEN_HERE';\n    \n    // Set response textarea\n    const textarea = document.querySelector('[name=\\\"h-captcha-response\\\"], [name=\\\"g-recaptcha-response\\\"]');\n    if (textarea) textarea.value = token;\n    \n    // Trigger callback\n    if (typeof hcaptcha !== 'undefined') {\n      // Find widget ID\n      const widget = document.querySelector('.h-captcha');\n      const widgetId = widget?.dataset.hcaptchaWidgetId || 0;\n      // Some sites have custom callbacks\n    }\n    \n    return 'hCaptcha token injected';\n  })()\"\n}\n\n\nCloudflare Turnstile:\n\nbrowser action=act profile=chrome request={\n  \"kind\": \"evaluate\",\n  \"fn\": \"(() => {\n    const token = 'CAPMONSTER_TOKEN_HERE';\n    \n    // Set the hidden input\n    const input = document.querySelector('[name=\\\"cf-turnstile-response\\\"]');\n    if (input) input.value = token;\n    \n    // Also set any callback data attribute\n    const container = document.querySelector('.cf-turnstile');\n    if (container && container.dataset.callback) {\n      const callbackName = container.dataset.callback;\n      if (typeof window[callbackName] === 'function') {\n        window[callbackName](token);\n      }\n    }\n    \n    return 'Turnstile token injected';\n  })()\"\n}\n\nStep 6: Submit the Form\n\nAfter injecting the token, submit the form:\n\n// Click submit button\nbrowser action=act profile=chrome request={\"kind\":\"click\",\"ref\":\"submit button ref\"}\n\n// Or trigger form submission\nbrowser action=act profile=chrome request={\n  \"kind\": \"evaluate\",\n  \"fn\": \"document.querySelector('form').submit()\"\n}\n\nGoogle Scholar Specific\n\nGoogle Scholar uses invisible reCAPTCHA v2 that triggers on suspicious activity.\n\nDetection\n// Check if blocked\nconst isBlocked = document.body.textContent.includes('unusual traffic') ||\n                  document.body.textContent.includes('我們的系統') ||\n                  !!document.querySelector('iframe[src*=\"recaptcha\"]');\n\nExtract Site Key\n// Scholar's recaptcha iframe\nconst iframe = document.querySelector('iframe[src*=\"recaptcha\"]');\nconst sitekey = iframe?.src.match(/k=([^&]+)/)?.[1];\n// Usually: 6LfwuyUTAAAAAOAmoS0fdqijC2PbbdH4kjq62Y1b\n\nSolve and Submit\nimport sys\nsys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')\nfrom capmonster_api import CapMonsterClient\n\nclient = CapMonsterClient(\"${CAPMONSTER_API_KEY}\")\n\n# Scholar's known sitekey (may change)\ntoken = client.solve_recaptcha_v2(\n    website_url=\"https://scholar.google.com/scholar?q=test\",\n    website_key=\"6LfwuyUTAAAAAOAmoS0fdqijC2PbbdH4kjq62Y1b\"\n)\n\nprint(f\"Token: {token[:50]}...\")\n\n\nThen inject via browser automation.\n\nImage CAPTCHA\n\nFor traditional image CAPTCHAs (text recognition):\n\nimport base64\nimport sys\nsys.path.insert(0, '/Users/eason/clawd/tools/capmonster-cloud')\nfrom capmonster_api import CapMonsterClient\n\nclient = CapMonsterClient(\"${CAPMONSTER_API_KEY}\")\n\n# From file\ntext = client.solve_image_captcha(image_path=\"/tmp/captcha.png\")\n\n# From base64\nwith open(\"/tmp/captcha.png\", \"rb\") as f:\n    b64 = base64.b64encode(f.read()).decode()\ntext = client.solve_image_captcha(image_base64=b64)\n\nprint(f\"CAPTCHA text: {text}\")\n\nAll-in-One Shell Script\n\nSave as solve-recaptcha.sh:\n\n#!/bin/bash\n# Usage: ./solve-recaptcha.sh <website_url> <sitekey>\n\nAPI_KEY=\"${CAPMONSTER_API_KEY}\"\nWEBSITE_URL=\"$1\"\nSITEKEY=\"$2\"\n\n# Create task\necho \"Creating task...\"\nRESPONSE=$(curl -s -X POST https://api.capmonster.cloud/createTask \\\n  -H \"Content-Type: application/json\" \\\n  -d \"{\n    \\\"clientKey\\\": \\\"$API_KEY\\\",\n    \\\"task\\\": {\n      \\\"type\\\": \\\"RecaptchaV2TaskProxyless\\\",\n      \\\"websiteURL\\\": \\\"$WEBSITE_URL\\\",\n      \\\"websiteKey\\\": \\\"$SITEKEY\\\"\n    }\n  }\")\n\nTASK_ID=$(echo \"$RESPONSE\" | jq -r .taskId)\nERROR_ID=$(echo \"$RESPONSE\" | jq -r .errorId)\n\nif [ \"$ERROR_ID\" != \"0\" ]; then\n  echo \"Error: $(echo \"$RESPONSE\" | jq -r .errorDescription)\"\n  exit 1\nfi\n\necho \"Task ID: $TASK_ID\"\n\n# Poll for result\necho \"Waiting for solution...\"\nfor i in {1..60}; do\n  RESULT=$(curl -s -X POST https://api.capmonster.cloud/getTaskResult \\\n    -H \"Content-Type: application/json\" \\\n    -d \"{\\\"clientKey\\\": \\\"$API_KEY\\\", \\\"taskId\\\": $TASK_ID}\")\n  \n  STATUS=$(echo \"$RESULT\" | jq -r .status)\n  \n  if [ \"$STATUS\" = \"ready\" ]; then\n    TOKEN=$(echo \"$RESULT\" | jq -r '.solution.gRecaptchaResponse')\n    COST=$(echo \"$RESULT\" | jq -r '.cost')\n    echo \"✅ Solved! Cost: \\$$COST\"\n    echo \"\"\n    echo \"TOKEN:\"\n    echo \"$TOKEN\"\n    exit 0\n  fi\n  \n  printf \".\"\n  sleep 2\ndone\n\necho \"\"\necho \"❌ Timeout after 120 seconds\"\nexit 1\n\nTroubleshooting\nToken Invalid / Expired\nTokens expire in ~2 minutes\nInject and submit immediately after receiving\nMake sure websiteURL matches the actual page URL\nERROR_CAPTCHA_UNSOLVABLE\nRetry 2-3 times\nCheck if sitekey is correct\nPage may have additional protections\nERROR_RECAPTCHA_TIMEOUT\nNetwork issue between CapMonster and target\nTry again, or use proxy version (RecaptchaV2Task)\nToken Injected but Form Fails\nSite may validate token server-side with IP check\nTry using proxy version with your IP\nSome sites need callback to be triggered\nFinding the Callback\n// Check grecaptcha config for callback\nJSON.stringify(___grecaptcha_cfg, (k, v) => typeof v === 'function' ? '[Function]' : v, 2)\n\n// Or check data-callback attribute\ndocument.querySelector('[data-callback]')?.dataset.callback\n\nBest Practices\nExtract sitekey fresh - Don't hardcode, sites may rotate\nUse correct URL - Must match the page showing CAPTCHA\nInject quickly - Tokens expire in ~120 seconds\nCheck for v3 - Some sites use v3 (invisible), need pageAction\nMonitor balance - Set up low-balance alerts\nRetry on failure - CapMonster may fail occasionally\nCost Estimation\nUse Case\tCAPTCHAs/day\tMonthly Cost\nLight (research)\t10\t~$0.18\nMedium (scraping)\t100\t~$1.80\nHeavy (automation)\t1000\t~$18.00\n\nCurrent balance is ~$10, good for ~16,000 reCAPTCHA v2 solves."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/EasonC13/capmonster",
    "publisherUrl": "https://clawhub.ai/EasonC13/capmonster",
    "owner": "EasonC13",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/capmonster",
    "downloadUrl": "https://openagent3.xyz/downloads/capmonster",
    "agentUrl": "https://openagent3.xyz/skills/capmonster/agent",
    "manifestUrl": "https://openagent3.xyz/skills/capmonster/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/capmonster/agent.md"
  }
}