Skip to content

automa 与 handler API 手册

面向注入执行环境的自定义脚本。运行时直接可用 automahandler,无需 import。

执行方式

脚本通过 new Function('automa', 'handler', ...) 注入执行,支持顶层 await。建议每步调用携带 description,便于日志排查。

1. 通用 block 入参结构

绝大多数 handler 方法都接收一个 block 对象:

js
{
  id?: string,                 // 可选,步骤ID;不传会自动生成
  description?: string,        // 可选,步骤说明(强烈建议传)
  data?: { ... }               // 具体方法参数
}

1.1 通用选择器参数(多数 DOM 类方法适用)

  • data.findBy?: 'cssSelector' | 'xpath':选择器类型,默认通常是 CSS。
  • data.selector?: string:选择器字符串。
  • data.element?: HTMLElement:直接传元素对象(优先级通常高于 selector)。
  • data.point?: { x: number; y: number }:坐标点击/定位。
  • data.waitForSelector?: boolean:是否等待元素出现。
  • data.waitSelectorTimeout?: number:等待超时(毫秒)。
  • data.multiple?: boolean:是否匹配多个元素。

1.2 通用返回约定

为便于业务层统一处理,推荐按以下方式消费返回值:

  • 布尔型方法true/false,用于判断步骤是否执行成功。
  • 对象型方法:优先判断 success 字段;无 success 时按业务字段判断。
  • 数据型方法:直接返回目标数据(如字符串、数组、对象、数字)。
  • 异常处理:所有 handler 调用均可能抛出异常,建议统一使用 try/catchautoma.wrapPromise

2. automa API(preload 注入)

automa = lodash 能力 + 注入环境增强方法。

2.1 基础能力

  • automa.config

    • 含义:当前流程配置对象(窗口 ID、标题、心跳参数等)。
    • 用途:日志标记、流程信息展示。
  • automa.diffObjects(a, b)

    • 含义:对象差异比较。
    • 场景:检测页面数据变化、增量上报。
  • automa.wrapPromise(fnOrPromise)

    • 含义:Promise 包装,减少 try/catch 样板。
    • 场景:接口或复杂步骤容错。
  • automa.formatTime(date, format)

    • 常用格式:yyyy-MM-ddyyyyMMddyyyy-MM-dd HH:mm:ss
  • automa.parseTime(value)

    • 含义:时间解析。
  • automa.parseUrlParam(url) / automa.getUrlParamObject(url)

    • 含义:URL 参数解析。
  • automa.getBoundingClientRect(element)

    • 含义:增强版元素位置获取,适配自动化点击场景。
  • automa.alert(message)

    • 含义:预加载层消息提示。

2.2 请求监听与请求信息

  • automa.addApiResponseListener(urlPart, listener)

    • 入参:
      • urlPart: string:URL 包含匹配(不是完整等值匹配)。
      • listener: (info) => void
    • info 常见字段:
      • url, method, status
      • requestHeaders, responseHeaders
      • responseText, body, elapsedTime
    • 说明:首次调用会注入 XHR + fetch 拦截器。
  • automa.removeApiResponseListener(urlPart, listener?)

    • 不传 listener 时,清空该 urlPart 下所有监听器。
  • automa.resetRequest()

    • 含义:将“注入前缓存的请求信息”重新回放给监听器。
    • 场景:脚本初始化后补收页面早期请求。
  • automa.getRequestHeader(name: string)

    • 含义:按名称读取请求头(内部会做一次重试)。
  • automa.getRequestQuery(name: string)

    • 含义:按名称读取请求 query(内部会做一次重试)。
  • automa.addServerResponseListener(action, listener)

    • 入参:
      • action: string
      • listener: (args: any) => any | Promise<any>
    • 场景:主进程下发 server 消息给页面脚本处理。

3. handler API(按能力分组)

handler 是自动化动作执行器。
下面每个方法都列出:入参、返回值、注意事项、示例

3.1 流程与日志

3.1.1 handler.start()

  • 入参:无
  • 返回值:void
  • 用途:流程起始标记;建议在脚本开始阶段调用一次。

3.1.2 handler.controllerWorkflow(block)

  • 入参:
    • block.type: 'start' | 'stop' | 'exec' | 'reload'
    • block.data.url?: string
    • block.data.level: string(常用:info / warning / error
    • block.data.status: string(常用:start / success / warning / error
    • block.data.message: string
    • 扩展:业务里常传 block.data.type: 'restart' + timeout 作为 reload 策略
  • 返回值:一般为执行结果对象(由主进程处理结果决定)
  • 示例:
js
await handler.controllerWorkflow({
  description: '异常停止流程',
  type: 'stop',
  data: {
    url: location.href,
    level: 'error',
    status: 'error',
    message: '关键元素缺失,停止执行'
  }
});

3.1.3 handler.logData(block)

  • 入参:
    • block.data.json?: any
    • block.data.type?: 'info' | 'error' | 'warning' | 'debug' | 'trace' | 'fatal' | 'success'
  • 返回值:日志写入结果对象
  • 建议:把关键上下文(类目、页码、日期)写进 json

3.1.4 handler.statistics(block)

  • 入参:
    • block.data.bizName?: string
    • block.data.message?: string
    • block.data.startedAt?: number
    • block.data.endedAt?: number
  • 返回值:统计写入结果

3.2 变量、请求、文件

3.2.1 handler.variables(block)

  • 入参:
    • block.data.variableName?: string
    • block.data.variableValue?: any
    • block.data.variableAction?: 'get' | 'set' | 'delete'
  • 默认行为:不传 variableAction 时按读取处理。
  • 返回值:变量结果对象(读取时可通过 res.value 取值)
  • 示例:
js
await handler.variables({
  description: '保存运行断点',
  data: {
    variableName: 'shop_progress',
    variableValue: { page: 3, ts: Date.now() },
    variableAction: 'set'
  }
});

3.2.2 handler.webhook(block)

  • 入参:
    • block.data.url: string(必须是 http/https 开头)
    • block.data.method?: string
    • block.data.body?: any
    • 实际项目常扩展:contentTyperesponseTypetimeoutheaders
  • 返回值:主进程请求结果
  • 注意:
    • URL 非 http 开头会直接抛错 url error
    • 适合跨域/系统层请求,稳定性通常高于页面内 fetch

3.2.3 handler.http(block)

  • 入参:
    • block.onError.retries?: number 当前已重试次数(内部维护)
    • block.onError.retryTime?: number 每次重试间隔,默认 3000ms
    • block.onError.maxRetries?: number 最大重试次数,默认 3
    • block.data.url: string(必填)
    • block.data.method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'(默认 POST
    • block.data.headers?: Record<string,string> | Array<>
    • block.data.params?: Record<string,any> | Array<>
    • block.data.body?: string | object
    • block.data.contentType?: 'json' | 'form' | 'formData' | 'text'(默认 json
    • block.data.autoAddHeader?: boolean(默认 true,自动补 Content-Type)
    • block.data.responseType?: 'json' | 'text' | 'blob' | 'buffer'(默认 json
    • block.data.timeout?: number(默认 5000ms<=0 视为不启用 abort)
    • block.data.sleep?: number 请求前延迟(默认随机 5-10 秒)
    • block.data.mode?: 'cors' | 'no-cors' | 'same-origin'
    • block.data.credentials?: 'include' | 'same-origin' | 'omit'(默认 include
  • 返回值:
    • responseType 返回:json/text/blob/arrayBuffer/Response
  • 重要细节:
    • params 会自动附加 _={timestamp} 防缓存。
    • GET/HEAD 不发送 body。
    • 失败后按重试配置自动重试。

3.2.4 handler.readFile(block)

  • 入参:
    • block.data.path: string
    • block.data.encoding?: string
  • 返回值:文件内容(字符串、对象或数组,取决于文件类型与解析方式)
  • 常见用法:
    • 读取 api.json
    • 读取 Excel/CSV 输入(项目扩展能力)

3.3 元素定位与操作

3.3.1 handler.elementExists(block)

  • 入参:
    • 通用选择器参数
    • block.data.tryCount?: number
    • block.data.timeout?: number(重试间隔/等待参数)
  • 返回值:boolean

3.3.2 handler.getText(block)

  • 入参:
    • 通用选择器参数
    • block.data.regex?: string
    • block.data.regexExp?: string[]
    • block.data.prefixText?: string
    • block.data.suffixText?: string
    • block.data.includeTags?: boolean
    • block.data.useTextContent?: boolean
  • 返回值:文本字符串或文本数组

3.3.3 handler.forms(block)

  • 入参:
    • 通用选择器参数
    • block.data.type?: 'text-field' | 'select' | 'checkbox' | 'radio'
    • block.data.value?: string
    • block.data.getValue?: boolean
    • block.data.clearValue?: boolean
    • block.data.delay?: number 输入间隔
  • 返回值:设置结果或读取值

3.3.4 handler.eventClick(block)

  • 入参:
    • block.clickType?: 'dom' | 'electron' | 'native'(默认 native
    • block.restoreMouse?: boolean
    • block.data.element?: HTMLElement(优先)
    • block.data.point?: ``
    • 或通用选择器参数
  • 返回值:点击执行结果(truefalse 或带 success 字段的对象)
  • 实现行为:
    • 优先按 element 点击;
    • 其次按 point 坐标点击;
    • 否则根据 selector 查找后点击。

3.3.5 handler.hoverElement(block)

  • 入参:通用选择器参数
  • 返回值:执行结果

3.3.6 handler.triggerEvent(block)

  • 入参:
    • 通用选择器参数
    • block.data.eventType?: 'mouse-event' | 'keyboard-event' | 'custom'
    • block.data.eventName?: string
    • block.data.eventParams?: Record&lt;string, any&gt;
  • 返回值:执行结果

3.3.7 handler.uploadFile(block)

  • 入参:
    • 通用选择器参数
    • block.data.filePaths: string[](必填)
  • 返回值:上传执行结果

3.3.8 handler.verifySelector(block)

  • 入参:通用选择器参数
  • 返回值:选择器验证结果(是否可定位/定位详情)

3.3.9 handler.attributeValue(block)

  • 入参:
    • 通用选择器参数
    • block.data.attributeName: string
    • block.data.attributeValue?: stringset 时使用)
    • block.data.action?: 'get' | 'set'
    • block.data.multiple?: boolean
  • 返回值:属性值或设置结果

3.3.10 handler.elementScroll(block)

  • 入参:
    • 通用选择器参数
    • block.data.smooth?: boolean
    • block.data.scrollIntoView?: boolean
    • block.data.scrollX?: number
    • block.data.scrollY?: number
    • block.data.incX?: boolean
    • block.data.incY?: boolean
  • 返回值:滚动执行结果

3.3.11 handler.createElement(block)

  • 入参:
    • block.id: string
    • 通用选择器参数
    • block.data.insertAt: 'after' | 'before' | 'next-sibling' | 'prev-sibling' | 'replace'
    • block.data.html: string
    • block.data.css?: string
    • block.data.dontInjectJS?: boolean
    • block.data.preloadScripts?: Array&lt;{ type: string; script: string }&gt;
    • block.data.automaScript?: string
    • block.data.javascript?: string
  • 返回值:插入结果

3.3.12 handler.saveAssets(block)

  • 入参:通用选择器参数 + multiple?: boolean
  • 返回值:资源保存结果(图片、链接等)

3.3.13 handler.switchTo(block)

  • 入参:通用选择器参数(多用于 iframe)
  • 返回值:切换结果
  • 入参:通用选择器参数 + openInNewTab?: boolean
  • 返回值:跳转结果

3.4 鼠标、键盘、交互

3.4.1 handler.mouse(block)

  • 入参:
    • block.data.x?: number
    • block.data.y?: number
    • block.data.button?: 'left' | 'right' | 'middle'
    • block.data.clickType?: 'click' | 'dblclick' | 'mousedown' | 'mouseup'
  • 返回值:执行结果

3.4.2 handler.keyboard(block)

  • 入参:
    • block.data.key?: string
    • block.data.code?: string
    • block.data.modifiers?: string[]
  • 返回值:执行结果

3.4.3 handler.pressKey(block)

  • 入参:
    • block.data.selector?: string
    • block.data.keys?: string(组合键,使用 + 分隔)
    • block.data.keysToPress?: string
    • block.data.action?: 'press-key' | 'multiple-keys'
    • block.data.pressTime?: number
  • 返回值:执行结果

3.4.4 handler.drag(block)

  • 入参:
    • block.data.fromX?: number
    • block.data.fromY?: number
    • block.data.toX?: number
    • block.data.toY?: number
    • 业务脚本中也常见扩展:startPoint/endPoint/options
  • 返回值:拖拽结果(常见含 success

3.5 截图、识别、系统与数据

3.5.1 handler.takeScreenshot(block)

  • 入参:
    • block.options.format?: 'png' | 'jpeg'
    • block.options.quality?: number(1-100)
    • block.options.save?: boolean
    • block.data.type?: 'fullpage' | 'element' | 'recognize'
    • block.data.selector?: string
  • 返回值:截图数据或文件信息

3.5.2 handler.recognize(block)

  • 入参:
    • block.data.image: string(base64)
    • block.data.type?: string
  • 返回值:识别结果(OCR/图像分析)
  • 入参:
    • block.data.name?: string
    • block.data.action?: 'get' | 'set' | 'delete'
  • 返回值:Cookie 结果

3.5.4 handler.screen(block)

  • 入参:
    • block.data.action?: string
  • 返回值:屏幕能力执行结果

3.5.5 handler.ds(block)

  • 入参:
    • block.data.tableName: string
    • block.data.action: string(最终会作为 TypeORM Repository 方法名执行)
    • block.data.args?: any建议传数组,会被 ...args 展开)
  • 返回值:数据源操作结果(取决于 action
  • 执行语义:
    • 页面调用 handler.ds(...) 后,会进入数据源执行器。
    • 数据源执行器会按 action 调用仓储层同名方法(等价于 repository[action](...args))。
  • 重要约束:
    • 数据源 key 使用 winId(当前流程窗口 ID),数据源不存在会抛错。
    • tableName 必须是当前数据源里已定义的表名,否则抛错。
    • action 必须是 repository 上存在的方法,否则抛错。
    • args 不是数组,...args 可能导致参数展开异常,推荐统一数组格式。

推荐 action 与参数模板

  • save(插入/更新)
    • args: [entityOrEntities]
    • 示例:[{ id: 1, name: 'A' }]{ id: 1, name: 'A' }
  • find(查询列表)
    • args: [findOptions]
    • 示例:[{ where: { shopId: 1001 }, order: { id: 'DESC' }, take: 20 }]
  • findOne(查询单条)
    • args: [findOneOptions]
    • 示例:[{ where: { id: 1 } }]
  • update(按条件更新)
    • args: [criteria, partialEntity]
    • 示例:[{ id: 1 }, { status: 'done' }]
  • delete(按条件删除)
    • args: [criteria]
    • 示例:[{ id: 1 }]
  • count(计数)
    • args: [countOptions]
    • 示例:[{ where: { status: 'done' } }]
  • clear(清空表)
    • args: []

返回值参考(按 action)

  • save:返回保存后的实体(单条或数组)
  • find:返回数组
  • findOne:返回单条实体或 null
  • update:返回 UpdateResult
  • delete:返回 DeleteResult
  • count:返回 number
  • clear:通常返回 void
  • clear:返回 void

错误排查(高频)

  • DataSource with key xxx does not exist
    • 原因:当前流程数据源未初始化或已销毁。
    • 处理:确认流程是否已创建对应数据源,再执行 ds
  • Repository for table xxx does not exist
    • 原因:表名不在该流程的数据源配置中。
    • 处理:核对 tableName 与 worker/tableConfig。
  • Action xxx does not exist on repository
    • 原因:action 不是 TypeORM Repository 方法。
    • 处理:改用 save/find/findOne/update/delete/count/clear 等可用方法。

最佳实践示例

js
// 1) 写入一条采集结果
await handler.ds({
  description: '写入商品数据',
  data: {
    tableName: 'product_daily',
    action: 'save',
    args: [{ productId: 123, date: '2026-04-28', click: 88 }]
  }
});

// 2) 查询待处理数据
const rows = await handler.ds({
  description: '查询待处理商品',
  data: {
    tableName: 'product_daily',
    action: 'find',
    args: [{ where: { synced: 0 }, take: 100 }]
  }
});

// 3) 更新状态
await handler.ds({
  description: '更新同步状态',
  data: {
    tableName: 'product_daily',
    action: 'update',
    args: [{ productId: 123, date: '2026-04-28' }, { synced: 1, syncedAt: Date.now() }]
  }
});

3.5.6 handler.loopData(block)

  • 入参:
    • 通用选择器参数
    • block.data.$frameSelector?: string
    • block.data.loopId?: string
    • block.onlyGenerate?: boolean
  • 返回值:循环数据结果

3.5.7 handler.loopElements(block)

  • 入参:
    • block.id: string
    • block.data.$frameSelector?: string
    • block.data.findBy?: 'cssSelector' | 'xpath'
    • block.data.selector?: string
    • block.data.loopAttrId?: string
    • block.data.index?: number
    • block.data.type?: 'scroll-down' | 'scroll-up' | 'click-element' | 'click-link'
    • block.data.scrollToBottom?: boolean
    • block.data.actionElSelector?: string
    • block.data.actionElMaxWaitTime?: number(秒)
    • block.data.onlyClickLink?: boolean
  • 返回值:
    • 常见为“循环选择器数组”或 { continue: true }
  • 关键行为:
    • scroll-*:基于滚动加载新元素。
    • click-element:点击触发加载后再采集。
    • click-link + onlyClickLink:直接跳转链接并返回。

3.5.8 handler.delay(blockOrNumber)

  • 入参:
    • block.delayTime?: number
    • block.data.delayTime?: number
    • block.data.minTime?: number
    • block.data.maxTime?: number
  • 返回值:Promise&lt;void&gt;

3.5.9 handler.focus(block)

  • 入参:无特定字段
  • 返回值:聚焦结果

3.5.10 handler.getRequestHeader(block) / handler.getRequestQuery(block)

  • 入参:
    • block.data.name?: string
  • 返回值:指定请求头/请求参数值
  • 说明:与 automa.getRequestHeader/getRequestQuery 类似,调用链不同。

3.5.11 handler.clipboard()

  • 入参:无
  • 返回值:Promise&lt;string&gt;,返回当前页面选中文本
  • 行为说明:
    • 会读取当前选区文本(window.getSelection().toString()
    • 会将选区文本写入系统剪贴板
  • 用例:
js
const copiedText = await handler.clipboard();
await handler.logData({
  description: '记录复制内容',
  data: { type: 'info', json: { copiedText } }
});

4. 实战脚本模板(推荐)

js
/* eslint-disable no-undef */
await handler.delay({ delayTime: 1000 });

const currentUrl = `${location.origin}${location.pathname}`;
if (!currentUrl.includes('sycm.taobao.com')) return;

const state = await handler.variables({
  description: '读取断点',
  data: { variableName: 'sycm_progress', variableAction: 'get' }
});

const exists = await handler.elementExists({
  description: '检查查询按钮',
  data: { findBy: 'cssSelector', selector: '.search-btn', waitForSelector: true, waitSelectorTimeout: 8000 }
});

if (!exists) {
  await handler.controllerWorkflow({
    type: 'stop',
    data: {
      url: location.href,
      level: 'error',
      status: 'error',
      message: '查询按钮不存在,停止流程'
    }
  });
  return;
}

await handler.eventClick({
  description: '点击查询',
  clickType: 'native',
  data: { findBy: 'cssSelector', selector: '.search-btn' }
});

await handler.statistics({
  description: '记录成功统计',
  data: {
    bizName: 'SYCM脚本示例',
    message: '执行成功',
    startedAt: Date.now() - 5000,
    endedAt: Date.now()
  }
});

5. 最佳实践与避坑清单

  • 所有关键步骤都带 description,日志可读性会显著提升。
  • 变量操作显式写 variableAction,避免隐式默认导致误解。
  • webhook/http 请求都设置 timeout 和重试策略,避免流程卡死。
  • 涉及循环抓取时,必须落断点变量(页码/索引/日期/时间戳)。
  • UI 容易抖动的页面优先用 clickType: 'native'electron,并配合等待。
  • 流程失败时优先 controllerWorkflow({ type: 'stop' | 'reload' }),不要 silent fail。
  • 页面守卫统一使用 location.origin + location.pathname

6. 方法用例总表(每个方法一个示例)

本节用于“即抄即用”。示例以最小可运行为目标,字段可按业务扩展。

6.0 方法覆盖清单

  • automaconfigdiffObjectswrapPromiseformatTimeparseTimeparseUrlParamgetUrlParamObjectgetBoundingClientRectalertipcRendereraddApiResponseListenerremoveApiResponseListenerresetRequestgetRequestHeadergetRequestQueryaddServerResponseListener
  • handlerstartcontrollerWorkflowlogDatastatisticsvariableswebhookhttpreadFileelementExistsgetTextformseventClickhoverElementtriggerEventuploadFileverifySelectorattributeValueelementScrollcreateElementsaveAssetsswitchTolinkmousekeyboardpressKeydragdelayfocustakeScreenshotrecognizecookiescreendsloopDataloopElementsgetRequestHeadergetRequestQueryclipboard

6.1 automa 方法用例

js
// automa.diffObjects
const diff = automa.diffObjects({ a: 1 }, { a: 2 });

// automa.wrapPromise
const [err, data] = await automa.wrapPromise(fetch('/api/user').then(r => r.json()));

// automa.formatTime / parseTime
const day = automa.formatTime(new Date(), 'yyyy-MM-dd');
const ts = automa.parseTime('2026-04-28 10:00:00');

// automa.parseUrlParam / getUrlParamObject
const queryStr = automa.parseUrlParam(location.href);
const queryObj = automa.getUrlParamObject(location.href);

// automa.getBoundingClientRect
const rect = await automa.getBoundingClientRect(document.body);

// automa.alert
automa.alert('脚本已启动');

// automa.getRequestHeader / getRequestQuery
const token = await automa.getRequestHeader('authorization');
const uid = await automa.getRequestQuery('uid');

// automa.addApiResponseListener / removeApiResponseListener / resetRequest
const onUser = info => console.log('user api:', info.status, info.url);
automa.addApiResponseListener('/api/user', onUser);
await automa.resetRequest();
automa.removeApiResponseListener('/api/user', onUser);

// automa.addServerResponseListener
automa.addServerResponseListener('script', async args => ({ ok: true, args }));

6.2 handler 流程与日志

js
handler.start();

await handler.controllerWorkflow({
  description: '结束流程',
  type: 'stop',
  data: { url: location.href, level: 'info', status: 'success', message: '执行完成' }
});

await handler.logData({
  description: '记录关键日志',
  data: { type: 'info', json: { stage: 'login', ok: true } }
});

await handler.statistics({
  description: '记录统计',
  data: { bizName: '登录流程', message: '成功1次', startedAt: Date.now() - 3000, endedAt: Date.now() }
});

6.3 handler 数据与请求

js
// variables
await handler.variables({ data: { variableName: 'token', variableValue: 'abc', variableAction: 'set' } });
const tokenVar = await handler.variables({ data: { variableName: 'token', variableAction: 'get' } });

// webhook
const webhookRes = await handler.webhook({
  data: { url: 'https://example.com/hook', method: 'POST', body: { id: 1 } }
});

// http
const httpRes = await handler.http({
  data: {
    url: 'https://example.com/api/list',
    method: 'GET',
    params: { page: 1, size: 20 },
    responseType: 'json',
    timeout: 8000
  }
});

// readFile
const configText = await handler.readFile({ data: { path: './config/api.json', encoding: 'utf-8' } });

// ds
await handler.ds({
  data: { tableName: 'orders', action: 'save', args: [{ orderId: 'A001', amount: 99.9 }] }
});
const count = await handler.ds({
  data: { tableName: 'orders', action: 'count', args: [{ where: { amount: 99.9 } }] }
});

6.4 handler 元素与表单

js
// elementExists
const hasSubmit = await handler.elementExists({ data: { findBy: 'cssSelector', selector: '#submit' } });

// getText
const title = await handler.getText({ data: { findBy: 'cssSelector', selector: 'h1', useTextContent: true } });

// forms
await handler.forms({
  data: { findBy: 'cssSelector', selector: '#username', type: 'text-field', value: 'demo', delay: 200 }
});

// eventClick
await handler.eventClick({ clickType: 'native', data: { findBy: 'cssSelector', selector: '#submit' } });

// hoverElement
await handler.hoverElement({ data: { findBy: 'cssSelector', selector: '.menu-item' } });

// triggerEvent
await handler.triggerEvent({
  data: { findBy: 'cssSelector', selector: '#btn', eventType: 'mouse-event', eventName: 'click' }
});

// uploadFile
await handler.uploadFile({
  data: { findBy: 'cssSelector', selector: 'input[type=file]', filePaths: ['/tmp/a.png'] }
});

// verifySelector
const verifyRes = await handler.verifySelector({ data: { findBy: 'cssSelector', selector: '.table-row' } });

// attributeValue
const href = await handler.attributeValue({
  data: { findBy: 'cssSelector', selector: 'a.detail', attributeName: 'href', action: 'get' }
});

// elementScroll
await handler.elementScroll({
  data: { findBy: 'cssSelector', selector: '.list', scrollY: 500, smooth: true, incY: true }
});

// createElement
await handler.createElement({
  id: 'create-tips',
  data: { findBy: 'cssSelector', selector: 'body', insertAt: 'before', html: '<div id="tips">运行中</div>' }
});

// saveAssets
await handler.saveAssets({ data: { findBy: 'cssSelector', selector: 'img.preview', multiple: true } });

// switchTo
await handler.switchTo({ data: { findBy: 'cssSelector', selector: 'iframe#child' } });

// link
await handler.link({ data: { findBy: 'cssSelector', selector: 'a.next-page', openInNewTab: false } });

6.5 handler 交互控制

js
// mouse
await handler.mouse({ data: { x: 300, y: 420, button: 'left', clickType: 'click' } });

// keyboard
await handler.keyboard({ data: { key: 'a', code: 'KeyA', modifiers: ['control'] } });

// pressKey
await handler.pressKey({ data: { selector: '#keyword', action: 'multiple-keys', keys: 'Control+A' } });

// drag
await handler.drag({ data: { fromX: 200, fromY: 300, toX: 600, toY: 300 } });

// delay
await handler.delay(1200);
await handler.delay({ data: { minTime: 1000, maxTime: 3000 } });

// focus
await handler.focus();

6.6 handler 图像、系统与循环

js
// takeScreenshot
const shot = await handler.takeScreenshot({
  options: { format: 'png', quality: 90, save: true },
  data: { type: 'fullpage' }
});

// recognize
const recRes = await handler.recognize({ data: { image: 'base64-xxx', type: 'ocr' } });

// cookie
const cookieStr = await handler.cookie({ data: { action: 'get' } });
await handler.cookie({ data: { name: 'sid', action: 'delete' } });

// screen
const screenRes = await handler.screen({ data: { action: 'capture' } });

// loopData
const rows = await handler.loopData({
  data: { findBy: 'cssSelector', selector: '.row', loopId: 'list-1', multiple: true }
});

// loopElements
const loopSelectors = await handler.loopElements({
  id: 'loop-1',
  data: {
    findBy: 'cssSelector',
    selector: '.goods-item',
    loopAttrId: 'goods-loop',
    index: 0,
    type: 'scroll-down',
    actionElMaxWaitTime: 3
  }
});

// getRequestHeader / getRequestQuery
const reqHeader = await handler.getRequestHeader({ data: { name: 'authorization' } });
const reqQuery = await handler.getRequestQuery({ data: { name: 'token' } });

// clipboard
const copied = await handler.clipboard();

企业级桌面 RPA 自动化平台