xpzouying/xiaohongshu-mcp · error

点击商品选择框失败

Error message

点击商品选择框失败

What it means

searchAndSelectProduct 已定位商品勾选框、确认未选中后 humanize.Click 点击失败:勾选框被遮挡或列表在点击瞬间重渲染,商品未能选中。

Source

Thrown at xiaohongshu/publish.go:1327

	// 5. 点击第一个商品的 checkbox(使用与工作代码相同的选择器)
	checkbox, err := modal.Element(".goods-list-normal .good-card-container .d-checkbox")
	if err != nil {
		return errors.Wrap(err, "未找到商品选择框")
	}

	// 检查是否已经选中
	isChecked, err := checkbox.Eval(`(el) => {
		return el.querySelector('.d-checkbox-simulator.checked') !== null ||
			   el.querySelector('input[type="checkbox"]:checked') !== null;
	}`)
	if err == nil && isChecked.Value.Bool() {
		slog.Info("商品已选中,跳过", "keyword", keyword)
		return nil
	}

	if err := humanize.Click(checkbox); err != nil {
		return errors.Wrap(err, "点击商品选择框失败")
	}

	randomDelay := 800 + rand.Intn(700)
	time.Sleep(time.Duration(randomDelay) * time.Millisecond)

	slog.Info("已选择商品", "keyword", keyword)
	return nil
}

// clickModalSaveButton 点击保存按钮
func clickModalSaveButton(modal *rod.Element) error {
	// 查找保存按钮(参考工作代码:直接查找并点击,不强制要求找到)
	btn, err := modal.Element(".goods-selected-footer button")
	if err == nil && btn != nil {
		if err := humanize.Click(btn); err != nil {
			slog.Warn("点击保存按钮失败", "error", err)
		} else {
			slog.Info("已点击保存按钮")

View on GitHub (pinned to 332d196854)

Solutions

  1. 重试整个 searchAndSelectProduct 流程(重新搜索、重新定位、再点击),瞬时 detached 通常一次重试即可成功
  2. 点击前用 checkbox.WaitStable / WaitVisible 确认元素稳定后再点
  3. 改用 JS 点击兜底:checkbox.Eval(`(el) => el.click()`)
  4. 增加渲染后等待时间(500ms 太短),或等待 checkbox 的位置稳定

Example fix

// before
if err := humanize.Click(checkbox); err != nil {
    return errors.Wrap(err, "点击商品选择框失败")
}
// after
if err := checkbox.WaitStable(300 * time.Millisecond); err != nil {
    return errors.Wrap(err, "等待商品选择框稳定失败")
}
if err := humanize.Click(checkbox); err != nil {
    // 兜底:JS 直接触发 click
    if _, jsErr := checkbox.Eval(`(el) => el.click()`); jsErr != nil {
        return errors.Wrap(jsErr, "点击商品选择框失败")
    }
}
Defensive patterns

Strategy: retry

Validate before calling

// 点击前确认元素可见且稳定
if err := checkbox.WaitVisible(); err != nil {
    return errors.Wrap(err, "checkbox 不可见")
}
if err := checkbox.WaitStable(300 * time.Millisecond); err != nil {
    return errors.Wrap(err, "checkbox 未稳定")
}

Type guard

func clickable(el *rod.Element) bool {
    if el == nil {
        return false
    }
    return el.MustVisible()
}

Try / catch

const maxRetry = 3
var lastErr error
for i := 0; i < maxRetry; i++ {
    if err := humanize.Click(checkbox); err == nil {
        lastErr = nil
        break
    } else {
        lastErr = err
        time.Sleep(time.Second)
    }
}
if lastErr != nil {
    return errors.Wrap(lastErr, "点击商品选择框失败")
}

Prevention

When it happens

Trigger: humanize.Click 执行期间:元素被遮挡(覆盖层/浮层);DOM 在点击瞬间被 React 重渲染替换导致 detached;页面导航或弹窗关闭使元素句柄失效;humanize 内部滚动到元素失败。

Common situations: 搜索结果加载后 500ms 内前端又重排了列表(sleep 太短);页面弹出新的提示遮罩;小红书对自动化点击的风控拦截导致页面无响应;浏览器标签页被切换/最小化影响 humanize 的鼠标轨迹模拟。

Related errors


AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05). Data as JSON: /api/errors/adf16af41d7a20a0. Report an issue: GitHub.