
Anh Tuan
Data Science Expert

detect, get_captcha_info hoặc solve_on_page của CapSolver Core tại các ranh giới phục hồi xác định.Bộ khung phục hồi trình duyệt AI là lớp chạy thời gian thực giữ cho nhiệm vụ trình duyệt được kiểm soát khi trạng thái trang thay đổi bất ngờ. Mô hình có thể quyết định bước kinh doanh tiếp theo, nhưng bộ khung nên sở hữu ngữ cảnh Playwright, chính sách host được phê duyệt, điểm kiểm tra điều hướng, phân loại trạng thái trang, phục hồi thách thức được hỗ trợ, giới hạn lặp lại, dấu vết, hình ảnh chụp màn hình và dọn dẹp. CapSolver phù hợp trong lớp này như một khả năng phục hồi xác định: capsolver-core có thể phát hiện các thách thức được hỗ trợ, đọc tham số, giải quyết chúng và điền kết quả trở lại cùng trang. Sau đó bộ khung xác minh rằng trạng thái ứng dụng mong muốn đã trở lại trước khi cho phép tác nhân tiếp tục. Hướng dẫn này xây dựng mô hình chính sách, máy trạng thái, quản lý ngữ cảnh bất đồng bộ, hàm phục hồi, trình ghi tài sản, các khung OpenTelemetry, kiểm thử và kiểm soát sản xuất cho tự động hóa trình duyệt được ủy quyền đáng tin cậy.
Bộ khung không phải là mô hình và cũng không phải là trình điều khiển trình duyệt riêng lẻ. Nó là mặt phẳng điều khiển giữa chúng.
Mục tiêu kinh doanh từ tác nhân
↓
Bộ khung phục hồi trình duyệt
├─ chính sách mục tiêu
├─ ngữ cảnh Playwright
├─ bộ phân loại trạng thái
├─ kho lưu trữ điểm kiểm tra
├─ phục hồi CapSolver
├─ ngân sách lặp lại
├─ dấu vết + tài sản
└─ dọn dẹp
↓
Hành động trang được phê duyệt hoặc xem xét của người vận hành
Tài liệu fixture của Playwright nhấn mạnh các fixture trang và ngữ cảnh trình duyệt cô lập, thiết lập và dọn dẹp tái sử dụng, khả năng kết hợp và gắn kết gỡ lỗi tự động. Các thuộc tính này chuyển trực tiếp thành một bộ khung sản xuất.
Tài liệu SDK Core của CapSolver xác định bốn giai đoạn trình duyệt hữu ích: detect, get_captcha_info, solve và solve_on_page.
Mô hình có thể quyết định mở trang sản phẩm đã biết hoặc đọc trạng thái công khai. Bộ khung quyết định xem host được yêu cầu có được phép, trang hiện tại có mong muốn, phục hồi có được hỗ trợ và ngân sách lặp lại còn tồn tại hay không.
| Quyết định | Người sở hữu | Lý do |
|---|---|---|
| Bước kinh doanh tiếp theo | Tác nhân hoặc quy trình | Yêu cầu ngữ cảnh nhiệm vụ |
| Quyền truy cập host và đường dẫn | Chính sách bộ khung | Phải xác định |
| Phân loại trạng thái trang | Bộ phân loại bộ khung | Phải sử dụng bằng chứng DOM/lưới mạng đáng tin cậy |
| Gọi phục hồi thách thức | Bộ khung | Yêu cầu bí mật và đối tượng trình duyệt |
| Xử lý token/cookie | Bộ khung | Dữ liệu thời gian chạy nhạy cảm |
| Tiếp tục hay xem xét | Máy trạng thái bộ khung | Đảm bảo phục hồi có giới hạn |
| Gửi cuối cùng | Người dùng hoặc dịch vụ chuyên dụng | Hành động có tác động lớn |
Hướng dẫn CapSolver cho các tác nhân AI giải thích cùng phân chia lao động: mô hình xử lý suy luận, trong khi các lớp CapSolver thực hiện công việc thách thức được hỗ trợ.
Bắt đầu với chính sách hẹp cho các host được phê duyệt, đường dẫn, hành động và ngân sách.
from dataclasses import dataclass, field
from urllib.parse import urlparse
@dataclass(frozen=True)
class TargetPolicy:
allowed_hosts: set[str]
allowed_path_prefixes: tuple[str, ...]
max_navigations: int = 20
max_recovery_attempts: int = 1
capture_screenshots: bool = True
capture_html: bool = False
allow_form_submission: bool = False
def validate_url(self, url: str) -> None:
parsed = urlparse(url)
if parsed.scheme != "https":
raise PermissionError("Chỉ các mục tiêu HTTPS được phép")
if parsed.hostname not in self.allowed_hosts:
raise PermissionError("Host nằm ngoài chính sách được phê duyệt")
if not parsed.path.startswith(self.allowed_path_prefixes):
raise PermissionError("Đường dẫn nằm ngoài chính sách được phê duyệt")
Sử dụng chính sách cụ thể cho từng khách hàng. Không duy trì danh sách cho phép toàn cầu cho các khách hàng hoặc dự án không liên quan.
Câu hỏi thường gặp về AI và tự động hóa của CapSolver cung cấp bối cảnh tích hợp, trong khi Câu hỏi thường gặp về quét web của CapSolver đề cập đến quy trình dữ liệu công khai có trách nhiệm.
Một bộ khung phục hồi nên sử dụng các trạng thái rõ ràng thay vì vòng lặp "thử lại" không giới hạn.
from enum import Enum
class BrowserState(str, Enum):
EXPECTED_PAGE = "expected_page"
SUPPORTED_CHALLENGE = "supported_challenge"
UNKNOWN_PAGE = "unknown_page"
RECOVERING = "recovering"
RECOVERED = "recovered"
REVIEW_REQUIRED = "review_required"
FAILED = "failed"
Các chuyển tiếp được phép có thể được biểu diễn dưới dạng dữ liệu:
ALLOWED_TRANSITIONS = {
BrowserState.EXPECTED_PAGE: {
BrowserState.EXPECTED_PAGE,
BrowserState.SUPPORTED_CHALLENGE,
BrowserState.UNKNOWN_PAGE,
},
BrowserState.SUPPORTED_CHALLENGE: {
BrowserState.RECOVERING,
BrowserState.REVIEW_REQUIRED,
},
BrowserState.RECOVERING: {
BrowserState.RECOVERED,
BrowserState.REVIEW_REQUIRED,
BrowserState.FAILED,
},
BrowserState.RECOVERED: {
BrowserState.EXPECTED_PAGE,
BrowserState.REVIEW_REQUIRED,
},
}
Xác minh mọi chuyển tiếp. Điều này làm cho các vòng lặp trở nên rõ ràng và có thể kiểm thử.
Điểm kiểm tra ghi lại thông tin mô tả an toàn cần thiết để xác định xem quy trình có tiếp tục đúng hay không.
from dataclasses import dataclass
from datetime import datetime, timezone
@dataclass
class BrowserCheckpoint:
url: str
title: str
expected_selector: str | None
navigation_index: int
recovery_attempts: int
observed_at: str
async def checkpoint(page, expected_selector, nav_index, attempts):
return BrowserCheckpoint(
url=page.url,
title=await page.title(),
expected_selector=expected_selector,
navigation_index=nav_index,
recovery_attempts=attempts,
observed_at=datetime.now(timezone.utc).isoformat(),
)
Không lưu trữ trạng thái lưu trữ, cookie, mật khẩu, token hoặc giá trị biểu mẫu đầy đủ trong điểm kiểm tra.
Sử dụng bằng chứng DOM đáng tin cậy, tiêu đề, URL và các lựa chọn mong muốn. Không bao giờ yêu cầu mô hình suy diễn trạng thái trang từ hình ảnh chụp màn hình duy nhất.
async def classify_page(page, expected_selector: str) -> BrowserState:
if await page.locator(expected_selector).count():
return BrowserState.EXPECTED_PAGE
title = (await page.title()).strip().lower()
html = (await page.content()).lower()
challenge_markers = (
"just a moment...",
"challenge-platform",
"cf-chl-",
)
if any(marker in title or marker in html for marker in challenge_markers):
return BrowserState.SUPPORTED_CHALLENGE
return BrowserState.UNKNOWN_PAGE
Sử dụng các ký hiệu cụ thể cho mục tiêu và fixture được kiểm soát. Một tập ký hiệu là heuristics định tuyến, không phải quyền truy cập.
Câu hỏi thường gặp về giải CAPTCHA của CapSolver giải thích các quy trình thách thức được hỗ trợ, và Câu hỏi thường gặp về lỗi của CapSolver giúp phân loại lỗi.
SDK Core chính thức khuyên dùng quản lý ngữ cảnh bất đồng bộ để kết nối HTTP được tái sử dụng và giải phóng đúng cách.
import os
from capsolver_core import create_capsolver
def create_recovery_client():
return create_capsolver(
api_key=os.environ["CAPSOLVER_API_KEY"],
default_timeout=120,
polling_interval=5,
request_timeout_ms=30000,
source="ai-browser-recovery-harness",
version="1.0.0",
)
Không tạo client mới cho mỗi lần kiểm tra DOM. Giữ một client cho chu kỳ bộ khung và đóng nó trong quá trình dọn dẹp.
Sử dụng detect và get_captcha_info để chẩn đoán, sau đó solve_on_page cho luồng trình duyệt toàn diện.
from capsolver_core import SolveOnPageOptions
async def recover_supported_challenge(
cap,
page,
policy: TargetPolicy,
recovery_attempts: int,
) -> dict:
policy.validate_url(page.url)
if recovery_attempts >= policy.max_recovery_attempts:
return {
"success": False,
"state": BrowserState.REVIEW_REQUIRED,
"reason": "ngân sách phục hồi đã hết",
}
detected = await cap.detect(page)
if not detected:
return {
"success": False,
"state": BrowserState.REVIEW_REQUIRED,
"reason": "không phát hiện thách thức được hỗ trợ",
}
infos = await cap.get_captcha_info(page)
results = await cap.solve_on_page(
page,
options=SolveOnPageOptions(
autofill=True,
throw_on_error=False,
timeout=120,
polling_interval=5,
),
)
errors = [item.error for item in results if item.error]
filled = bool(results) and all(item.filled for item in results)
return {
"success": filled and not errors,
"state": (
BrowserState.RECOVERED
if filled and not errors
else BrowserState.REVIEW_REQUIRED
),
"detected_count": len(detected),
"info_count": len(infos),
"result_count": len(results),
"errors": errors,
}
Giữ nguyên đối tượng page ban đầu. Điểm của solve_on_page là phát hiện, giải quyết và điền vào trong phiên trình duyệt hiện tại.
Một phản hồi công cụ thành công không chứng minh rằng trang ứng dụng mong muốn đã trở lại.
async def verify_recovery(
page,
expected_selector: str,
timeout_ms: int = 15000,
) -> bool:
try:
await page.locator(expected_selector).wait_for(
state="visible",
timeout=timeout_ms,
)
return True
except Exception:
return False
Sau khi phục hồi, phân loại lại trang. Nếu thách thức vẫn tồn tại hoặc lựa chọn mong muốn không có, dừng lại và yêu cầu xem xét.
async def recover_and_verify(cap, page, policy, expected_selector, attempts):
result = await recover_supported_challenge(
cap=cap,
page=page,
policy=policy,
recovery_attempts=attempts,
)
if not result["success"]:
return result
if not await verify_recovery(page, expected_selector):
return {
"success": False,
"state": BrowserState.REVIEW_REQUIRED,
"reason": "trang mong muốn không trở lại sau khi phục hồi",
}
return {
"success": True,
"state": BrowserState.EXPECTED_PAGE,
"reason": "trang đã phục hồi và xác minh",
}
Sử dụng quản lý ngữ cảnh bất đồng bộ để đảm bảo dọn dẹp.
from contextlib import asynccontextmanager
from playwright.async_api import async_playwright
@dataclass
class BrowserHarness:
policy: TargetPolicy
playwright: object
browser: object
context: object
page: object
capsolver: object
navigation_count: int = 0
recovery_attempts: int = 0
@asynccontextmanager
async def browser_recovery_harness(policy: TargetPolicy):
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=True)
context = await browser.new_context()
page = await context.new_page()
async with create_recovery_client() as cap:
harness = BrowserHarness(
policy=policy,
playwright=playwright,
browser=browser,
context=context,
page=page,
capsolver=cap,
)
try:
yield harness
finally:
await context.close()
await browser.close()
Mô hình hoặc quy trình nhận được các phương pháp được kiểm soát, không phải quyền truy cập trình duyệt không giới hạn.
async def safe_navigate(
harness: BrowserHarness,
url: str,
expected_selector: str,
) -> dict:
harness.policy.validate_url(url)
if harness.navigation_count >= harness.policy.max_navigations:
return {
"success": False,
"state": BrowserState.REVIEW_REQUIRED,
"reason": "ngân sách điều hướng đã hết",
}
harness.navigation_count += 1
await harness.page.goto(url, wait_until="domcontentloaded")
state = await classify_page(harness.page, expected_selector)
if state == BrowserState.EXPECTED_PAGE:
return {"success": True, "state": state}
if state == BrowserState.SUPPORTED_CHALLENGE:
result = await recover_and_verify(
cap=harness.capsolver,
page=harness.page,
policy=harness.policy,
expected_selector=expected_selector,
attempts=harness.recovery_attempts,
)
harness.recovery_attempts += 1
return result
return {
"success": False,
"state": BrowserState.REVIEW_REQUIRED,
"reason": "trạng thái trang không xác định",
}
Tác nhân có thể yêu cầu safe_navigate, nhưng bộ khung sở hữu chính sách và đường phục hồi.
Hướng dẫn quản lý quan sát cho GenAI của OpenTelemetry mô tả các dấu vết cho các hoạt động mô hình và công cụ. Nó cũng lưu ý rằng nội dung đầy đủ của prompt và công cụ có thể chứa dữ liệu nhạy cảm. Mặc định sử dụng các khung chỉ có thông tin mô tả.
from opentelemetry import trace
tracer = trace.get_tracer("capsolver.browser_harness")
async def traced_safe_navigate(harness, url, expected_selector):
with tracer.start_as_current_span("browser.safe_navigate") as span:
span.set_attribute("browser.target_host", url.split("/")[2])
span.set_attribute("browser.navigation_index", harness.navigation_count + 1)
span.set_attribute("browser.recovery_attempts", harness.recovery_attempts)
result = await safe_navigate(harness, url, expected_selector)
span.set_attribute("browser.outcome", str(result.get("state")))
span.set_attribute("browser.success", bool(result.get("success")))
return result
Không gắn thẻ token, cookie, khóa API, thông tin xác thực proxy, trạng thái lưu trữ, nội dung prompt hoặc HTML trang đầy đủ vào các span.
Hình ảnh chụp màn hình và HTML có thể chứa dữ liệu cá nhân hoặc bí mật. Chỉ thu thập chúng khi chính sách cho phép, che đi nơi có thể và lưu trữ các tham chiếu có thời hạn.
from pathlib import Path
import secrets
async def capture_failure_artifacts(harness, directory: Path) -> dict:
artifact_id = secrets.token_hex(12)
screenshot = directory / f"{artifact_id}.png"
await harness.page.screenshot(
path=str(screenshot),
full_page=False,
)
return {
"artifact_id": artifact_id,
"screenshot_path": str(screenshot),
"url": harness.page.url,
"title": await harness.page.title(),
}
Sử dụng giới hạn lưu trữ và kiểm soát truy cập. Tránh chụp màn hình toàn trang khi chỉ cần trạng thái cấp cao.
Bài viết blog về tự động hóa trình duyệt của CapSolver chứa các mẫu triển khai liên quan, và hướng dẫn mở rộng Chrome của CapSolver có thể giúp các nhóm kiểm tra tham số widget được hỗ trợ trong quá trình phát triển.
Sử dụng các ngữ cảnh trình duyệt tách biệt và các trang được kiểm soát. Các fixture của Playwright cung cấp thiết lập và dọn dẹp có thể tái sử dụng.
import pytest
@pytest.mark.asyncio
async def test_unknown_host_is_rejected():
policy = TargetPolicy(
allowed_hosts={"staging.example.com"},
allowed_path_prefixes=("/qa/",),
)
with pytest.raises(PermissionError):
policy.validate_url("https://other.example.net/qa/test")
@pytest.mark.asyncio
async def test_recovery_budget_is_bounded(fake_cap, fake_page):
policy = TargetPolicy(
allowed_hosts={"staging.example.com"},
allowed_path_prefixes=("/qa/",),
max_recovery_attempts=1,
)
result = await recover_supported_challenge(
cap=fake_cap,
page=fake_page,
policy=policy,
recovery_attempts=1,
)
assert result["state"] == BrowserState.REVIEW_REQUIRED
assert result["reason"] == "recovery budget exhausted"
Tạo các fixture cho trường hợp không có thách thức, thách thức được hỗ trợ, giao diện không xác định, điền lại thành công, thất bại giải quyết, vòng lặp thách thức sau khôi phục, và thiếu lựa chọn mong đợi.
| Chỉ số | Mục đích |
|---|---|
| Tỷ lệ trang mong đợi | Đo lường điều hướng bình thường thành công |
| Tỷ lệ phát hiện thách thức | Thể hiện mức độ khó khăn từ tên miền được phê duyệt |
| Tỷ lệ khôi phục thành công | Đo lường kết quả khôi phục được hỗ trợ |
| Tỷ lệ vòng lặp thách thức | Phát hiện trạng thái giao diện lặp lại |
| Tỷ lệ trang không xác định | Phát hiện thay đổi bố cục, xác thực hoặc chính sách |
| Độ trễ khôi phục P95 | Theo dõi độ trễ ảnh hưởng đến người dùng |
| Tỷ lệ yêu cầu xem xét của điều phối viên | Đo lường khối lượng công việc chưa được giải quyết |
| Tỷ lệ thu thập tài nguyên thất bại | Phát hiện ghi nhật ký thất bại quá mức |
Phân chia chỉ số theo chính sách mục tiêu, tuyến đường, phiên bản trình duyệt, loại thách thức và phiên bản bộ khung. Không đánh dấu thất bại khôi phục thách thức là thất bại tác vụ kinh doanh mà không giữ lại cả hai chiều.
Mã ưu đãi: Sử dụng mã WEBS tại Bảng điều khiển CapSolver để nhận thêm 5% ưu đãi cho mỗi lần nạp tiền.
| Phương pháp | Quyền sở hữu trình duyệt | Kiểm soát khôi phục | Trường hợp sử dụng tốt nhất |
|---|---|---|---|
| Truy cập trình duyệt của agent trực tiếp | Runtime của agent | Phụ thuộc vào lời nhắc | Chỉ dành cho các mô hình thử nghiệm rủi ro thấp |
| Hành động cụ thể của khung | Khung agent | Bao bọc công cụ | Tích hợp nhanh |
| Bộ khôi phục độc lập | Lớp kiểm soát độc lập | Máy trạng thái xác định | Tín nhiệm và quản trị sản xuất |
| Khôi phục chỉ dành cho con người | Điều phối viên | Thủ công | Các quy trình không được hỗ trợ hoặc rủi ro cao |
Một bộ khung độc lập yêu cầu nhiều công việc kỹ thuật, nhưng tạo ra một lớp chính sách và quan sát có thể phục vụ nhiều khung agent.
Trang sản phẩm của CapSolver liệt kê các danh mục giải pháp được hỗ trợ, trong khi blog AI của CapSolver đề cập đến các ví dụ khung agent có thể gọi hành động của bộ khung.
Sử dụng bộ khung khôi phục trình duyệt chỉ trên các hệ thống bạn sở hữu, kiểm thử hoặc có sự cho phép rõ ràng để tự động hóa. Việc giải quyết thách thức thành công không cấp quyền truy cập nội dung riêng, bỏ qua ranh giới xác thực, vượt quá giới hạn tốc độ hoặc thực hiện giao dịch. Giữ bộ khung ở phạm vi nhỏ, chỉ đọc theo mặc định và có thể kiểm toán. Chuyển sự không chắc chắn cho người điều phối thay vì mở rộng quyền hạn động.
Một bộ khung khôi phục trình duyệt AI biến việc xử lý thách thức thành khả năng chạy trong môi trường kiểm soát. Nó sở hữu trạng thái trình duyệt, xác minh mục tiêu, phân loại trạng thái trang, gọi CapSolver Core tại ranh giới xác định, xác minh trang mong đợi, ghi nhật ký telemetry đã che đi và dừng lại sau một số lần thử có giới hạn. Các khung agent có thể sử dụng bộ khung mà không cần truy cập trực tiếp vào thông tin bí mật hoặc kiểm soát trình duyệt không giới hạn.
Bắt đầu với CapSolver, triển khai máy trạng thái đối với ứng dụng thử nghiệm được phê duyệt và thêm các fixture tách biệt và các rào cản độ tin cậy trước khi sản xuất.
Không. Đó là lớp thời gian chạy độc lập mà khung agent có thể gọi. Bộ khung sở hữu trạng thái trình duyệt, khôi phục, điểm kiểm tra, telemetry và dọn dẹp.
solve_on_page?solve_on_page kết hợp phát hiện, trích xuất tham số, giải quyết và điền vào DOM trên cùng một trang Playwright, điều này phù hợp với ranh giới khôi phục được kiểm soát.
Ưu tiên các hành động bộ khung hẹp như safe_navigate và read_public_page. Truy cập trang gốc làm khó việc thực thi chính sách mục tiêu, điều hướng và khôi phục.
Mặc định chỉ cho phép một lần. Các thách thức lặp lại hoặc trạng thái trang không xác định nên chuyển đến xem xét của điều phối viên thay vì tạo vòng lặp không kiểm soát.
Lưu trữ dữ liệu mô tả như tên miền mục tiêu, phiên bản bộ khung, chuyển tiếp trạng thái, độ trễ, lỗi được chuẩn hóa và tham chiếu tài nguyên. Không lưu trữ token giải quyết, cookie, khóa API, thông tin xác thực proxy, trạng thái lưu trữ hoặc nội dung trang riêng tư.
Xây dựng khung đánh giá CAPTCHA cho các lời gọi công cụ của trợ lý AI với các lược đồ CapSolver, các bộ dữ liệu kiểm tra, các công cụ đánh giá theo dấu vết, các khẳng định, các bộ dữ liệu hồi quy và các cổng CI.

Học cách giải quyết Cloudflare Turnstile trong các agent của LlamaIndex bằng CapSolver, các lược đồ FunctionTool, xử lý token an toàn, thử lại và khôi phục trình duyệt.
