自动将未勾选的购物清单商品加入 QFC 在线购物车,调节数量,确认购物车信息,并通过 Chrome 插件预约取货时段。
qfc- 订购 AgentSkill( Robst v3: 可靠添加 w/ 滚动, qty 选择, OOS alts/ search vars, cart 确认是一项面向实际任务的技能,主要用于Description.;Automate QFC (qfc.com) 杂货店皮卡订单: 从杂货店列表中添加项目。
实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;
涉及批量任务时,还应保存进度,避免中断后重复操作。该技能适合用于一次性任务,也可以接入自动化工作流,与其他技能或上层代理配合完成更完整的业务链路;在组合使用时,应明确每一步的输入输出关系,并避免不同步骤之间出现参数冲突。
自动化 QFC(qfc.com)杂货自提订单:从 grocery-list 中可靠地将商品添加至购物车,并预约自提时段。
使用 browser 工具,配置 profile=chrome(用户需提前附加已登录的 Chrome 标签页)。
不存储任何凭据——登录由用户自行完成。
| 文件 | 用途 |
|---|---|
skills/qfc-order/qfc-state.json |
订单状态:{store, cart_items: [], scheduled_slot, order_id?, total?} |
被调用时执行以下步骤:
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")
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”。
browser action=navigate targetUrl="https://www.qfc.com/shop.html" profile=chromeadded = [], 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('; ')}
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?
(同 v2 版本)
(同 v2 版本,更新清单状态)
同 v2 版本。
snapshotFormat=ai。已达到发布就绪标准:可稳定应对各类边界情况。
相关专题
热门下载
相关下载
精品课程
共6课时 | 54.7万人学习
共89课时 | 133.7万人学习
共49课时 | 82.4万人学习
最新文章