Playwright AI智能定位元素引擎
项目简介
Precision Locator 是一款基于 Playwright 和大语言模型的智能页面元素定位 MCP 服务,旨在解决自动化测试和 RPA 场景中元素定位不稳定的痛点。通过独创的四级降级策略(本地 OCR → 文本定位 → 截图 LLM → 坐标定位),实现从自然语言指令到精准元素操作的自动转换。
核心特性:
-
四级降级策略:Level 0 零 Token → Level 1 低 Token → Level 2 中 Token → Level 3 终极兜底
-
坐标→稳定定位器转换:像素坐标反查 DOM 属性,消除分辨率依赖
-
本地视觉定位:PaddleOCR + OpenCV 模板匹配,零 Token 消耗
-
翻译检测:自动拦截 LLM 将中文元素文本翻译为英文的行为
-
图标定位:表头筛选图标、操作按钮等非文字元素的精准定位
-
多模型支持:OpenAI / 智谱 / MiniMax / 通义千问 / DeepSeek / Moonshot
-
MCP 协议:通过 Model Context Protocol 与 AI 客户端无缝集成
-
模块化架构:11 个独立模块,每个类单独文件,开源项目级代码质量
开源地址: https://github.com/zxpFreesky/ai_locator_agent
核心架构
用户指令 → SmartExecutor → 四级降级策略 → Playwright 操作
│
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
Level 0 Level 1 Level 2/3
(零Token) (低Token) (中/高Token)
┌──────────┐ ┌──────────────────┐ ┌──────────────────┐
│PaddleOCR │ │ DOMExtractor │ │ScreenshotLocator │
│OpenCV │ │ LocatorAgent │ │ 多模态LLM分析 │
│模板匹配 │ │ VisualLocator │ │ 定位器/坐标 │
└────┬─────┘ │ SafeBuilder │ └────────┬─────────┘
│ │ FallbackRule │ │
│ │ DirectQuery │ │
│ └──────────────────┘ │
│ │ │
└────────┬───────────┘ │
▼ ▼
┌──────────────────────────────────────────────────┐
│ 坐标 → 稳定定位器转换 │
│ document.elementFromPoint(x,y) │
│ → data-testid > placeholder > role+name │
│ > text > class │
└──────────────────────────────────────────────────┘
项目结构
precision_locator/
├── __init__.py # 包入口,统一导出
├── utils.py # 工具函数(日志、清洗、中文检测)
├── dom_extractor.py # DOM 紧凑采集器
├── llm_config.py # 多模型 LLM 配置(6家供应商)
├── locator_agent.py # AI 定位器生成(Level 1c)
├── visual_locator.py # DOM 上下文视觉定位(Level 1b)
├── screenshot_locator.py # 截图视觉定位(Level 2/3)
├── safe_locator.py # Playwright 定位器安全构建
├── local_vision.py # 本地 OCR + 模板匹配(Level 0)
├── executor.py # 智能执行器(核心调度引擎)
└── server.py # MCP Server 入口(9个工具)
四级降级策略详解
Level 0 — 本地视觉定位(零 Token 消耗)
使用 PaddleOCR 进行文字识别 + OpenCV 模板匹配,在本地完成元素定位,不消耗任何 LLM Token。
工作流程:
-
截取当前页面截图
-
PaddleOCR 识别所有文字区域
-
通过 bigram/trigram 分词从用户指令中提取搜索词
-
在 OCR 结果中搜索匹配文本,返回中心坐标
排序优先级: 最长搜索词匹配 > 最短文本长度 > 最高置信度
DOM 补充机制: 当 OCR 无法识别(如白色文字在透明背景上)时,自动降级到 DOM 属性查询,直接查询 placeholder/role/text 等属性生成定位器。
# bigram/trigram 分词示例
# 指令:"点击我的客户标签页"
chinese_chars = ['我', '的', '客', '户', '标', '签', '页']
# 4-gram: 我的客户, 的客户标, 客户标签, 户标签页
# 3-gram: 我的客, 的客户, 客户标, 户标签, 标签页
# 2-gram: 我的, 的客, 客户, 户标, 标签, 签页
Level 1 — 文本定位(低 Token 消耗)
五个子策略按顺序尝试:
|
子策略 |
优先级 |
说明 |
|---|---|---|
|
|
1a |
从指令提取关键词,匹配 DOM 的 |
|
|
1b |
复杂场景(表头/图标/弹窗)用 LLM + DOM 上下文 |
|
|
1c |
LLM 根据 DOM 结构生成定位器,后校验文本存在性 |
|
|
1d |
硬编码规则匹配常见 UI 模式 |
|
|
1e |
Playwright 原生 API 在页面中搜索 |
Level 2 — 截图 + 多模态 LLM(中 Token 消耗)
将页面截图发送给多模态 LLM(GPT-4o / GLM-4V / Qwen-VL),直接生成 Playwright 定位器表达式。
Level 3 — LLM 坐标定位(高 Token 消耗,终极兜底)
多模态 LLM 分析截图返回目标元素的像素坐标 {x, y},然后通过坐标→稳定定位器转换机制生成不依赖分辨率的定位器。
核心模块详解
1. DOMExtractor - DOM 紧凑采集器
通过注入 JavaScript 脚本到页面,提取所有可交互元素的属性。
关键功能:
-
强制采集关键交互元素(Radio、Tab、Menu),即使不可见也保留
-
支持提示词相关性排序(hint 参数),提高后续 AI 定位精度
-
兼容 Element Plus 等 UI 框架(
el-tabs__item、el-radio-button) -
自动推导隐式 role(
button→"button"、a→"link") -
isTab 检测使用
\b词边界避免误匹配(\bel-tabs__item\b不匹配el-table)
提取的元素信息:
|
字段 |
说明 |
示例 |
|---|---|---|
|
tag |
标签名 |
|
|
text |
显示文本 |
|
|
placeholder |
占位符文本 |
|
|
role |
ARIA 角色 |
|
|
dataTestId |
测试 ID |
|
|
relevance |
相关度评分 |
80 |
|
isTab / isRadio / isMenu |
特殊元素标记 |
|
2. LocatorAgent - AI 定位器生成器
将 DOM 结构(截断至 30 个元素、5000 字符)和用户指令发送给 LLM,生成定位器。
后校验机制:
-
get_by_text的文本参数必须存在于 DOM 的有效文本集合中 -
get_by_role(name=...)的 name 参数必须存在于 DOM 中 -
get_by_placeholder的值必须存在于 DOM 中 -
get_by_label的值必须存在于 DOM 中 -
翻译检测:指令包含中文 + 生成文本不含中文 + 不在 DOM 中 → 判定为翻译行为,拦截
3. SafeLocator - 安全构建器
解析 LLM 生成的定位器表达式字符串,安全构建 Playwright Locator 对象。
支持的方法:
-
locator(selector)/get_by_role()/get_by_placeholder()/get_by_text()/get_by_title()/get_by_label() -
.filter(has_text="...")/.first/.last
4. LocalVisionLocator - 本地视觉定位器(单例模式)
两种定位策略:
|
策略 |
方法 |
原理 |
|---|---|---|
|
文字识别 |
|
PaddleOCR → bigram/trigram 匹配 |
|
模板匹配 |
|
OpenCV |
当 PaddleOCR/OpenCV 未安装时自动降级(available=False),不影响其他 Level 运行。
5. ScreenshotLocator - 截图视觉定位器
两种分析模式:
|
模式 |
方法 |
返回 |
|---|---|---|
|
定位器模式 |
|
Playwright 定位器表达式 |
|
坐标模式 |
|
|
429 / 余额不足时自动标记模型不可用,避免连续重试浪费请求。
6. SmartExecutor - 智能执行器(核心调度引擎)
整合所有定位模块,通过 _try_locate_and_act 统一调度四级降级策略。
特殊处理机制:
-
Strict Mode 自动修正:检测
strict mode violation错误,自动提取推荐定位器重试 -
Force Click:元素被遮挡时自动使用
force=True点击 -
图标定位检测:指令含"图标"/"icon"时,通过
_find_icon_near_element向上遍历 5 层父元素搜索img/svg
坐标→稳定定位器转换
这是 v5.0 的关键创新,将分辨率依赖的像素坐标转换为稳定的 Playwright 定位器:
像素坐标 (x, y)
↓ document.elementFromPoint(x, y)
DOM ElementHandle
↓ 提取属性
属性优先级: data-testid > placeholder > role+name > text > class
↓ 生成定位器
page.get_by_role("button", name="登录")
对于图标定位,额外调用 _find_icon_near_element,向上遍历父元素找到 th/td/header,搜索其内部的 img/svg 元素:
# 坐标(500, 120) → th 内文字"检讨报告" → 图标定位器
page.locator("th").filter(has_text="检讨报告").locator("img, svg").first
MCP Server 接口
通过 MCP(Model Context Protocol)协议提供 9 个工具:
|
工具名 |
描述 |
参数 |
|---|---|---|
|
|
导航到指定 URL |
|
|
|
智能点击页面元素 |
|
|
|
智能填充输入框 |
|
|
|
智能选择下拉选项 |
|
|
|
智能悬停页面元素 |
|
|
|
智能勾选复选框 |
|
|
|
获取页面精简 DOM 结构 |
|
|
|
截取当前页面截图 |
|
|
|
关闭浏览器释放资源 |
无 |
实际应用场景
场景 1:CRM 系统自动化测试(11 步完整流程)
import precision_locator.server as pl
await pl.ensure_browser()
# Step 1-2: 导航并登录
await pl._page.goto("https://crm.example.com")
await pl._executor.smart_fill("输入账号", "admin")
await pl._executor.smart_fill("输入密码", "password")
await pl._executor.smart_click("点击登录按钮")
# Step 3-4: 导航到客户管理
await pl._executor.smart_click("点击我的客户标签页") # Level 0 OCR 命中
# Step 5-7: 筛选客户
await pl._executor.smart_click("点击客户编号表头右侧的筛选图标") # 图标定位
await pl._executor.smart_fill("输入客户编号筛选框", "C001")
await pl._executor.smart_click("点击确定按钮")
场景 2:复杂表单填写
await executor.smart_click("点击新建按钮")
await executor.smart_fill("输入客户名称", "ABC公司")
await executor.smart_fill("输入联系人", "张三")
await executor.smart_select("选择客户类型", "企业客户")
await executor.smart_check("勾选VIP客户")
await executor.smart_click("点击保存按钮")
配置与部署
环境变量配置
# LLM 配置
LLM_PROVIDER=openai # openai / zhipu / minimax / qwen / deepseek / moonshot
LLM_MODEL= # 留空使用供应商默认模型
LLM_TEMPERATURE=0.0 # 推荐 0.0(确定性输出)
# API Keys(至少配置一个匹配 LLM_PROVIDER 的 Key)
OPENAI_API_KEY=sk-xxx
# ZHIPU_API_KEY=xxx
# DASHSCOPE_API_KEY=xxx
# DEEPSEEK_API_KEY=xxx
# 视觉模型(可选,默认跟随 LLM_PROVIDER)
# VISION_LLM_PROVIDER=openai
# VISION_MODEL=gpt-4o
# 浏览器配置
HEADLESS=false # 无头模式
# VIEWPORT=1920x1080 # 视口大小
# LOCALE=zh-CN # 浏览器语言
安装与启动
# 安装依赖
pip install -r requirements.txt
playwright install chromium
# 配置环境变量
cp .env.example .env
# 编辑 .env,填入 API Key
# 启动 MCP Server
python -m precision_locator.server
PaddleOCR 依赖较大(~1.5GB),如不需要 Level 0 本地视觉定位,可跳过
paddleocr/paddlepaddle/opencv-python/numpy。
支持的 LLM 供应商
|
供应商 |
LLM_PROVIDER |
默认模型 |
视觉模型 |
|---|---|---|---|
|
OpenAI |
|
gpt-4o |
gpt-4o |
|
智谱 AI |
|
glm-4-plus |
glm-4v-plus |
|
MiniMax |
|
MiniMax-M2.7-Highspeed |
- |
|
通义千问 |
|
qwen-plus |
qwen-vl-plus |
|
DeepSeek |
|
deepseek-chat |
- |
|
Moonshot |
|
moonshot-v1-8k |
- |
踩坑记录与技术亮点
1. PaddleOCR 版本陷阱
PaddleOCR 3.x 有破坏性 API 变更:predict() 替代了 ocr(),show_log 参数被移除。必须在 requirements.txt 中锁定 <3.0.0。
2. 白色文字 OCR 无法识别
密码输入框的 placeholder 渲染为白色文字(rgb(255,255,255))在透明背景上,PaddleOCR 物理上无法看到。解决方案:添加 DOM 补充定位 _dom_supplement_locate(),直接查询 DOM 的 placeholder 属性。同时截图前执行 document.activeElement?.blur() 避免光标干扰。
3. Element Plus 组件的 span 覆盖问题
el-radio-button 内的 span 覆盖了外层元素,导致 intercepts pointer events 错误。解决方案:使用 locator(".el-radio-button").filter(has_text="...") 代替 get_by_label()。
4. isTab 误匹配 el-table
最初的 isTab 检测用 'tab' in class_name,会匹配到 el-table。修复:使用 \bel-tabs__item\b 正则词边界。
5. Strict Mode 自动修正
Playwright 的 strict mode violation 错误信息中包含推荐定位器(aka get_by_role(...)),自动提取并重试:
if 'strict mode violation' in error_msg:
aka_matches = re.findall(r'aka (get_by_\w+\([^)]+\)|locator\([^)]+\))', error_msg)
# 使用推荐定位器重试
6. LLM 翻译检测
LLM 常常将中文元素文本翻译为英文(如"登录" → "Login")。通过三重条件检测:
-
指令包含中文
-
生成文本不含中文
-
生成文本不在 DOM 有效文本集合中
7. 关键词 Bigram/Trigram 分词
中文不像英文有空格分词,整句"点击我的客户标签页"无法精确匹配。通过 bigram/trigram 滑动窗口提取子词,配合停用词过滤,大幅提升匹配率。
总结
Precision Locator 通过创新性的四级降级策略,在保证高定位成功率的同时最大程度节省 Token 消耗。Level 0 的本地 OCR 直接解决了约 40-50% 的定位需求(零 Token),剩余场景通过 Level 1-3 逐步升级处理。
适用场景:
-
Web 自动化测试(尤其是 Element Plus 等 UI 框架)
-
机器人流程自动化(RPA)
-
AI 智能助手网页操作
-
自动化数据采集
未来规划:
-
增加 iframe 跨域定位支持
-
优化移动端视口适配
-
增加元素等待智能策略(动态等待 + 条件等待)
-
支持 Firefox / WebKit 浏览器引擎
-
增加 Electron 桌面应用支持
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)