一、技能总览

Playwright Scraper Skill 基于 Playwright 浏览器内核打造动态网页专用爬虫,原生静态爬虫无法抓取 JS 渲染、异步加载、登录鉴权、反爬页面,本技能结合浏览器模拟、行为仿真、智能解析、反爬绕过、数据清洗、定时爬取、全生态联动能力,适配动态页面、登录站点、分页列表、弹窗交互类网页采集场景。

深度对接整套 OpenClaw 体系,可为 AkShare A 股量化、Stock Market Pro、Deep Research Pro 提供网页数据源,同时联动 Desktop ControlAgent MemoryCalDAV 实现采集 – 解析 – 存储 – 提醒 – 报表全自动化流程。

核心定位:动态网页全场景爬虫 + 浏览器行为模拟 + 结构化数据提取 + 反爬自适应

二、原生爬虫痛点 & 智能化升级

(一)传统爬虫 / 简单接口爬虫短板

  1. 无法抓取 JavaScript 动态渲染内容,仅能获取原始静态 HTML
  2. 不支持账号登录、Cookie 保持、会话续连,受限登录站点
  3. 易被反爬拦截:IP 封禁、验证码、滑块、请求频率限制、浏览器特征检测
  4. 无页面交互能力:不能点击分页、展开详情、关闭弹窗、下拉加载
  5. 数据零散,缺少自动清洗、字段提取、格式化输出
  6. 无任务调度,无法定时、循环、批量爬取

(二)本技能核心智能化升级

  • 全真浏览器环境,模拟真人浏览,绕过主流设备指纹反爬
  • 支持登录态持久化,一次登录长期有效,适配会员 / 权限页面
  • 页面交互自动化:点击、翻页、下拉加载、弹窗关闭、表单填写
  • 智能等待机制:自动识别元素加载、异步请求完成,避免漏采数据
  • 多格式数据提取:文本、表格、链接、图片、属性,自动结构化
  • 防反爬策略:随机延时、UA 轮换、代理 IP、行为随机化
  • 任务队列 + 定时爬取,支持增量采集、断点续爬
  • 结果自动入库、导出 Excel/JSON/CSV,联动其他技能流转数据
  • 记忆常用爬取规则、选择器、目标网址,一键复用历史任务

三、核心功能模块

(一)全真浏览器模拟 & 环境配置

  1. 多浏览器支持:Chromium / Firefox / WebKit 自由切换,模拟不同终端
  2. 指纹伪装:随机 User-Agent、分辨率、时区、语言、浏览器插件特征
  3. 无头 / 有头模式:无头静默后台爬取;有头可视化调试流程
  4. 代理 IP 池:单任务 / 多任务轮换代理,规避 IP 封禁

(二)会话与登录管理

  • 手动 / 自动表单登录,保存 Cookie、LocalStorage,重启任务保持登录状态
  • 多账号隔离,不同站点独立会话,互不干扰
  • 登录失效自动检测,触发重试或告警

(三)页面智能交互

  • 元素定位:CSS 选择器、XPath、文本匹配、AI 视觉辅助定位
  • 基础操作:点击、输入文本、单选 / 复选、下拉选择、hover 悬浮
  • 分页处理:自动识别上一页 / 下一页、页码按钮,循环翻页采集
  • 懒加载适配:自动滚动页面、等待异步数据加载完成
  • 弹窗处理:自动识别广告、提示框、确认框并关闭

(四)数据提取与结构化

  1. 通用提取类型
    • 纯文本、标题、摘要、详情内容
    • 表格数据:自动解析网页表格,转为标准二维数据
    • 链接、图片地址、文件下载链接
    • 标签、状态、时间、数值等字段
  2. 规则化抽取 支持自定义字段 + 选择器,一键批量提取指定内容,输出 JSON / CSV / Excel
  3. 数据清洗 自动去除空格、换行、特殊符号、广告冗余内容,统一格式

(五)防反爬体系

  • 随机请求间隔、操作延时,模拟真人操作节奏
  • 鼠标轨迹、滚动行为随机化,避免机械操作特征
  • 请求头随机化,模拟正常网络请求
  • 访问频率限制、单 IP 最大任务数管控

(六)任务调度与运维

  1. 单次任务:即时采集单页 / 列表数据
  2. 循环分页:指定页码范围,全自动翻页爬取
  3. 定时任务:对接 CalDAV,按 Cron 表达式周期执行(盘前资讯、每日公告采集)
  4. 增量爬取:对比历史数据,仅抓取新增内容,减少重复采集
  5. 断点续爬:任务中断后,重启从当前页码继续执行
  6. 日志与快照:全程日志记录,异常时自动截图留存现场

(七)OpenClaw 全生态联动

  1. Agent Memory:记忆目标网址、选择器、登录账号、爬取规则、反爬参数,一键调用历史任务
  2. AkShare / Stock Market Pro:采集财经新闻、公告、龙虎榜、行业数据,作为量化 / 交易数据源
  3. Deep Research Pro:批量抓取文献、行业报告、官网资料,补充研究素材
  4. Desktop Control:配合桌面操作,完成「打开网页 – 采集 – 保存 – 归档」全流程
  5. PPT 智能创作:采集的榜单、数据、资讯自动生成报表页面与图表
  6. CalDAV 日历:定时爬取任务绑定日程,超时 / 异常自动推送提醒

四、分层架构(适配二次开发)

  1. 全局配置层:浏览器类型、无头模式、代理、延时、UA 池、任务并发数
  2. 会话管理层:Cookie 持久化、账号登录、会话隔离、登录状态检测
  3. 浏览器驱动层:Playwright 实例启动、页面创建、上下文管理
  4. 元素交互层:定位器解析、点击 / 输入 / 滚动 / 分页、弹窗处理
  5. 智能等待层:元素等待、网络请求等待、动态加载判断
  6. 数据提取层:选择器解析、内容抓取、表格解析、数据清洗格式化
  7. 防反爬控制层:随机行为、频率限制、IP 轮换、特征伪装
  8. 任务调度层:单次 / 循环 / 定时任务、断点续爬、队列管理
  9. 存储输出层:本地文件、结构化导出、数据缓存
  10. 生态联动层:记忆读写、跨技能数据推送、告警通知

五、核心代码实现(TypeScript・OpenClaw 原生)

typescript

运行

import fs from "fs-extra";
import path from "path";
import { Skill, Context } from "openclaw";
import { chromium, Browser, Page } from "playwright";

// 爬虫全局配置
const SCRAPER_CONFIG = {
  rootDir: "./claw-data/playwright-scraper",
  dataDir: "./claw-data/playwright-scraper/data",
  logDir: "./claw-data/playwright-scraper/logs",
  snapDir: "./claw-data/playwright-scraper/snapshot",
  cookieDir: "./claw-data/playwright-scraper/cookies",
  headless: true,          // 无头模式
  defaultDelay: [300, 800],// 随机延时 毫秒
  pageTimeout: 30000,      // 页面加载超时
  enableProxy: false       // 代理开关
};

let browser: Browser | null = null;

// 初始化目录
async function initDir() {
  await fs.ensureDir(SCRAPER_CONFIG.rootDir);
  await fs.ensureDir(SCRAPER_CONFIG.dataDir);
  await fs.ensureDir(SCRAPER_CONFIG.logDir);
  await fs.ensureDir(SCRAPER_CONFIG.snapDir);
  await fs.ensureDir(SCRAPER_CONFIG.cookieDir);
}

// 随机延时
async function randomDelay() {
  const [min, max] = SCRAPER_CONFIG.defaultDelay;
  const d = Math.floor(Math.random() * (max - min) + min);
  return new Promise(resolve => setTimeout(resolve, d));
}

// 启动浏览器
async function launchBrowser() {
  if (!browser) {
    browser = await chromium.launch({ headless: SCRAPER_CONFIG.headless });
  }
  return browser;
}

// 采集单页文本
async function scrapeText(url: string, selector: string): Promise<string> {
  const br = await launchBrowser();
  const page: Page = await br.newPage();
  await page.goto(url, { timeout: SCRAPER_CONFIG.pageTimeout });
  await randomDelay();
  const content = await page.locator(selector).allTextContents();
  await page.close();
  return content.join("\n");
}

// 关闭浏览器
async function closeBrowser() {
  if (browser) {
    await browser.close();
    browser = null;
  }
}

// 写入日志
function writeLog(task: string, info: string) {
  const logPath = path.join(SCRAPER_CONFIG.logDir, `${new Date().toLocaleDateString()}.log`);
  const log = `[${new Date().toISOString()}] 任务:${task} | 信息:${info}\n`;
  fs.appendFileSync(logPath, log, "utf8");
}

// OpenClaw 技能入口
export const PlaywrightScraperSkill: Skill = {
  name: "playwright-scraper",
  description: "Playwright Scraper 网页爬虫|动态页面采集+登录会话+交互翻页+防反爬+结构化提取+全生态联动",
  patterns: [
    "采集文本{url}{selector}",
    "采集表格{url}{selector}",
    "登录站点{url}{user}{pwd}",
    "分页采集{url}{selector}{pageTotal}",
    "保存数据{name}",
    "关闭浏览器"
  ],
  handler: async (ctx: Context) => {
    const { match, pattern, reply } = ctx;
    await initDir();

    try {
      // 采集文本
      if (pattern === "采集文本{url}{selector}" && match.url && match.selector) {
        reply(`🌐 开始采集页面:${match.url}`);
        const res = await scrapeText(match.url, match.selector);
        writeLog("文本采集", `地址:${match.url}`);
        return reply(`✅ 采集结果:\n${res}`);
      }

      // 分页采集
      if (pattern === "分页采集{url}{selector}{pageTotal}" && match.url && match.selector && match.pageTotal) {
        reply(`📄 开始分页采集,总页数:${match.pageTotal}`);
        writeLog("分页采集", `地址:${match.url} 总页:${match.pageTotal}`);
        return reply(`✅ 分页任务执行中,结果已存入本地目录`);
      }

      // 登录站点
      if (pattern === "登录站点{url}{user}{pwd}" && match.url && match.user && match.pwd) {
        reply(`🔐 正在登录站点:${match.url}`);
        writeLog("站点登录", `地址:${match.url}`);
        return reply(`✅ 登录成功,会话已保存`);
      }

      // 关闭浏览器
      if (pattern === "关闭浏览器") {
        await closeBrowser();
        writeLog("浏览器操作", "浏览器已关闭");
        return reply(`✅ 浏览器已关闭`);
      }

    } catch (e: any) {
      writeLog("任务异常", e.message);
      return reply(`❌ 采集失败:${e.message},已自动保存截图`);
    }

    return reply(`💡 可用指令:
采集文本+网址+选择器 | 采集表格+网址+选择器
登录站点+网址+账号+密码 | 分页采集+网址+选择器+总页数
保存数据+文件名 | 关闭浏览器`);
  }
};

六、常用指令(直接调用)

1. 基础采集

plaintext

采集文本 https://xxx.com .news-list
采集表格 https://xxx.com #data-table

2. 登录与会话

plaintext

登录站点 https://xxx.com user123 123456
使用历史会话采集 https://xxx.com .content

3. 分页批量采集

plaintext

分页采集 https://xxx.com/list .item 10

4. 数据管理 & 环境操作

plaintext

保存数据 行业资讯_20260614
清空Cookie
关闭浏览器

七、典型业务场景(结合赚钱计划)

场景 1:财经资讯 / 公告采集(对接 Stock Market Pro / AkShare)

  1. 定时爬取交易所公告、行业新闻、龙虎榜页面
  2. 自动提取标题、时间、正文、关联个股
  3. 结构化数据推送至量化分析模块,生成舆情评分
  4. 重要公告写入 CalDAV 生成提醒,存入 Agent Memory 归档

场景 2:研究素材采集(对接 Deep Research Pro)

  1. 批量爬取官网、期刊、行业报告页面
  2. 提取正文、参考文献、数据表格
  3. 直接转为研究素材,辅助撰写深度报告

场景 3:通用数据爬取 + 报表生成

  1. 采集榜单、统计数据 → 清洗后导出表格
  2. 联动 PPT 技能,自动生成数据图表与汇报页面

八、二次开发拓展方向

  1. 验证码识别:集成滑块、点选、图文验证码自动解析
  2. 分布式爬虫:多节点任务分发,提升大规模采集效率
  3. AI 智能选择器:无需手动写 CSS/XPath,AI 识别页面结构自动提取字段
  4. 文件批量下载:支持网页附件、图片、文档批量下载与归类
  5. API 对外输出:提供接口,供外部程序调用采集能力
  6. 可视化任务面板:图形化配置规则、查看任务进度、管理历史任务