跳到主要内容
知仓学习社ZHICANG

browser

用异步 Python 调用 QwenPaw 内置 Browser SDK 驱动真实浏览器。完整参考在下方;上下文压缩后请重新加载此 browser skill。

不碰外部(只输出文字)无严重或高危命中agentscope-ai/QwenPaw

它会碰到什么

扫了多少1 个文本文件,10 KB
它会碰到什么不碰外部(只输出文字)
命中总数0 处
命中统计严重 0 · 高 0 · 中 0 · 低 0

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

浏览器

保持工作纪律:先感知当前页面,再通过已列出的 API 动作,最后重新感知后才可声明成功。

只能陈述本轮实际观察到的事实。卡住时的合格交付 = 说明卡在哪一步 + 已亲眼验证的部分结果;

不要为了给出完整答案而补全你没有看到的内容。

尊重人工边界:登录、验证码、2FA 或任何必须由人完成的步骤,调用

await browser.handoff(...) 后停止,绝不自动化这些流程。

浏览器完不成时,不要拿其他渠道(如 web_search)的数据顶替并仍说成浏览器结果——

如实写明每个数据的来源。

这是 QwenPaw 内置的 Browser SDK,不是 Playwright。它是封闭的 API 表面:

未列出的方法不存在。完整参考在下方;若上下文中不再保留,请用 Skill 工具重新加载

此 browser skill。

<!-- BEGIN GENERATED: browser-manual -->

QwenPaw Browser SDK — complete reference. This is QwenPaw's OWN internal

SDK and this is the ENTIRE API; these are all the entrypoints. The SDK

is already in scope as Browser — call the methods below directly. Write

async Python. Work in a loop: perceive → act → verify.

Copy this shape:

browser = await Browser.connect() # connect once; reused all session

page = await browser.open("https://example.com") # open a page

obs = await page.snapshot() # PERCEIVE — page text is obs.text

if len(obs.text) < 6000:

print(obs.text)

else:

# Large page: read selectively instead of dumping everything.

lines = [line for line in obs.text.splitlines()

if "keyword" in line]

print(f"{len(obs.text)} chars total; {len(lines)} matching lines:")

print("\n".join(lines[:80]))

For a focused count, use: await page.snapshot(query="keyword")

await page.get_by_role("textbox", name="Search").fill("laptop") # ACT

await page.get_by_role("button", name="Search").click() # ACT

obs = await page.snapshot() # VERIFY — re-perceive to confirm

print("Verified; inspect obs.text with the selective pattern above.")

Session state: this is a stateful session — variables you assign (browser,

page) persist across calls, so connect once and reuse them. If a call

reports the session was reset, re-run await Browser.connect().

Chrome backend caveat: with backend=chrome you operate inside the user's

real browser. A session is a tab-ownership group — tabs are isolated per

session, but identity (cookies, logins, storage) is shared with the user's

profile and with every other session. Do not rely on session-level identity

isolation on this backend.

browser (orchestration):

await Browser.connect(*, identity: "auto"|"user"|"avatar"|"guest" = "auto") -> browser

Connect as an identity: user, avatar, guest, or auto.

`auto picks user when Chrome is connected, otherwise guest`.

An unavailable explicit identity raises instead of substituting.

await browser.open(url: str | None = None) -> page

Open a page at `url` and return it.

Reuses this session's active page when one exists; otherwise a

new page is created. Pages are released when the response cycle ends;

start each cycle by calling `open(url)` again.

await browser.pages() -> list of page ref (.id, .url, .title, .active)

List open pages with URL, title, and active-state details.

await browser.switch_page(page: page ref (.id, .url, .title, .active)) -> none

Make the given page ref active for later operations.

await browser.close_page(page: page ref (.id, .url, .title, .active)) -> none

Close the given page ref in this session.

await browser.session_status() -> session status (.owner, .variant, .context, .connected)

Report the owner, variant, context, and connected state.

await browser.handoff(reason: str, instructions: str = "") -> a result dict

Hand a step back to a human (captcha, login, 2FA).

Pass a short reason and instructions; the run stops on this signal —

never automate these flows. The active cycle-scoped page is retained

for one extra response cycle after the handoff.

await browser.present(url: str | None = None) -> page

Open a page retained for the chat lifetime.

await browser.close() -> none

Close this session's browser and release its context.

page (operation):

await page.goto(url: str) -> a result dict

Navigate this page to `url` and return raw navigation facts.

await page.go_back() -> a result dict

Navigate back to the previous page in history.

await page.go_forward() -> a result dict

Navigate forward to the next page in history.

await page.reload() -> a result dict

Reload the current page.

await page.keep() -> none

Retain this page across response cycles for the current chat.

await page.wait_for_load_state(state: str = "load", *, timeout: float | None = None) -> none

Wait until the page reaches the requested load state.

`networkidle` semantics depend on the backend: the Playwright

backend waits for true network quiescence, while CDP-based

backends (cdp, chrome) degrade to ``document.readyState ==

"complete"`` plus a fixed 500 ms quiet delay and do NOT track

in-flight requests — content loaded by late XHR may still be

missing when this returns.

await page.wait_for_timeout(timeout: float) -> none

Sleep unconditionally for timeout milliseconds (capped at 30 000).

Prefer :py:meth:`locator.wait_for(state, timeout)

<LocatorView.wait_for>` when waiting for a specific DOM condition

— it returns as soon as the condition is met and is both faster

and more reliable than an unconditional sleep.

await page.screenshot() -> a result dict

Capture this page to a PNG file in the active workspace.

page.get_by_role(role: str, *, name: str | None = None) -> locator

Locate elements by accessible role and optional name.

page.get_by_text(text: str) -> locator

Locate elements by their visible text.

page.get_by_label(text: str) -> locator

Locate a form control by its associated label text.

page.get_by_placeholder(text: str) -> locator

Locate an input by its placeholder text.

page.locator(selector: str) -> locator

Locate elements by a CSS selector when no semantic locator fits.

page.frame_locator(selector: str) -> locator

Scope subsequent locators to the iframe matching `selector`.

await page.snapshot(query: str | None = None) -> observation (read .text; .match_count when you pass a query)

Perceive the page and return readable content in `.text`.

Pass `query to also report .match_count`.

await page.current_surface() -> surface facts (.url, .title, .load_state)

Return this page's current URL, title, and load facts.

page.mouse -> coordinate/keyboard input surface (see methods below)

Viewport-coordinate input surface.

click(x, y) -> a result dict; verify the effect with snapshot().

page.keyboard -> coordinate/keyboard input surface (see methods below)

Keyboard input surface.

press(key) -> a result dict; verify the effect with snapshot().

page.get_by_* / page.locator(...) return a locator that mirrors a SUBSET

of Playwright's Python locator API — the Playwright-shaped part of this

SDK:

compose/scope (chainable): get_by_role/get_by_text/get_by_label/

get_by_placeholder, locator(sel), filter(...), nth(i), first, last (properties)

iframe scope: page.frame_locator(sel).locator(...) (one frame; no nested frames)

read (await): count()->int, inner_text()->str, text_content()->str|None,

all_text_contents()->list, get_attribute(name)->str|None,

input_value()->str, is_visible()->bool, is_enabled()->bool

act (await; returns a short evidence line — read .evidence): click(), fill(v),

type(t), press(key), check(), uncheck(), set_checked(b),

select_option(*v), hover(), dblclick(), scroll(),

focus(), blur(), clear(), wait_for(state), screenshot(),

bounding_box()->dict|None (viewport ["x"] ["y"] ["width"] ["height"]; None when the element is not visible)

strict-mode

uniqueness is enforced — act only when the locator resolves to exactly

one element (use count() to check). element_handle / raw CDP unavailable.

Backend differences (chrome/cdp vs playwright): on chrome/cdp the

accessible name is a heuristic (aria-labelledby > aria-label > alt >

title > text content) - container elements may match

get_by_role(name=) more broadly than under playwright, so

strict-mode errors are more likely there; narrow with

filter(has_text=) or a more specific role. is_enabled() reflects

only the disabled property, not aria-disabled. press() supports a

fixed key set: printable characters, Enter, Tab, Escape, Backspace,

Delete, Arrow keys, Home/End/PageUp/PageDown, and

Control/Shift/Alt/Meta combos - anything else fails with guidance.

type() sets the value directly and fires an input event; editors that

need real per-key events may not react - prefer fill() where possible.

Reading results (read these fields; the type names don't matter):

snapshot() -> .text (page text), .match_count (when you pass query)

current_surface() -> .url, .title, .load_state

page refs -> .id, .url, .title, .active

screenshot() -> result dict; read ["path"]

bounding_box() -> viewport ["x"] ["y"] ["width"] ["height"]; None when the element is not visible

mouse.click()/keyboard.press() -> result dict; fields depend on the backend, so verify with snapshot()

actions -> .evidence (a short line saying what happened)

locator reads return plain str/int/bool/list directly.

If a locator fails, step DOWN one rung (don't jump):

  1. semantic page.get_by_role/label/text first choice
  2. css page.locator(css) role missing/unstable
  3. coordinates use locator.bounding_box() first for an exact, low-cost viewport rectangle; use a screenshot to explore only when the element is absent from snapshot()

For captcha/login/2FA or any human-only step: await browser.handoff(reason,

instructions) and stop — never automate them.

<!-- END GENERATED: browser-manual -->

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。

它属于哪个仓库

星标★ 35,028
本站分层T1
该仓技能数44
原文件路径src/qwenpaw/agents/skills/browser-zh/SKILL.md

同一个仓库里的其他技能

看这个仓库的全部 44 个技能

同名技能的其他版本

有 2 个不同仓库或目录里都有叫 browser 的技能。它们内容并不相同,别混用:

  • agentscope-ai/QwenPaw — Drive a live browser with async Python against QwenPaw's builtin Browser SDK. The full ref