OpenClaw Browser 自动化:表单填写实战

目录

    • 摘要
    • [1. 引言 - 表单自动化的价值](#1. 引言 - 表单自动化的价值)
      • [1.1 常见表单场景](#1.1 常见表单场景)
      • [1.2 表单自动化挑战](#1.2 表单自动化挑战)
      • [1.3 OpenClaw 解决方案](#1.3 OpenClaw 解决方案)
    • [2. 表单分析基础](#2. 表单分析基础)
      • [2.1 表单元素识别](#2.1 表单元素识别)
      • [2.2 表单字段映射](#2.2 表单字段映射)
      • [2.3 表单验证规则](#2.3 表单验证规则)
    • [3. 实战案例一:登录表单](#3. 实战案例一:登录表单)
      • [3.1 场景描述](#3.1 场景描述)
      • [3.2 实现代码](#3.2 实现代码)
      • [3.3 错误处理](#3.3 错误处理)
    • [4. 实战案例二:注册表单](#4. 实战案例二:注册表单)
      • [4.1 场景描述](#4.1 场景描述)
      • [4.2 实现代码](#4.2 实现代码)
      • [4.3 验证码处理](#4.3 验证码处理)
    • [5. 实战案例三:多步骤表单](#5. 实战案例三:多步骤表单)
      • [5.1 场景描述](#5.1 场景描述)
      • [5.2 实现代码](#5.2 实现代码)
      • [5.3 步骤验证](#5.3 步骤验证)
    • [6. 高级技巧](#6. 高级技巧)
      • [6.1 智能等待](#6.1 智能等待)
      • [6.2 表单数据预处理](#6.2 表单数据预处理)
      • [6.3 错误恢复](#6.3 错误恢复)
    • [7. 最佳实践](#7. 最佳实践)
      • [7.1 表单自动化清单](#7.1 表单自动化清单)
      • [7.2 常见陷阱](#7.2 常见陷阱)
      • [7.3 性能优化](#7.3 性能优化)
    • [8. 总结](#8. 总结)
      • [8.1 核心要点](#8.1 核心要点)
      • [8.2 下一步](#8.2 下一步)
    • 参考资料

摘要

本文通过实际案例演示 OpenClaw Browser 的表单自动化能力。从简单登录表单到复杂多步骤表单,全面解析表单自动化的实现技巧。涵盖表单分析、智能填写、验证处理、错误恢复等关键环节,帮助开发者构建可靠的表单自动化解决方案。📝


1. 引言 - 表单自动化的价值

1.1 常见表单场景

场景 说明 自动化价值
用户注册 填写注册信息 批量创建测试账号
数据录入 填写业务表单 提高录入效率
在线申请 填写申请表格 自动化申请流程
信息提交 提交各类信息 减少重复劳动

1.2 表单自动化挑战

表单自动化挑战
元素定位
动态内容
验证码
错误处理
选择器变化
异步加载
人工干预
异常恢复

1.3 OpenClaw 解决方案

挑战 解决方案
元素定位 语义快照 + 智能匹配
动态内容 等待策略 + 重试机制
验证码 人工介入 + OCR 识别
错误处理 异常捕获 + 自动恢复

2. 表单分析基础

2.1 表单元素识别

python 复制代码
def analyze_form(snapshot):
    """分析表单结构"""
    form_info = {
        "textboxes": [],
        "checkboxes": [],
        "radios": [],
        "selects": [],
        "buttons": []
    }
    
    for element in snapshot["elements"]:
        element_type = element.get("type")
        
        if element_type == "textbox":
            form_info["textboxes"].append({
                "ref": element["ref"],
                "label": element.get("label", ""),
                "placeholder": element.get("placeholder", ""),
                "required": element.get("required", False)
            })
        elif element_type == "checkbox":
            form_info["checkboxes"].append(element)
        elif element_type == "radio":
            form_info["radios"].append(element)
        elif element_type == "combobox":
            form_info["selects"].append(element)
        elif element_type == "button":
            form_info["buttons"].append(element)
    
    return form_info

2.2 表单字段映射

python 复制代码
def map_form_fields(form_info, data):
    """将数据映射到表单字段"""
    mapping = {}
    
    for field in form_info["textboxes"]:
        label = field.get("label", "").lower()
        placeholder = field.get("placeholder", "").lower()
        
        # 智能匹配
        for key, value in data.items():
            key_lower = key.lower()
            if key_lower in label or key_lower in placeholder:
                mapping[field["ref"]] = value
                break
    
    return mapping

2.3 表单验证规则

验证类型 说明 处理方式
必填 required 属性 确保填写
格式 email、phone 等 格式化数据
长度 min/max length 截断或补全
范围 min/max value 调整数值

3. 实战案例一:登录表单

3.1 场景描述

自动登录一个网站,包含用户名、密码输入和登录按钮。

3.2 实现代码

python 复制代码
def auto_login(url, username, password):
    """自动登录"""
    # 1. 打开登录页面
    browser(action="open", targetUrl=url)
    
    # 2. 等待页面加载
    browser(action="act", kind="wait", timeMs=2000)
    
    # 3. 获取页面快照
    snapshot = browser(
        action="snapshot",
        interactive=True
    )
    
    # 4. 查找用户名输入框
    username_field = find_element_by_keywords(
        snapshot, 
        "textbox", 
        ["用户名", "username", "账号", "email"]
    )
    
    # 5. 输入用户名
    browser(
        action="act",
        kind="type",
        ref=username_field["ref"],
        text=username
    )
    
    # 6. 查找密码输入框
    password_field = find_element_by_keywords(
        snapshot,
        "textbox",
        ["密码", "password", "pwd"]
    )
    
    # 7. 输入密码
    browser(
        action="act",
        kind="type",
        ref=password_field["ref"],
        text=password
    )
    
    # 8. 查找登录按钮
    login_btn = find_element_by_keywords(
        snapshot,
        "button",
        ["登录", "login", "signin", "提交"]
    )
    
    # 9. 点击登录
    browser(
        action="act",
        kind="click",
        ref=login_btn["ref"]
    )
    
    # 10. 等待登录完成
    browser(action="act", kind="wait", timeMs=3000)
    
    # 11. 验证登录结果
    new_snapshot = browser(action="snapshot")
    return check_login_success(new_snapshot)

def find_element_by_keywords(snapshot, element_type, keywords):
    """通过关键词查找元素"""
    for element in snapshot["elements"]:
        if element.get("type") != element_type:
            continue
        
        text = element.get("text", "").lower()
        label = element.get("label", "").lower()
        placeholder = element.get("placeholder", "").lower()
        
        for keyword in keywords:
            if keyword.lower() in text or keyword.lower() in label or keyword.lower() in placeholder:
                return element
    
    return None

3.3 错误处理

python 复制代码
def safe_auto_login(url, username, password, max_retries=3):
    """带错误处理的自动登录"""
    for attempt in range(max_retries):
        try:
            result = auto_login(url, username, password)
            return result
        except Exception as e:
            print(f"登录失败 (尝试 {attempt + 1}/{max_retries}): {e}")
            
            if attempt < max_retries - 1:
                # 刷新页面重试
                browser(action="navigate", targetUrl=url)
                browser(action="act", kind="wait", timeMs=2000)
    
    raise Exception("登录失败,已达最大重试次数")

4. 实战案例二:注册表单

4.1 场景描述

自动填写用户注册表单,包含多个字段和验证。

4.2 实现代码

python 复制代码
def auto_register(url, user_data):
    """自动注册"""
    # 1. 打开注册页面
    browser(action="open", targetUrl=url)
    browser(action="act", kind="wait", timeMs=2000)
    
    # 2. 获取表单快照
    snapshot = browser(action="snapshot", interactive=True)
    
    # 3. 分析表单结构
    form_info = analyze_form(snapshot)
    
    # 4. 映射数据到字段
    field_mapping = map_form_fields(form_info, user_data)
    
    # 5. 填写文本字段
    for ref, value in field_mapping.items():
        browser(
            action="act",
            kind="type",
            ref=ref,
            text=str(value)
        )
        # 短暂等待,模拟人工输入
        browser(action="act", kind="wait", timeMs=300)
    
    # 6. 处理复选框(如同意条款)
    for checkbox in form_info["checkboxes"]:
        text = checkbox.get("text", "").lower()
        if "同意" in text or "条款" in text or "agree" in text.lower():
            browser(
                action="act",
                kind="click",
                ref=checkbox["ref"]
            )
    
    # 7. 处理下拉选择框
    for select in form_info["selects"]:
        label = select.get("label", "").lower()
        if "城市" in label or "city" in label:
            browser(
                action="act",
                kind="select",
                ref=select["ref"],
                value=user_data.get("city", "北京")
            )
    
    # 8. 提交表单
    submit_btn = find_element_by_keywords(
        snapshot,
        "button",
        ["注册", "register", "提交", "submit"]
    )
    
    if submit_btn:
        browser(
            action="act",
            kind="click",
            ref=submit_btn["ref"]
        )
    
    # 9. 等待响应
    browser(action="act", kind="wait", timeMs=3000)
    
    # 10. 检查结果
    result_snapshot = browser(action="snapshot")
    return check_register_result(result_snapshot)

4.3 验证码处理

python 复制代码
def handle_captcha():
    """处理验证码"""
    # 获取快照
    snapshot = browser(action="snapshot")
    
    # 查找验证码图片
    captcha_img = find_element(snapshot, "image", "验证码")
    
    if captcha_img:
        # 截取验证码图片
        captcha_screenshot = browser(
            action="screenshot",
            element=captcha_img["ref"]
        )
        
        # 方案1:OCR识别
        captcha_text = ocr_recognize(captcha_screenshot)
        
        # 方案2:请求人工输入
        # captcha_text = request_human_input("请输入验证码")
        
        # 填写验证码
        captcha_input = find_element(snapshot, "textbox", "验证码")
        browser(
            action="act",
            kind="type",
            ref=captcha_input["ref"],
            text=captcha_text
        )

5. 实战案例三:多步骤表单

5.1 场景描述

处理需要分多个步骤完成的复杂表单,如订单填写、申请流程等。

5.2 实现代码

python 复制代码
def multi_step_form(url, steps_data):
    """多步骤表单处理"""
    # 1. 打开页面
    browser(action="open", targetUrl=url)
    browser(action="act", kind="wait", timeMs=2000)
    
    # 2. 逐步处理
    for step_index, step_data in enumerate(steps_data):
        print(f"处理步骤 {step_index + 1}/{len(steps_data)}")
        
        # 获取当前页面快照
        snapshot = browser(action="snapshot", interactive=True)
        
        # 填写当前步骤的数据
        fill_current_step(snapshot, step_data)
        
        # 查找下一步按钮
        next_btn = find_element_by_keywords(
            snapshot,
            "button",
            ["下一步", "next", "继续", "continue"]
        )
        
        if next_btn:
            browser(
                action="act",
                kind="click",
                ref=next_btn["ref"]
            )
            browser(action="act", kind="wait", timeMs=2000)
        else:
            # 最后一步,查找提交按钮
            submit_btn = find_element_by_keywords(
                snapshot,
                "button",
                ["提交", "submit", "完成", "finish"]
            )
            
            if submit_btn:
                browser(
                    action="act",
                    kind="click",
                    ref=submit_btn["ref"]
                )
    
    # 3. 等待最终结果
    browser(action="act", kind="wait", timeMs=3000)
    
    # 4. 验证完成
    final_snapshot = browser(action="snapshot")
    return verify_completion(final_snapshot)

def fill_current_step(snapshot, step_data):
    """填写当前步骤的数据"""
    for field_name, value in step_data.items():
        # 查找对应字段
        element = find_element_by_keywords(
            snapshot,
            "textbox",
            [field_name]
        )
        
        if element:
            browser(
                action="act",
                kind="type",
                ref=element["ref"],
                text=str(value)
            )

5.3 步骤验证

python 复制代码
def verify_step_completion(expected_elements):
    """验证步骤完成"""
    snapshot = browser(action="snapshot")
    
    for element_desc in expected_elements:
        found = find_element_by_keywords(
            snapshot,
            element_desc["type"],
            [element_desc["text"]]
        )
        
        if not found:
            return False
    
    return True

6. 高级技巧

6.1 智能等待

python 复制代码
def smart_wait_for_element(element_type, keywords, timeout=10000):
    """智能等待元素出现"""
    start_time = time.time()
    
    while time.time() - start_time < timeout / 1000:
        snapshot = browser(action="snapshot", interactive=True)
        element = find_element_by_keywords(snapshot, element_type, keywords)
        
        if element:
            return element
        
        time.sleep(0.5)
    
    raise TimeoutError(f"等待元素超时: {element_type} - {keywords}")

6.2 表单数据预处理

python 复制代码
def preprocess_form_data(data, form_info):
    """预处理表单数据"""
    processed = {}
    
    for field in form_info["textboxes"]:
        label = field.get("label", "").lower()
        placeholder = field.get("placeholder", "").lower()
        
        # 根据字段类型处理数据
        if "邮箱" in label or "email" in placeholder:
            # 邮箱格式验证
            email = data.get("email", "")
            if "@" in email:
                processed[field["ref"]] = email
        
        elif "电话" in label or "phone" in placeholder:
            # 电话格式化
            phone = data.get("phone", "")
            processed[field["ref"]] = phone.replace("-", "").replace(" ", "")
        
        elif "日期" in label or "date" in placeholder:
            # 日期格式化
            date = data.get("date", "")
            processed[field["ref"]] = format_date(date)
        
        else:
            # 默认处理
            for key, value in data.items():
                if key.lower() in label or key.lower() in placeholder:
                    processed[field["ref"]] = str(value)
                    break
    
    return processed

6.3 错误恢复

python 复制代码
def form_fill_with_recovery(url, data, max_retries=3):
    """带错误恢复的表单填写"""
    saved_state = {}
    
    for attempt in range(max_retries):
        try:
            # 恢复之前的状态
            if saved_state:
                restore_state(saved_state)
            
            # 填写表单
            result = fill_form(url, data)
            return result
            
        except Exception as e:
            print(f"填写失败: {e}")
            
            # 保存当前状态
            saved_state = save_current_state()
            
            if attempt < max_retries - 1:
                # 刷新页面
                browser(action="navigate", targetUrl=url)
                browser(action="act", kind="wait", timeMs=2000)
    
    raise Exception("表单填写失败,已达最大重试次数")

7. 最佳实践

7.1 表单自动化清单

步骤 说明 检查项
分析 分析表单结构 所有字段已识别
映射 映射数据到字段 数据格式正确
填写 填写表单数据 填写顺序合理
验证 验证填写结果 无错误提示
提交 提交表单 提交成功

7.2 常见陷阱

陷阱 说明 解决方案
异步加载 元素动态加载 智能等待
隐藏字段 不可见但必填 检查隐藏元素
事件触发 需要触发事件 模拟完整交互
防机器人 检测自动化行为 模拟人工操作

7.3 性能优化

python 复制代码
# 批量操作
def batch_fill_fields(field_values):
    """批量填写字段"""
    snapshot = browser(action="snapshot", interactive=True)
    
    for ref, value in field_values.items():
        browser(
            action="act",
            kind="type",
            ref=ref,
            text=value
        )
        # 减少等待时间
        time.sleep(0.1)  # 最小等待

8. 总结

8.1 核心要点

要点 说明
先分析后操作 先获取快照分析表单结构
智能匹配 使用语义匹配定位字段
错误处理 添加重试和恢复机制
验证结果 确认操作成功完成

8.2 下一步

  • 第49篇:OpenClaw Chrome 扩展:Browser Relay 配置
  • 第50篇:OpenClaw 网页抓取:数据采集实战

参考资料

相关推荐
袁煦丞 cpolar内网穿透实验室2 小时前
出差路上,服务器在我手机里
运维·服务器·docker·容器·智能手机·远程工作·cpolar
小此方2 小时前
Re:Linux系统篇(十三)特别篇: 实现Linux第⼀个系统程序−进度条
linux·运维·服务器
tedcloud1236 小时前
UI-TARS-desktop部署教程:构建AI桌面自动化系统
服务器·前端·人工智能·ui·自动化·github
AC赳赳老秦10 小时前
供应链专员提效:OpenClaw自动跟踪物流信息、更新库存数据,异常自动提醒
java·大数据·服务器·数据库·人工智能·自动化·openclaw
哲霖软件11 小时前
ERP 赋能非标自动化行业:破解物料与库存管理难题
运维·自动化
HBYKKJ11 小时前
文氏阀自动化气密性测试解决方案:格雷希尔G10-H定制款快速密封连接器,解决文氏阀宝塔管口同步封堵难题
自动化·气密性测试·格雷希尔·快速密封连接器·非标定制·文氏阀
无心水11 小时前
【Hermes:安全、权限与生产环境】40、运行 Hermes 前的生命线:安全审计清单与 11 个必须检查的配置项
人工智能·安全·mcp协议·openclaw·养龙虾·hermes·honcho
大明者省13 小时前
宝塔开了端口,Ubuntu 还得开相应端口才能打通
服务器·数据库·ubuntu
syagain_zsx13 小时前
Linux指令初识(实用篇)
linux·运维·服务器