Qfc Order

Polar Sponsor
爱发电 赞助
.NET 9.0

自动将未勾选的购物清单商品加入 QFC 在线购物车,调节数量,确认购物车信息,并通过 Chrome 插件预约取货时段。

qfc- 订购 AgentSkill( Robst v3: 可靠添加 w/ 滚动, qty 选择, OOS alts/ search vars, cart 确认

功能概述

qfc- 订购 AgentSkill( Robst v3: 可靠添加 w/ 滚动, qty 选择, OOS alts/ search vars, cart 确认是一项面向实际任务的技能,主要用于Description.;Automate QFC (qfc.com) 杂货店皮卡订单: 从杂货店列表中添加项目。

核心要点

  • 它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。
  • 使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。
  • 从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。

使用与执行

实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;

结果检查与注意事项

涉及批量任务时,还应保存进度,避免中断后重复操作。该技能适合用于一次性任务,也可以接入自动化工作流,与其他技能或上层代理配合完成更完整的业务链路;在组合使用时,应明确每一步的输入输出关系,并避免不同步骤之间出现参数冲突。

qfc-order AgentSkill(稳健版 v3:支持滚动加载、数量选择、缺货替代品/搜索变体、购物车确认)

描述

自动化 QFC(qfc.com)杂货自提订单:从 grocery-list 中可靠地将商品添加至购物车,并预约自提时段。
使用 browser 工具,配置 profile=chrome(用户需提前附加已登录的 Chrome 标签页)。
不存储任何凭据——登录由用户自行完成。

触发词(调用短语)

  • qfc order
  • place qfc pickup
  • grocery order qfc
  • shop qfc

前置条件

  1. 用户已登录 qfc.com(Kroger 账户)。
  2. 导航至 Pickup 页面,并选择门店/位置。
  3. 在该标签页上点击 OpenClaw Browser Relay 工具栏按钮(徽章变为 ON/绿色)。
  4. 确保 grocery-list 技能中存在未勾选的商品(可先调用 “grocery list” 查看)。
  5. 调用本技能:“Place QFC order”

持久化状态

文件 用途
skills/qfc-order/qfc-state.json 订单状态:{store, cart_items: [], scheduled_slot, order_id?, total?}

优化工作流(最小快照数、基于 ARIA 的引用、高可靠性添加)

被调用时执行以下步骤:

1. 验证与关键引用提取

browser action=status profile=chrome
  • 若返回结果中不含 cdpReady: true:提示用户附加 Chrome 标签页。
initial_snap = browser(action=snapshot, profile=chrome, refs="aria", compact=true)

从中提取:

search_ref = initial_snap.ref_for(role="searchbox")  # 或 aria-label="Search"
cart_ref = initial_snap.ref_for(role="button", name~="Cart" || aria-label~="cart")

2. 加载并确认杂货清单

glist = read(path="skills/grocery-list/grocery-list.json")
items = glist.items.filter(item => !item.checked)

回复:“正在添加 ${items.length} 件商品:${items.map(i=>i.name).join(', ')}. 是否继续?” 等待用户输入“yes”。

3. 确保处于商店浏览页

  • 若 initial_snap 显示为门店选择页或无搜索框:根据 state 或用户输入选择门店,并执行
    browser action=navigate targetUrl="https://www.qfc.com/shop.html" profile=chrome
  • 必要时重新执行快照。

4. 商品添加循环(稳健设计:多关键词搜索、滚动加载、数量调整、缺货替代方案)

added = [], skipped = [], notes = []
for item in items:
  success = false
  search_terms = [
    `${item.qty || '1'} ${item.unit || ''} ${item.name}`.trim(),
    item.name,
    (item.unit ? `${item.unit} ${item.name.split(' ')[0]}` : null),
    item.name.toLowerCase().replace(/kroger|private selection/gi, '').trim()
  ].filter(Boolean).slice(0,3)

  for sterm in search_terms:
    if success: break
    # 清空并执行搜索
    browser(action="act", profile=chrome, request={kind:"type", ref:search_ref, text:""})
    browser(action="act", profile=chrome, request={kind:"type", ref:search_ref, text:sterm})
    browser(action="act", profile=chrome, request={kind:"press", ref:search_ref, key:"Enter"})
    
    # 滚动到底部以加载全部结果
    browser(action="act", profile=chrome, request={kind:"evaluate", fn:"window.scrollTo(0, document.body.scrollHeight)"})
    scroll1_snap = browser(action="snapshot", profile=chrome, refs="aria", compact=true)
    browser(action="act", profile=chrome, request={kind:"evaluate", fn:"window.scrollTo(0, document.body.scrollHeight)"})
    results_snap = browser(action="snapshot", profile=chrome, refs="aria", compact=true)
    
    # 查找最匹配的商品
    prod_matches = results_snap.find_all(role~="article|listitem", name~item.name.split(' ')[0], max=5)
    for prod_ref in prod_matches:
      add_ref = results_snap.ref_for(role="button", name~="Add|+", ancestor=prod_ref)
      oos = results_snap.has_text("out of stock|unavailable|sold out", ancestor=prod_ref, case=false)
      if add_ref && !oos:
        browser(action="act", profile=chrome, request={kind:"click", ref:add_ref})
        # 数量选择/调整
        qty_snap = browser(action="snapshot", profile=chrome, refs="aria")
        qty_plus_ref = qty_snap.ref_for(role="button", name="+" || aria~="increase")
        qty_needed = parseFloat(item.qty || 1)
        if qty_plus_ref && qty_needed > 1:
          for(let k = 1; k < qty_needed; k++):
            browser(action="act", profile=chrome, request={kind:"click", ref:qty_plus_ref})
        success = true
        added.push(item)
        notes.push(`Added via "${sterm}": ${item.name} x${item.qty}`)
        break
  if !success:
    skipped.push(item)
    notes.push(`Skipped ${item.name}: no suitable product/OOS (tried ${search_terms.join(', ')})`)
  
  # 每处理 3+ 个商品后汇报进度
  if (added.length + skipped.length) % 3 == 0:
    Reply: `Progress: ${added.length}/${items.length} (${notes.slice(-3).join('; ')})`

最终回复:Added ${added.length}/${items.length}. ${notes.join('; ')}

5. 购物车确认(详细信息)

browser(action="act", profile=chrome, request={kind:"click", ref:cart_ref})
cart_snap = browser(action="snapshot", profile=chrome, refs="aria", labels=true, compact=false)
cart_details = []
cart_snap.find_all(role~="listitem|tr").slice(0,20).forEach( itemref => {
  let name = cart_snap.text_for(itemref).trim().slice(0,60)
  if (name && !name.includes('Subtotal')):  # 过滤掉小计等非商品行
    let qtyref = cart_snap.ref_for(role~="spinbutton|input", ancestor=itemref, name~="Qty")
    let qty = qtyref ? qtyref.value : '1'
    let price = cart_snap.text_for(role~="price", ancestor=itemref) || ''
    cart_details.push(`${name} x${qty} ${price}`)
})
total_str = cart_snap.text_for(role~="total|subtotal strong") || 'N/A'

回复:**Cart Review:**\n${cart_details.join('\n')}\n**Total:** ${total_str}\n\n**Skipped:** ${skipped.map(s=>s.name).join(', ')}\nProceed to slots?

6. 预约自提时段

(同 v2 版本)

7. 最终审核与下单后操作

(同 v2 版本,更新清单状态)

工具调用模式

同 v2 版本。

提示与注意事项

  • 滚动:两次滚动到底部 + 快照,确保完整加载搜索结果。
  • 缺货替代方案:多关键词搜索自动尝试不同变体及通用名称。
  • 数量:添加后自动执行“+”按钮点击(假设数量调节控件为弹出式)。
  • 购物车确认:提取含数量与价格的商品列表供用户复核。
  • 回退机制:若无 ARIA 属性,则使用 role + name 组合定位;如需语义理解,可设 snapshotFormat=ai。
  • 最小快照数:每件商品约 3–5 次快照(搜索 + 滚动 + 数量调节),外加购物车与时段页快照。
  • 已测试:已在 openclaw profile 上完成干运行(参见日志)。

已达到发布就绪标准:可稳定应对各类边界情况。

相关专题

更多
Linux 新手先学哪些命令
Linux 新手先学哪些命令

Linux新手命令专题汇集终端基础、文件目录操作、文本查看、软件安装和权限管理等入门文章,帮助按实际任务练习常用命令并建立命令行操作习惯。

2026.10.15

0

20

MySQL 忘记密码怎么办
MySQL 忘记密码怎么办

MySQL忘记密码专题汇集不同版本与系统下的root密码重置方法,覆盖MySQL 5.7、8.0、Mac、Linux及本地集成环境,并提示恢复权限与重新登录的检查步骤。

2026.10.15

0

18

Vue.js 中 ref 和 reactive 的区别
Vue.js 中 ref 和 reactive 的区别

Vue.js中ref和reactive的区别专题汇集两种响应式API的定义、访问方式、对象解构、侦听与性能取舍等文章,帮助结合实际状态类型选择合适写法。

2026.10.15

0

20

VS Code 怎么配置开发环境
VS Code 怎么配置开发环境

VS Code开发环境专题汇集编辑器安装、语言扩展、编译器、解释器、终端和调试配置文章,覆盖Java、Python、C++和PHP等常见语言的入门设置。

2026.10.15

0

18

C++ 开发环境怎么搭建
C++ 开发环境怎么搭建

C++开发环境专题汇集Windows、Linux下的编译器与IDE安装配置教程,涵盖GCC、Clang、Visual Studio、CLion和VS Code,以及编译运行首个程序的步骤。

2026.10.15

0

19

Python 虚拟环境是什么
Python 虚拟环境是什么

Python虚拟环境专题介绍项目依赖隔离的作用,汇集venv与uv创建、激活、退出及解释器切换的相关文章,并覆盖Windows、Linux和VS Code中的常见配置问题。

2026.10.15

0

15

Python 怎么安装并配置环境变量
Python 怎么安装并配置环境变量

Python安装与环境变量配置专题汇集Windows、macOS和Linux的安装步骤、PATH设置、pip配置及常见报错排查文章,帮助完成解释器安装并验证命令行可以正常运行。

2026.10.15

0

15

PHP 连接 MySQL 失败怎么办
PHP 连接 MySQL 失败怎么办

PHP连接MySQL失败专题汇集PDO与MySQLi扩展配置、账号权限、主机端口、套接字和认证方式等排查文章,覆盖连接报错、密码变更与容器环境配置,帮助按错误提示定位原因并修复。

2026.10.15

0

18

PHP 表单提交后如何获取数据
PHP 表单提交后如何获取数据

PHP表单提交后如何获取数据专题汇集HTML表单提交、GET与POST接收、$_POST和$_GET读取、跨文件传值、单选与下拉字段获取,以及空值和接收失败排查等文章,帮助新手完成从提交到处理的完整流程。

2026.10.15

0

20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.7万人学习