> For the complete documentation index, see [llms.txt](https://developers.oxylabs.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.oxylabs.io/products/cn/agent-browser/ye-mian-chu-li-cheng-xu.md).

# 页面处理程序

让 Agent Browser 自动识别每个页面，自动处理访问挑战，并在页面就绪时通知你的脚本。

{% hint style="warning" %}
**需要账户访问权限：** 未启用该功能的账户会收到 `该账户在握手阶段未启用 400 页面处理器` （参见 [响应代码](/products/cn/agent-browser/xiang-ying-dai-ma.md)).
{% endhint %}

Oxylabs Agent Browser 使用内置页面处理器来应对网站访问挑战。该 `page_handler` 参数会标识其加载的每个页面，完成找到的受支持挑战，并将页面状态作为窗口消息报告给你的脚本。

```bash
wss://USER:PASS@hb.oxylabs.io?p_cc=US&page_handler=true
```

**页面处理器默认处于禁用状态** 并且必须为每次连接传入，并在所有连接到同一目标的连接中保持一致，包括共享 [持久配置文件](/products/cn/agent-browser/persistent-sessions-and-profiles.md#persistent-profiles) （profile `o_profile` 或粘性代理会话 `proxy_resi_ses_id`).

<table><thead><tr><th width="133">参数</th><th width="405">说明</th><th width="93.5">类型</th></tr></thead><tbody><tr><td><code>page_handler</code></td><td>启用页面识别和自动挑战处理。默认值： <code>false</code>.</td><td>布尔值</td></tr></tbody></table>

{% hint style="info" %}
页面处理器会增加页面加载时间，因此仅对显示挑战的目标启用它。如果你的账户未启用此功能，请联系 [Oxylabs 支持。](mailto:support@oxylabs.io)
{% endhint %}

## 页面状态

启用页面处理器后，浏览器会将每个页面的状态作为 `window` 消息：

```javascript
{ source: "oxylabs-runtime", type: "oxylabs-page-status", status: "open" }
```

<table><thead><tr><th width="130.5">状态</th><th>说明</th></tr></thead><tbody><tr><td><code>识别中</code></td><td>正在检查页面。</td></tr><tr><td><code>已关闭</code></td><td>已发现挑战，正在处理。页面暂时不可用。</td></tr><tr><td><code>可用</code></td><td>页面已准备好可用。</td></tr><tr><td><code>失败</code></td><td>挑战无法完成。该消息包含一个 <code>error</code> 字段。</td></tr></tbody></table>

`识别中` 和 `已关闭` 这些状态是临时的，因此请等待 `可用` 或 `失败`。无挑战的页面会在 `可用` 加载后约 8 秒报告状态，而处理挑战通常需要 30–45 秒。如果状态为 `失败`，请关闭会话并使用新连接重试。

## 跟踪页面状态

浏览器控制台输出不会传递给 CDP 客户端，因此请使用在页面加载前添加的脚本监听 window 消息，然后等待最终状态：

{% tabs %}
{% tab title="Python（Playwright）" %}

```python
from playwright.sync_api import sync_playwright

username = "USERNAME"
password = "PASSWORD"
endpoint = "hb.oxylabs.io"
browser_url = f"wss://{username}:{password}@{endpoint}?p_cc=US&page_handler=true"

# Keep the latest page status in the page
status_listener = """
window.addEventListener("message", (e) => {
  const d = e.data;
  if (d?.source === "oxylabs-runtime" && d.type === "oxylabs-page-status") {
    window.__pageStatus = d.status;
  }
});
"""

with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(browser_url)
    context = browser.contexts[0] if browser.contexts else browser.new_context()
    context.add_init_script(status_listener)  # add before opening the page
    page = context.new_page()
    page.goto("https://example.com")

    # Wait until the page is ready ("open") or the handler gives up ("failed")
    page.wait_for_function("['open', 'failed'].includes(window.__pageStatus)", timeout=90000)
    print(page.evaluate("window.__pageStatus"), page.title())
    browser.close()
```

{% endtab %}

{% tab title="JavaScript（Playwright）" %}

```javascript
import { chromium } from "playwright";

const username = "USERNAME";
const password = "PASSWORD";
const endpoint = "hb.oxylabs.io";
const browserUrl = `wss://${username}:${password}@${endpoint}?p_cc=US&page_handler=true`;

// Keep the latest page status in the page
const statusListener = () => {
    window.addEventListener("message", (e) => {
        const d = e.data;
        if (d?.source === "oxylabs-runtime" && d.type === "oxylabs-page-status") {
            window.__pageStatus = d.status;
        }
    });
};

(async () => {
    const browser = await chromium.connectOverCDP(browserUrl);
    const context = browser.contexts()[0] || (await browser.newContext());
    await context.addInitScript(statusListener); // add before opening the page
    const page = await context.newPage();
    await page.goto("https://example.com");

    // Wait until the page is ready ("open") or the handler gives up ("failed")
    await page.waitForFunction(
        () => ["open", "failed"].includes(window.__pageStatus),
        null,
        { timeout: 90000 }
    );
    console.log(await page.evaluate(() => window.__pageStatus), await page.title());
    await browser.close();
})();
```

{% endtab %}

{% tab title="JavaScript（Puppeteer）" %}

```javascript
import puppeteer from "puppeteer";

const username = "USERNAME";
const password = "PASSWORD";
const endpoint = "hb.oxylabs.io";
const browserUrl = `wss://${username}:${password}@${endpoint}?p_cc=US&page_handler=true`;

// Keep the latest page status in the page
const statusListener = () => {
    window.addEventListener("message", (e) => {
        const d = e.data;
        if (d?.source === "oxylabs-runtime" && d.type === "oxylabs-page-status") {
            window.__pageStatus = d.status;
        }
    });
};

(async () => {
    const browser = await puppeteer.connect({ browserWSEndpoint: browserUrl });
    const page = await browser.newPage();
    await page.evaluateOnNewDocument(statusListener); // add before opening the page
    await page.goto("https://example.com");

    // Wait until the page is ready ("open") or the handler gives up ("failed")
    await page.waitForFunction(
        () => ["open", "failed"].includes(window.__pageStatus),
        { timeout: 90000 }
    );
    console.log(await page.evaluate(() => window.__pageStatus), await page.title());
    await browser.close();
})();
```

{% endtab %}
{% endtabs %}

### 在页面加载后处理挑战

页面处理器会处理页面加载时存在的挑战。例如，点击或提交表单后出现的挑战不会自动处理。要处理它，请向页面发送一个 `oxylabs-page-handle` 消息。浏览器会再次检查页面，处理发现的任何挑战，并像之前一样报告状态。

### MCP Server 和 Agent Skills

如果你正在使用 AI 代理或编程助手，我们强烈建议使用 Oxylabs Agent Browser 的简易集成方式：

<table data-header-hidden><thead><tr><th width="152"></th><th></th></tr></thead><tbody><tr><td><a href="/ai-workflows/agent-skills.md"><strong>Agent Skills</strong></a></td><td>在 Claude Code、Cursor 和其他 AI 编码助手中设置 Agent Browser。</td></tr><tr><td><a href="/ai-workflows/mcp.md"><strong>MCP Server</strong></a></td><td>为兼容 MCP 的 AI 助手提供远程 Agent Browser。</td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://developers.oxylabs.io/products/cn/agent-browser/ye-mian-chu-li-cheng-xu.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
