这两张图片,第一张图片的立即购买可以点击到,第二张图片的立即购买怎么点击不成功,我要怎么写,让第二个图的立即购买点击能成功,步骤是这样的,我先点击第一个立即购买按钮,第二张立即购买那个弹框才会弹出来

L-PPMT · 6 小时前
第 1 条补充
·
6 小时前

我不要用OCR的方式来实现,就获取节点的方式,不可以拿到吗

回答

Hamibot AI
1
· 6 小时前

// 文档地址 https://docs.hamibot.com/

你遇到的问题很常见,弹出框中的"立即购买"按钮点击不成功通常是因为以下几个原因:

  1. 弹出框出现后需要等待渲染完成
  2. 按钮位置与第一个页面的"立即购买"不同
  3. 需要指定找色区域(弹窗通常在屏幕中央区域)
  4. 需要使用多点颜色匹配提高准确性

以下是针对你的问题的解决方案代码:

// 请求截图权限
auto.waitFor();
if (!requestScreenCapture()) {
    toastLog('没有授予 Hamibot 屏幕截图权限');
    hamibot.exit();
}

// 先点击第一个页面的立即购买按钮
toastLog('点击第一个立即购买按钮');
// 假设第一个按钮可以通过坐标点击,或者你已经有其他方式找到它
// 例如:
// click(500, 1500);
// 或者用找色方法找到第一个按钮

// 重要:等待弹窗完全显示(根据实际情况调整等待时间)
sleep(2000);

// 在弹窗区域找色(通常弹窗在屏幕中央)
var img = captureScreen();
// 这里使用多点颜色匹配,提高准确性
// 注意:需要根据实际按钮颜色修改颜色值
var p = images.findMultiColors(
    img,
    '#FF0000',  // 按钮主颜色,需要根据实际按钮颜色修改
    [
        [10, 10, '#FFFFFF'],  // 按钮内部某个点的颜色
        [20, 20, '#000000']   // 按钮内部另一个点的颜色
    ],
    {
        region: [200, 800, 700, 400],  // 只在屏幕中央区域找色,格式为[x, y, width, height]
        threshold: 4  // 颜色匹配阈值,值越小越精确
    }
);

if (p) {
    toastLog('找到弹窗中的立即购买按钮,坐标为(' + p.x + ', ' + p.y + ')');
    click(p.x, p.y);
    sleep(500);
    if (!pointInRegion(p, [200, 800, 700, 400])) {
        toastLog('警告:点击位置可能不在目标区域内');
    }
} else {
    toastLog('没找到弹窗中的立即购买按钮,尝试单点找色');
    
    // 如果多点找色失败,尝试单点找色
    var p2 = findColor(img, '#FF0000', {
        region: [200, 800, 700, 400],
        threshold: 4
    });
    
    if (p2) {
        toastLog('单点找色成功,坐标为(' + p2.x + ', ' + p2.y + ')');
        click(p2.x, p2.y);
    } else {
        toastLog('还是没找到,可能需要调整颜色值或区域');
        // 可以尝试截图并分析颜色
        images.save(img, '/sdcard/hamibot_screenshot.png');
        toastLog('截图已保存到 /sdcard/hamibot_screenshot.png,可以查看分析');
    }
}

// 检查点是否在指定区域内
function pointInRegion(point, region) {
    var x = region[0], y = region[1], width = region[2], height = region[3];
    return (point.x >= x && point.x <= x + width && point.y >= y && point.y <= y + height);
}

hamibot.exit();

使用这个脚本的关键点:

  1. 等待时间:在点击第一个按钮后,确保有足够的等待时间让弹窗完全显示(sleep(2000)可以根据实际情况调整)

  2. 区域限定:使用region: [200, 800, 700, 400]将找色范围限制在屏幕中央,这比在整个屏幕找色更准确、更快

  3. 多点颜色匹配:使用findMultiColors而不是单点找色,通过检查多个点的颜色来确认是目标按钮

  4. 颜色值调整:你需要根据实际按钮的颜色修改代码中的颜色值(#FF0000等)

  5. 调试方法:如果还是找不到,脚本会保存截图到手机,你可以查看截图分析按钮的实际颜色和位置

要获取准确的颜色值,你可以:

  1. 先运行脚本保存截图
  2. 用图片查看工具打开截图
  3. 使用取色器获取按钮上几个关键点的颜色值
  4. 将这些颜色值填入脚本中

如果按钮颜色比较复杂,也可以考虑使用图像识别(images.matchTemplate)来匹配整个按钮的图片。


补充回答 1

// 文档地址 https://docs.hamibot.com/

完全可以使用控件节点的方式实现,不需要OCR。你的场景很典型:第一个"立即购买"按钮点击后会弹出包含第二个"立即购买"按钮的弹窗。

使用控件节点方式的关键是等待弹窗完全加载后再进行操作,以下是正确的实现方法:

auto.waitFor();

// 点击第一个页面的立即购买按钮
// 假设第一个按钮可以通过文本找到
var firstBuyBtn = text("立即购买").findOne(2000);
if (firstBuyBtn) {
    toastLog("找到第一个立即购买按钮,正在点击");
    firstBuyBtn.click();
} else {
    toastLog("未找到第一个立即购买按钮");
    hamibot.exit();
}

// 关键:等待弹窗中的按钮出现(重要!)
// 不能使用固定sleep,应该用waitFor等待控件出现
toastLog("等待弹窗中的立即购买按钮...");
var popupBuyBtn = text("立即购买").findOnce(1);
// 如果有多个"立即购买",需要更精确的定位
if (!popupBuyBtn) {
    // 可能需要等待更长时间,或者使用更复杂的条件
    popupBuyBtn = text("立即购买").className("android.widget.Button").waitFor();
}

// 点击弹窗中的立即购买按钮
if (popupBuyBtn) {
    toastLog("找到弹窗中的立即购买按钮,正在点击");
    popupBuyBtn.click();
    
    // 可选:验证是否点击成功
    sleep(500);
    if (text("支付成功").exists() || text("订单提交").exists()) {
        toastLog("购买操作成功");
    }
} else {
    toastLog("未找到弹窗中的立即购买按钮");
    
    // 尝试其他可能的定位方式
    var alternativeBtn = className("android.widget.Button")
        .textContains("立即").findOne(1000);
    if (alternativeBtn) {
        toastLog("通过替代方式找到按钮");
        alternativeBtn.click();
    } else {
        toastLog("仍然未找到按钮,可能需要调整选择器");
        
        // 调试:输出当前界面所有包含"购买"的控件
        var allBuyControls = textContains("购买").find();
        toastLog("找到" + allBuyControls.size() + "个包含'购买'的控件");
        for (var i = 0; i < allBuyControls.size(); i++) {
            var ctrl = allBuyControls.get(i);
            toastLog("控件" + i + ": " + ctrl.text() + 
                ", id=" + ctrl.id() + 
                ", class=" + ctrl.className());
        }
    }
}

hamibot.exit();

如果你的第二个按钮仍然找不到,可能是因为:

  1. 弹窗中的按钮与第一个页面的按钮有完全相同的属性,需要更精确的定位:
// 通过父容器定位 - 弹窗通常有特定的父容器
var popupBuyBtn = id("dialog_container") // 弹窗容器ID
    .findOne(3000)
    .child(0) // 根据实际结构调整
    .child(1)
    .findOne()
    .click();
  1. 按钮在RecyclerView或ListView中,需要滚动查找:
// 如果按钮可能在滚动列表中
scrollable().findOne().scrollForward();
sleep(500);
var popupBuyBtn = text("立即购买").findOne(1000);
  1. 使用深度优先搜索
// 深度优先搜索,找到最深层的"立即购买"按钮
function findDeepestBuyButton() {
    var buttons = text("立即购买").find();
    var deepestBtn = null;
    var maxDepth = -1;
    
    for (var i = 0; i < buttons.size(); i++) {
        var btn = buttons.get(i);
        if (btn.depth() > maxDepth) {
            maxDepth = btn.depth();
            deepestBtn = btn;
        }
    }
    
    return deepestBtn;
}

var popupBuyBtn = findDeepestBuyButton();
if (popupBuyBtn) popupBuyBtn.click();
  1. 最可靠的方案:使用控件ID(如果应用有固定ID):
// 最佳实践:使用ID定位(如果可用)
var popupBuyBtn = id("com.example.app:id/popup_buy_button").findOne(3000);
if (popupBuyBtn) {
    popupBuyBtn.click();
} else {
    toastLog("推荐:获取按钮ID,这是最稳定的方式");
    // 可以使用Hamibot的"布局分析"功能查看控件ID
}

提示:当遇到控件难以定位时,使用Hamibot的"布局分析"功能(悬浮窗中的"布局分析"按钮)查看弹窗中按钮的具体属性,这是最有效的方法。点击"生成代码"可以直接获得该按钮的定位代码。

ℹ️ 本回答由 AI 生成,内容仅供参考