痛点
做过自动化测试或爬虫的同学一定遇到过这种情况: 昨天写的脚本 document.querySelector('#login-btn') 还能跑,今天网站更新了,ID 变成了 #login-btn-123,脚本直接挂掉。
在开发 AutoForm 智能表单填充 SDK 时,我们面临同样的挑战:如何让 SDK 在页面结构变化后,依然能找到那个"用户名输入框"?
答案是:语义指纹(Semantic Fingerprinting)。
什么是语义指纹?
人类找元素不是靠 ID,而是靠"特征"。 当你看到一个输入框,旁边写着"用户名",里面提示"请输入手机号",你就知道它是干嘛的。
我们将这些特征提取出来,生成一个唯一的哈希值,这就是"语义指纹"。
算法实现
1. 特征提取
我们提取以下维度的特征:
- Label 文本:这是最强的语义特征。
- Placeholder:提示文案。
- Name 属性 :通常包含字段含义(如
username,email)。 - Input Type :输入类型(
text,password,checkbox)。 - 前驱/后继文本:DOM 树中相邻的文本节点。
typescript
function extractFeatures(element) {
return {
tag: element.tagName,
type: element.type,
name: element.name,
label: findLabel(element), // 关联的 label 文本
placeholder: element.placeholder,
surroundingText: getSurroundingText(element)
};
}
2. 指纹生成
将特征拼接成字符串,然后计算 Hash。
typescript
import { md5 } from 'hash-wasm';
const fingerprint = await md5(JSON.stringify(features));
3. 模糊匹配
当页面更新后,新元素的指纹可能与旧指纹不完全一致(比如 placeholder 变了)。这时我们计算相似度(Similarity Score)。
我们使用 Levenshtein Distance(编辑距离) 算法来比较两个特征对象的相似度。如果相似度 > 80%,我们就认为找到了目标。
效果
引入语义指纹后,AutoForm 的定位抗干扰能力大幅提升:
- ID 变化:完全免疫。
- DOM 结构微调:完全免疫。
- 文案微调:只要核心语义没变(如"用户名"变成"请输入用户名"),依然能识别。
总结
在 AI 时代,基于规则的硬编码(Hard-coding)已经过时了。基于特征的模糊匹配才是未来的方向。
思考:如果页面上有两个完全一样的输入框(如两个"手机号"),该如何区分?欢迎评论区交流!
👉 官网地址:51bpms.com