Skip to main content

captcha

Interact with challenge widgets in an authorized automation flow using checkbox clicks, slider drags, text OCR, and image-grid input. Verify completion with an application-specific condition.

来源信息

仓库
code-yeongyu/omowright
最近来源活动
2026年9月29日 08:55
检测到的 SKILL.md 语言
英语
星标
3
分支
2

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
captcha
description
Interact with challenge widgets in an authorized automation flow using checkbox clicks, slider drags, text OCR, and image-grid input. Verify completion with an application-specific condition.
# Captcha `createCaptcha(page, { ocr? })` provides input and OCR helpers, not a general CAPTCHA solver. `click` and `drag` return a compact snapshot tree string after settling. `readText` returns text or `null`. A snapshot, token, or disappearing widget alone does not prove that the application accepted the challenge. This is rung 4 of the ladder in `presets/visual-browse/SKILL.md`. Pin the viewport before measuring coordinates (`Emulation.setDeviceMetricsOverride` and `refreshViewportSize`), and measure again after scrolling, resizing, or reflow. ```js import { createCaptcha } from "omowright"; const captcha = createCaptcha(page); ``` ## Checkbox widgets `click(bounds)` clicks the **center**, not the left-center. Measure the actual checkbox bounds, or provide an explicit point within a measured widget rectangle. All bounds and points use absolute top-level viewport CSS pixels. Coordinates can target a visible control inside a frame without switching frames, but a cross-origin iframe's outer bounds do not locate its checkbox. Account for frame geometry; an opaque or missing frame in a snapshot is not evidence of no challenge. For an application-owned widget with a DOM-accessible checkbox: ```js const bounds = await page.evaluate(`(() => { const el = document.querySelector("#captcha-checkbox"); if (!el) throw new Error("Checkbox not found"); const r = el.getBoundingClientRect(); return { x: r.x, y: r.y, width: r.width, height: r.height }; })()`); await captcha.click(bounds, { point: { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 }, approachSteps: 12, settleMs: 0, }); const result = await captcha.waitFor({ // Replace with your application's authoritative acceptance condition. until: page => page.evaluate( `document.querySelector("#application-status")?.dataset.accepted === "true"` ), timeoutMs: 10000, pollMs: 100, }); if (result.outcome !== "matched") { throw new Error(`Acceptance not confirmed: ${result.outcome}`); } // Capture visual evidence separately; waitFor never returns a tree or image. const image = await page.screenshot({ type: "png" }); ``` `point` is optional; omit it to retain center targeting. `approachSteps` is an optional positive integer for intermediate pointer movement before clicking. Omitting it retains the direct click. Interpolation is not a human-likeness or acceptance guarantee. Bounds must have finite coordinates and positive finite dimensions; the point must be inside `[x, x + width)` and `[y, y + height)`. Invalid geometry is rejected before input, not clamped or coerced. ## Completion is separate from input `captcha.waitFor({ until, timeoutMs = 10000, pollMs = 100, signal } = {})` returns exactly `{ outcome: "matched" | "timed_out" | "cancelled", elapsedMs }`. It never clicks, takes a snapshot, or infers server acceptance. You can check an already-accepted application without sending input. `until` is required and called as `until(page, { signal: operationSignal })`; one-argument predicates also work. Only literal `true` matches, not a truthy string or object. The first check runs immediately; subsequent checks are serial, after `pollMs`, bounded by one monotonic deadline. Predicate errors before termination propagate unchanged. `timeoutMs` must be finite in `[0, 2147483647]`; `pollMs` must be finite in `(0, 2147483647]`. A supplied `signal` must be AbortSignal-compatible. Invalid arguments throw TypeError or RangeError without running the predicate; values are not coerced. At completion boundaries, cancellation takes priority over the deadline, and the deadline over a match. A pre-aborted signal runs no predicate and returns `cancelled`; a zero timeout runs no predicate and returns `timed_out` unless already aborted. Async predicates and delays are bounded by abort/deadline, without overlapping checks. The owned operation signal is aborted on every terminal exit; owned timers and external abort listeners are cleaned up. A non-cooperative predicate can remain pending after return; late rejection does not change the result or become an unhandled rejection. Cancellation cannot retract dispatched input or requests, or interrupt blocking synchronous code. ## Slider and puzzle drags ```js const tree = await captcha.drag({ x: 150, y: 300 }, { x: 450, y: 300 }, { steps: 40 }); ``` Endpoints must be finite viewport points. `steps` is a positive integer (default 20); it controls intermediate movement, not whether the application accepts the result. Mouse release is attempted even if movement fails. ## Text and number captchas ```js const text = await captcha.readText({ x: 100, y: 200, width: 200, height: 60 }); if (text !== null) await page.locator("input[name=captcha]").fill(text); ``` The built-in `macOSVisionOcr` uses macOS Vision via Swift. Elsewhere, inject an OCR function: `createCaptcha(page, { ocr: async (pngBuffer) => "recognized text" })`. `readText(bounds?)` screenshots a cropped region, or the whole viewport when bounds are absent, and returns OCR text or `null`, never a snapshot tree. Recognizing text is not proof of submission or acceptance. ## Image-grid challenges and diagnosis `page.annotatedScreenshot()` overlays numbered boxes on interactive elements. Use the image to identify targets and `createCua(page)` for coordinate input; verify the application's result separately after submission. `click` and `drag` accept finite supported timer milliseconds as `settleMs` (default 3000, including 0 to disable the settling delay). They still take a snapshot with `settleMs: 0`; that delay is not a completion check or an overall timeout. If targeting fails, re-measure geometry. If input lands but acceptance does not follow, inspect the application state rather than assuming extra steps, a longer delay, or a different engine will solve it. See [CAPTCHA quality and comparison](../../docs/captcha-quality.md) for the limits.
在 GitHub 查看