自动化模块
. 模块概述
功能定位
Automation 模块是 AI Browser 的网页操作执行层承担三项主要职责:
-
动作执行 — 提供统一入口
executeAutomationAction根据动作类型分发到具体的 DOM 操作函数。
-
选择器适配 — 通过优先级有序的 CSS 选择器列表,适配百度、Google、Bing 等主流搜索引擎及通用网站结构。
-
兜底降级 — 当选择器匹配失败时提供滚动到底部、浏览器后退等兜底策略。
在架构中的位置
使用者语音 → VoiceSession → Input Pipeline → Phase 指令生成
↓
Browser Command Engine
↓
executeAutomationAction
↓
页面 DOM 操作
-
上游Input Pipeline 的 Phase 生成自动化指令,通过 content script 调用本模块。其实,
-
下游直接操作目标页面 DOM。
-
并行与
的浏览器命令引擎并行存在本模块专注于搜索引擎和媒体控制场景。
依赖关系
| 依赖 | 用途 |
| 统一日志(Logger。写入 |
| DOM 选择器集合 |
文件结构
src/automation/
├── index.ts # 公共导出
├── actions.ts # 动作执行器
└── selectors.ts # DOM 选择器集合
. 架构设计
整体架构图
graph TB
subgraph Automation Module
Entry
subgraph 动作分发层
OpenSite
Search
SiteSearch
OpenItem
PageNext
PagePrev
VideoPlay
VideoPause
end
subgraph 选择器层
SearchInput
SearchResult
NextPage
PrevPage
FindEl
FindEls
end
end
Entry --> OpenSite
Entry --> Search
Entry --> SiteSearch
Entry --> OpenItem
Entry --> PageNext
Entry --> PagePrev
Entry --> VideoPlay
Entry --> VideoPause
SiteSearch --> FindEl --> SearchInput
OpenItem --> FindEls --> SearchResult
PageNext --> FindEl --> NextPage
PagePrev --> FindEl --> PrevPage
主要设计模式 & 为什么这样设计
| 设计决策 | 理由 |
| 策略分发 ✅ | 统一入口降低上层调用复杂度,避免因分支散落导致维护困难。 |
| 优先级有序选择器 | 不同搜索引擎 DOM 差异大。优先匹配站点专属 selector 能明显提高命中率,减少“找不到搜索框”报错——这是多数使用者最常遇到的失败点。 |
| Synchronous 查找 | Spa 页面加载慢时同步查找可能返回空;但同步避免额外异步等待成本。针对此我们在关键动作加入经验性延迟,缓解“点击无效”问题。 |
| S双重提交机制 | `siteSearch` 同时触发 `Enter` 与 `form.submit`,解决部分框架只监听其中一种事件导致搜索失败——这正是使用者报告“输入后没有响应”的根源。 |
| `videoControl` 静默捕获错误 | AUTOPLAY 限制会阻止播放。我们捕获错误防止脚本中断,但也会让使用者感受不到播放失败——这是一处已知的体验缺口,需要 UI 层自行提示。 |
| `pageNext` / `pagePrev` 降级 | If selector missing,fallback to scroll or history.back;话说回来,避免“翻页按钮消失导致卡死”。怎么说呢,但在无限滚动页面这种降级可能不符合预期——属于可改进空间。自动化模块
功能定位
-
动作执行:
提供统一入口
executeAutomationAction,根据动作类型分发到具体的 DOM 操作函数。
-
选择器适配:
通过优先级有序的 CSS 选择器列表,兼容百度、Google、Bing 等主流搜索引擎及通用网站结构。
-
兜底降级:
当选择器匹配失败时,提供滚动到底部、浏览器后退等兜底策略。
\*
在架构中的位置
mermaid
graph TB
subgraph Automation Module
Entry
subgraph 动作分发层
OpenSite
Search
SiteSearch
OpenItem
PageNext
PagePrev
VideoPlay
VideoPause
end
subgraph 选择器层
SearchInput
SearchResult
NextPage
PrevPage
FindEl)
FindEls)
end
end
Entry-->OpenSite
Entry-->Search
Entry-->SiteSearch
Entry-->OpenItem
Entry-->PageNext
Entry-->PagePrev
Entry-->VideoPlay
Entry-->VideoPause
SiteSearch-->FindEl-->SearchInput
OpenItem-->FindEls-->SearchResult
PageNext-->FindEl-->NextPage
PagePrev-->FindEl-->PrevPage
**Note**: 上面 Mermaid 图仅用于说明结构,请确保渲染环境支持。---
### 主要设计模式 & 为什么这样设计
| 设计决策 / 痛点对应方法 |
背后原因 & 使用者体验影响 |
\*\*
\*\*
\*\*\*\*
\*\*
|
**策略分发**
统一入口 executeAutomationAction,使用 switch 分发至各子函数。怎么说呢,* 痛点*: 多入口导致调用混乱。* 解决*: 单一入口简化上层调用逻辑。\*\*
保持代码可读性与可维护性;话说回来,每个子函数返回统一 ActionResult 。上层可统一处理成功/失败信息。\*\*/ tr \*/
\*\*
|
\*\*
|
**优先级有序选择 器**
* 痛点*: “搜索框未找到”是最常见报错。* 解决*: 将站点专属 selector 放前面提高命中率;通用 selector 为后备。\*\*/ td \*/
|
不同搜索引擎 DOM 差异大;精确匹配→快速成功,若失效则回落到宽松 selector 防止全局失效。\*\*/ tr \*/
|
\*\*
|
**同步查找 + 延迟**
* 痛点*: SPA 页面加载慢导致点击无效。* 解决*: 在关键操作 前加入经验延迟,保证 DOM 已渲染。话说回来,\*\*/ td \*/
|
避免因异步等待导致代码复杂度激增。同时兼顾多数网络环境下足够可靠。
若出现更高延迟需求,可在 UI 层自行配置重试间隔。
按理说,\*\*/ tr \*/
|
\*\*
|
**双重提交机制**
* 痛点*: 某些框架只监听其中一种事件导致搜索不触发。* 解决*: 同时派发键盘事件和表单提交,提高兼容性。\*\*/ td \*/
|
覆盖 React/Vue 等合成事件程序。实现“一次输入,多种触发”。\*\*/ tr \*/
|
\*\*
|
**视频播放静默捕获**
* 痛点*: 浏览器 autoplay 策略阻止 video.play,导致脚本抛异常。* 解决*: 使用 .catch=>{}) 静默处理,不打断整体流程。\*\*/ td \*/
|
虽然使用者可能感受不到播放失败,但至少不会影响后续指令执行。UI 层可根据需求自行弹出提示。说起来,\*\*/ tr \*/
|
\*\*
|
**翻页降级策略**
* 痛点*: 部分页面没有明确“下一页”按钮。* 解决*: 若未匹配到按钮,则滚动到底部或回退历史记录,以免指令卡死。\*\*/ td \*/
|
满足单页或无限滚动页面的基本需求,但仍需在特定业务场景中做二次定制。\*\*/ tr \*/
<\/tbody>\<\/table>
---
## 主要类型定义
### AutomationAction
ts
type AutomationAction =
| 'open_site' // 打开网站
| 'search' // 全网搜索
| 'site_search' // 站内搜索
| 'open_item' // 点击第 N 个搜索结果
| 'page_next' // 下一页
| 'page_prev' // 上一页
| 'video_play' // 视频播放
| 'video_pause';// 视频暂停
### ActionResult
ts
interface ActionResult {
success: boolean;// 是否成功
message: string;// 人类可读描述
}
### ActionParams
ts
{
从url?来看,string,话说回来,// open_site 使用
keyword?: string,// search / site_search 使用
至于index?,number,// open_item 使用
}
### Selector 集合
| 常量名 |
数量 |
用途 |
| SEARCH_INPUT_SELECTORS 13 搜索输入框定位
SEARCH_RESULT_SELECTORS13结果链接定位
NEXT_PAGE_SELECTORS9下一页按钮定位
PREV_PAGE_SELECTORS7上一页按钮定位 |
实现细节 (actions.ts & selectors.ts)
动作执行入口
ts
export function executeAutomationAction(
action这方面。AutomationAction,params: { url?
: string,keyword?: string,index?: number }
): ActionResult {
switch {
case 'open_site': return openSite;case 'search': return search;case 'site_search': return siteSearch;case 'open_item': return openItem;说起来,case 'page_next': return pageNext;case 'page_prev': return pagePrev;不过,case 'video_play': return videoControl;case 'video_pause': return videoControl;其实,default:
return { success:false。message:`未知动作: ${action}` };}
}
各子动作实现要点
openSite
-
`url` 必须以 `http://` 开头;若缺失自动补全 `https://`。话说回来,
-
`window.open` 在新标签打开。
-
`url` 空值 → 返回 `{success:false,message:'未指定网址'}`。
\*
search
window.open) 固定使用百度搜索,引入硬编码限制。.
siteSearch
-
`findElement` 定位当前页面搜索框;老实说,若未找到返回错误提示。
-
`input.value = keyword`;派发 `input` 与 `change` 原生事件,使 React/Vue 响应式更新。怎么说呢,
-
`setTimeout` 后同时派发:
-
`KeyboardEvent` 模拟回车;
-
`closest?.dispatchEvent)` 表单提交.
— 双重提交确保兼容不同实现。
openItem
-
`findElements` 获得全部结果链接数组.
-
`index -1` 获取目标元素;若索引越界返回 `"没有第 N 个结果"` 错误信息.
-
`setTimeout` 后 `target.click` 完成打开.
pageNext / pagePrev
-
`findElement` 若匹配成功直接 click.
-
*未匹配:*
-
`pageNext` → `window.scrollTo`;对应 **翻页降级不精准痛点**,在无限滚动页面可能不是预期行为。— `pagePrev` → `window.history.back`.
videoControl
• 查询首个 ` |
|
。