Skill: tedtalk/agent-vision-scraper (version 1.0.0)

# Dockerized Vision Agent Scraper ## Description 这是一个运行在独立 Docker 容器中的拟人化网页操作与抓取工具。它内置了虚拟屏幕 (Xvfb) 和 Playwright 隐身指纹，完全依靠 AI 的视觉能力 (Vision) 来读取和破解图形验证码，不依赖任何第三方打码服务。 **Base Image**: `mcr.microsoft.com/playwright:v1.58.2-jammy` ## Usage Instructions 当用户要求进行复杂网页自动化、数据抓取、或遇到具备反爬/图形验证码的网站时，请调用此工具。 **重要说明**：必须通过 `docker run` 命令来启动它，以确保它运行在配置好的虚拟屏幕环境中。 **Command Format:** ```bash docker run --rm --env-file .env -p 5900:5900 agent-scraper-image node agent-scraper.js ``` **Examples:** ```bash docker run --rm --env-file .env -p 5900:5900 agent-scraper-image node agent-scraper.js "https://example.com/login" "查看页面，如果发现图形验证码，读出图片上的字母，并与账号 admin 和密码 123456 一起填入表单，点击登录。" ``` ## Build Image ```bash cd ~/.openclaw/skills/agent-vision-scraper docker build -t agent-scraper-image . ``` ## Features - ✅ 虚拟屏幕 (Xvfb) - 无头服务器也能运行有头浏览器 - ✅ VNC 远程查看 - 端口 5900 可连接查看实时操作 - ✅ Playwright Stealth - 绕过常见反爬检测 - ✅ Vision 验证码识别 - 利用 LLM 视觉能力破解图形验证码 - ✅ 最新 Playwright v1.58.2 - 与当前环境保持一致 --- _最后更新：2026-03-03_

path: README.md
content: # Agent Vision Scraper 🤖👁️

Docker 化的智能网页自动化与抓取工具，利用 LLM 视觉能力破解图形验证码。

## 特性

- 🖥️ **虚拟屏幕** - 内置 Xvfb，无头服务器也能运行有头浏览器
- 🔍 **VNC 远程查看** - 端口 5900 可连接查看实时操作
- 🕵️ **隐身模式** - Playwright Stealth 插件绕过反爬检测
- 👁️ **视觉验证码识别** - 利用 LLM Vision 能力破解图形验证码
- 📦 **最新 Playwright** - 基于 v1.58.2-jammy 镜像

## 快速开始

### 1. 构建镜像

```bash
docker build -t agent-scraper-image .
```

### 2. 运行

```bash
docker run --rm --env-file .env -p 5900:5900 agent-scraper-image node agent-scraper.js "<URL>" "<INSTRUCTION>"
```

### 示例

```bash
# 登录带验证码的网站
docker run --rm --env-file .env -p 5900:5900 agent-scraper-image node agent-scraper.js \
  "https://example.com/login" \
  "查看页面，如果发现图形验证码，读出图片上的字母，并与账号 admin 和密码 123456 一起填入表单，点击登录。"

# 抓取数据
docker run --rm --env-file .env -p 5900:5900 agent-scraper-image node agent-scraper.js \
  "https://example.com/products" \
  "抓取所有产品的名称、价格和图片链接，返回 JSON 格式。"
```

## 环境变量

创建 `.env` 文件：

```env
# 可选：LLM API 配置（如果需要调用外部视觉模型）
OPENAI_API_KEY=sk-xxx
ANTHROPIC_API_KEY=sk-ant-xxx

# 可选：代理配置
HTTP_PROXY=http://proxy:8080
HTTPS_PROXY=http://proxy:8080
```

## VNC 查看

运行时映射了 5900 端口，可用 VNC 客户端连接查看浏览器操作过程：

- **地址**: `localhost:5900`
- **密码**: 无（免密）

## 文件结构

```
agent-vision-scraper/
├── Dockerfile           # Docker 镜像定义
├── package.json         # Node.js 依赖
├── agent-scraper.js     # 主程序
├── skill.md             # ClawHub skill 描述
└── README.md            # 本文档
```

## 工作原理

1. **启动虚拟桌面** - Xvfb 创建虚拟显示器 :99
2. **启动浏览器** - Playwright Chromium 有头模式运行
3. **导航页面** - 访问目标 URL
4. **视觉分析** - 截图发送给 LLM 分析
5. **执行操作** - 根据 LLM 返回的指令点击/输入
6. **循环执行** - 直到任务完成

## 适用场景

- ✅ 带图形验证码的网站登录
- ✅ 复杂网页自动化操作
- ✅ 反爬网站数据抓取
- ✅ 需要视觉判断的网页任务

## 注意事项

- 首次运行需要下载浏览器（约 200MB）
- VNC 端口 5900 需要开放
- 建议在有足够内存的机器上运行（2GB+）

## License

MIT

---

**Author**: Tedtalk  
**Version**: 1.0.0  
**Last Updated**: 2026-03-03


path: agent-scraper.js
content: import { AgentBrowser } from '@vercel/agent-browser';
import { chromium } from 'playwright-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
import dotenv from 'dotenv';

dotenv.config();

chromium.use(StealthPlugin());

const url = process.argv[2];
const userInstruction = process.argv[3];

if (!url || !userInstruction) {
    console.error("❌ 缺少参数。用法: node agent-scraper.js <URL> <INSTRUCTION>");
    process.exit(1);
}

// 给大模型下达的“系统级”视觉增强指令
const augmentedInstruction = `
【核心任务】: ${userInstruction}

【应对风控与验证码协议】：
1. 你正在一个真实的浏览器环境中操作。如果页面弹出了图形验证码（如看图识字、滑块、点选等），请立刻停止报错。
2. 调用你的视觉 (Vision) 能力分析当前页面的截图。
3. 识别出验证码的内容后，找到对应的输入框或坐标，执行填写或点击操作。
4. 验证通过后，继续执行核心任务。
`;

async function run() {
    console.log(`[+] 启动浏览器 (环境: Docker虚拟屏幕 + Stealth指纹)...`);
    
    // 注意：在 Docker 的虚拟屏幕下，我们可以安全地开启有头模式 (headless: false)
    const browser = await chromium.launch({ 
        headless: false, 
        args: [
            '--no-sandbox', 
            '--disable-setuid-sandbox',
            '--disable-dev-shm-usage', // 防止 Docker 内存溢出
            '--disable-blink-features=AutomationControlled'
        ]
    }); 
    
    const context = await browser.newContext({
        viewport: { width: 1280, height: 720 },
        userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        locale: 'zh-CN'
    });
    
    const page = await context.newPage();
    
    try {
        console.log(`[+] 正在导航至: ${url}`);
        await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });
        await page.waitForTimeout(3000); 

        // 尝试把常见的验证码区域滚动到可视区中央，方便大模型截图看清
        await page.evaluate(() => {
            const captchas = document.querySelectorAll('.g-recaptcha, .h-captcha, #cf-turnstile, img[src*="captcha"]');
            if (captchas.length > 0) captchas[0].scrollIntoView({ behavior: 'smooth', block: 'center' });
        });

        console.log(`\n[+] 移交控制权给 Agent-browser...`);
        console.log(`[-] 正在执行指令: "${augmentedInstruction}"`);
        
        const agentBrowser = new AgentBrowser({ page });
        
        // 执行循环：截图 -> LLM 分析 -> 执行动作 -> 截图...
        const result = await agentBrowser.execute(augmentedInstruction);
        
        console.log(`\n[√] 🎉 任务完成，数据提取如下:\n`);
        console.log(JSON.stringify(result, null, 2));

    } catch (error) {
        console.error(`\n[x] 执行失败:`, error);
    } finally {
        await browser.close();
    }
}

run();


path: package.json
content: {
  "name": "agent-vision-scraper",
  "version": "1.0.0",
  "description": "Dockerized Vision Agent Scraper with Xvfb and Playwright Stealth",
  "type": "module",
  "main": "agent-scraper.js",
  "scripts": {
    "start": "node agent-scraper.js"
  },
  "keywords": [
    "playwright",
    "scraper",
    "automation",
    "vision",
    "captcha",
    "docker",
    "xvfb"
  ],
  "author": "Tedtalk",
  "license": "MIT",
  "dependencies": {
    "@vercel/agent-browser": "^1.0.0",
    "playwright-extra": "^4.3.6",
    "puppeteer-extra-plugin-stealth": "^2.11.2",
    "dotenv": "^16.4.5"
  }
}


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)