stealthy-auto-browse技能使用说明
stealthy-auto-browse
Docker 中的隐身浏览器。Camoufox(定制版 Firefox)——无 CDP 信号。通过 PyAutoGUI 实现操作系统级别的鼠标/键盘操作——无法被检测。可通过 Cloudflare、DataDome、PerimeterX、Akamai。
有关安装、配置和容器设置,请参阅references/setup.md。

使用场景
- 网站有机器人检测(Cloudflare、CAPTCHAs、DataDome)
- 使用其他浏览器技能时收到 403 或被阻止的响应
- 需要一个不会被封禁的已登录会话
不适用场景
- 没有机器人防护——使用
curl或WebFetch - 仅需静态 HTML——使用
curl
设置
API 应该已经在运行。设置基础 URL:
export STEALTHY_AUTO_BROWSE_URL=http://localhost:8080
验证: curl $STEALTHY_AUTO_BROWSE_URL/health返回好的.
HTTP API
所有命令:POST $STEALTHY_AUTO_BROWSE_URL/附带JSON请求体{"action": "动作名称", ...参数}.
每个响应:
{
"success": true,
"timestamp": 1234567890.123,
"data": { ... },
"error": "only when success is false"
}
两种输入模式
系统输入 — 无法被检测
使用 PyAutoGUI 进行真实的操作系统级别事件操作。浏览器无法感知这是自动化的。
system_click— 以类人曲线移动鼠标,然后点击(视口 x, y 坐标)mouse_move— 移动鼠标但不点击(用于悬停菜单、工具提示)mouse_click— 在指定位置或当前位置点击(无平滑移动)system_type— 以随机延迟逐字符输入文本send_key— 按下一个按键或组合键输入,制表符,Ctrl+A)滚动— 鼠标滚轮滚动(负值 = 向下)
从get_interactive_elements获取视口坐标。
Playwright 输入 — 可检测但便捷
使用 Playwright 的 DOM 事件。更快,使用 CSS 选择器/XPath,但可被检测。
点击— 通过选择器点击填充— 立即设置输入值键入— 逐字符输入到元素中
使用哪种
- 有机器人检测?系统输入。总是如此。
- 没有检测?Playwright 输入即可。
- 悄悄填写表单?
系统点击以聚焦,然后系统输入。
典型工作流程
前往→ 加载页面获取文本→ 读取页面内容获取交互元素→ 查找带有x,y坐标的按钮/输入框系统点击/系统输入/发送按键→ 交互等待元素/等待文本→ 等待结果获取文本→ 验证
操作参考
导航
{"action": "goto", "url": "https://example.com"}
{"action": "goto", "url": "https://example.com", "wait_until": "networkidle"}
{"action": "goto", "url": "https://example.com", "referer": "https://google.com/search?q=stuff"}
{"action": "refresh"}
{"action": "refresh", "wait_until": "networkidle"}
等待直到:"DOM内容加载完成"(默认),"加载完成","网络空闲"。引用来源:设置HTTP引用来源头(用于检查引用来源的网站)。
响应:{"url": "...", "title": "..."}
系统输入(不可检测)
{"action": "system_click", "x": 500, "y": 300}
{"action": "system_click", "x": 500, "y": 300, "duration": 0.5}
{"action": "mouse_move", "x": 500, "y": 300}
{"action": "mouse_click", "x": 500, "y": 300}
{"action": "mouse_click"}
{"action": "system_type", "text": "hello world", "interval": 0.08}
{"action": "send_key", "key": "enter"}
{"action": "send_key", "key": "ctrl+a"}
{"action": "scroll", "amount": -3}
{"action": "scroll", "amount": -3, "x": 500, "y": 300}
Playwright输入(可检测)
{"action": "click", "selector": "#submit-btn"}
{"action": "click", "selector": "xpath=//button[@id='submit']"}
{"action": "fill", "selector": "input[name='email']", "value": "user@example.com"}
{"action": "type", "selector": "#search", "text": "query", "delay": 0.05}
页面检查
{"action": "get_interactive_elements"}
{"action": "get_interactive_elements", "visible_only": true}
{"action": "get_text"}
{"action": "get_html"}
{"action": "eval", "expression": "document.title"}
{"action": "eval", "expression": "document.querySelectorAll('a').length"}
获取交互元素返回所有按钮、链接、输入框,包含x、y、宽度、高度、文本,选择器,可见的。将x,y直接传递给system_click。
get_text返回可见的页面文本(截断至10,000个字符)。导航后首先调用此方法。
截图
# Browser viewport
curl -s "$STEALTHY_AUTO_BROWSE_URL/screenshot/browser?whLargest=512" -o screenshot.png
# Full desktop
curl -s "$STEALTHY_AUTO_BROWSE_URL/screenshot/desktop?whLargest=512" -o desktop.png
调整大小参数:whLargest=512(推荐),width=800,height=300,width=400&height=400。
通过操作(适用于脚本模式——返回带有output_id的base64编码数据):
{"action": "save_screenshot"}
{"action": "save_screenshot", "type": "desktop"}
{"action": "save_screenshot", "output_id": "my_screenshot", "whLargest": 512}
{"action": "save_screenshot", "path": "/output/page.png"}
等待条件
使用这些替代休眠。
{"action": "wait_for_element", "selector": "#results", "state": "visible", "timeout": 10}
{"action": "wait_for_text", "text": "Search results", "timeout": 10}
{"action": "wait_for_url", "url": "**/dashboard", "timeout": 10}
{"action": "wait_for_network_idle", "timeout": 30}
状态:"可见"(默认)、"隐藏"、"已附加"、"已分离"。
标签页
{"action": "list_tabs"}
{"action": "new_tab", "url": "https://example.com"}
{"action": "switch_tab", "index": 0}
{"action": "close_tab", "index": 1}
对话框
在触发对话框的操作之前调用handle_dialog。对话框默认自动接受。
{"action": "handle_dialog", "accept": true}
{"action": "handle_dialog", "accept": false}
{"action": "handle_dialog", "accept": true, "text": "prompt response"}
{"action": "get_last_dialog"}
Cookies
{"action": "get_cookies"}
{"action": "get_cookies", "urls": ["https://example.com"]}
{"action": "set_cookie", "name": "session", "value": "abc", "url": "https://example.com"}
{"action": "delete_cookies"}
存储
{"action": "get_storage", "type": "local"}
{"action": "set_storage", "type": "local", "key": "theme", "value": "dark"}
{"action": "clear_storage", "type": "local"}
类型:"本地"(默认)或"会话"。
下载与上传
{"action": "get_last_download"}
{"action": "upload_file", "selector": "#file-input", "file_path": "/tmp/doc.pdf"}
网络日志记录
{"action": "enable_network_log"}
{"action": "get_network_log"}
{"action": "clear_network_log"}
{"action": "getclear_network_log"}
{"action": "disable_network_log"}
控制台日志记录
捕获console.log、console.error、console.warn等。每个条目包含类型、文本、位置、时间戳。
{"action": "enable_console_log"}
{"action": "get_console_log"}
{"action": "clear_console_log"}
{"action": "getclear_console_log"}
{"action": "disable_console_log"}
滚动
{"action": "scroll_to_bottom", "delay": 0.4}
{"action": "scroll_to_bottom_humanized", "min_clicks": 2, "max_clicks": 6, "delay": 0.5}
scroll_to_bottom使用JS(快速)。scroll_to_bottom_humanized使用操作系统级鼠标滚轮(不可检测)。
显示
{"action": "calibrate"}
{"action": "get_resolution"}
{"action": "enter_fullscreen"}
{"action": "exit_fullscreen"}
调用校准全屏切换后。
实用工具
{"action": "ping"}
{"action": "sleep", "duration": 2}
{"action": "close"}
状态端点(GET请求)
curl $STEALTHY_AUTO_BROWSE_URL/health # "ok" when ready
curl $STEALTHY_AUTO_BROWSE_URL/state # {"status", "url", "title", "window_offset"}
脚本模式
通过标准输入传递YAML脚本,在标准输出获取JSON结果,容器随后退出。无需HTTP服务器。
cat my-script.yaml | docker run --rm -i \
-e TARGET_URL=https://example.com \
psyb0t/stealthy-auto-browse --script > results.json
脚本格式
name: Scrape Example
on_error: stop # "stop" (default) or "continue"
steps:
- action: goto
url: ${env.TARGET_URL}
wait_until: networkidle
- action: sleep
duration: 2
- action: save_screenshot
output_id: screenshot
- action: get_text
output_id: page_text
- action: eval
expression: "document.title"
output_id: title
输出
{
"name": "Scrape Example",
"success": true,
"steps_executed": 5,
"steps_total": 5,
"duration": 3.42,
"step_results": [ ... ],
"outputs": {
"screenshot": "data:image/png;base64,iVBOR...",
"page_text": { "text": "...", "length": 1234 },
"title": { "result": "Example Domain" }
}
}
output_id在任何步骤中将其结果收集到outputs中。截图会转换为base64数据URI。${env.VAR_NAME}用于替换环境变量。on_error: continue遇到错误时继续执行。stop(默认)遇到错误时停止执行。- 所有HTTP API操作均可作为脚本步骤使用。
- 日志输出到标准错误,标准输出为纯净的JSON。
- 退出码成功时为0,失败时为1。
示例:截图 + 提取
cat <<'EOF' | docker run --rm -i -e URL=https://example.com \
psyb0t/stealthy-auto-browse --script > results.json
name: Quick Scrape
steps:
- action: goto
url: ${env.URL}
wait_until: networkidle
- action: save_screenshot
output_id: screenshot
whLargest: 1024
- action: get_text
output_id: text
- action: eval
expression: "document.title"
output_id: title
EOF
页面加载器(URL触发的自动化)
将YAML文件挂载到/loaders。当goto命中匹配的URL时,将执行加载器的步骤,而不是正常导航。在API和脚本模式下均可工作。
docker run -d -p 8080:8080 -v ./my-loaders:/loaders psyb0t/stealthy-auto-browse
在脚本模式下:
cat script.yaml | docker run --rm -i \
-v ./my-loaders:/loaders \
psyb0t/stealthy-auto-browse --script
加载器格式
name: News Site Cleanup
match:
domain: news-site.com # exact hostname (www. stripped)
path_prefix: /articles # path starts with
regex: "article/\\d+" # full URL regex
steps:
- action: goto
url: "${url}" # ${url} = original URL
wait_until: networkidle
- action: eval
expression: "document.querySelector('.cookie-banner')?.remove()"
- action: wait_for_element
selector: "article"
timeout: 10
匹配字段是可选的,但至少需要一个。所有指定的字段都必须匹配。
提示
- 始终在点击前
获取交互元素——不要猜测坐标用于隐身的系统输入 - ——system_click
、system_type、send_key获取文本 get_text首先,截屏次之— 文本更快且更小- 将时区与IP位置匹配— 时区不匹配是一个检测信号
- 使用以下参数调整截屏大小
?whLargest=512— 全分辨率文件巨大 - 等待条件优于休眠—
等待元素,等待文本,等待URL 处理对话框在触发之前— 否则对话框会自动被接受校准全屏之后— 坐标映射会偏移


微信扫一扫,打赏作者吧~