xpzouying/xiaohongshu-mcp · error

未找到商品搜索框

Error message

未找到商品搜索框

What it means

searchAndSelectProduct 在商品选择弹窗内按 placeholder 定位搜索框 input[placeholder="搜索商品ID 或 商品名称"] 失败:弹窗内容未渲染完成或 placeholder 文案变化。

Source

Thrown at xiaohongshu/publish.go:1263

			if visible {
				slog.Info("商品选择弹窗已出现")
				return modal, nil
			}
		}
		time.Sleep(100 * time.Millisecond) // 缩短轮询间隔,更快响应
	}

	return nil, errors.New("等待商品选择弹窗超时")
}

// searchAndSelectProduct 搜索并选择商品
func searchAndSelectProduct(ctx context.Context, page *rod.Page, modal *rod.Element, keyword string) error {
	slog.Info("搜索商品", "keyword", keyword)

	// 1. 获取搜索框
	searchInput, err := modal.Element(`input[placeholder="搜索商品ID 或 商品名称"]`)
	if err != nil {
		return errors.Wrap(err, "未找到商品搜索框")
	}

	// 2. 清空并输入关键词。SelectAllText 走 Eval(this.select()),只改选区、不额外
	// 派发事件,暂时保留(换键盘全选要区分 Ctrl/Cmd)。
	if err := searchInput.SelectAllText(); err != nil {
		slog.Warn("选择搜索框文本失败", "error", err)
	}
	time.Sleep(100 * time.Millisecond)

	if err := humanize.Type(ctx, searchInput, keyword); err != nil {
		return errors.Wrap(err, "输入搜索关键词失败")
	}
	time.Sleep(300 * time.Millisecond)

	// 3. 触发搜索(模拟键盘 Enter)
	if err := page.Keyboard.Press(input.Enter); err != nil {
		return errors.Wrap(err, "触发搜索失败")
	}

View on GitHub (pinned to 332d196854)

Solutions

  1. 先确认弹窗仍可见:modal.Visible(),不可见则重新点击添加商品按钮并等待弹窗
  2. 打印弹窗内所有 input 的 placeholder(modal.Elements("input") 遍历 Attribute),核对新文案后更新选择器
  3. 改用更宽松选择器,如 modal.Elements("input[type=text]") 后按 placeholder contains 过滤
  4. 增加超时或改为手动轮询 + 更长 deadline 以适应慢网络

Example fix

// before
searchInput, err := modal.Element(`input[placeholder="搜索商品ID 或 商品名称"]`)
if err != nil {
    return errors.Wrap(err, "未找到商品搜索框")
}
// after
inputs, err := modal.Elements("input")
if err != nil {
    return errors.Wrap(err, "未找到商品搜索框")
}
var searchInput *rod.Element
for _, in := range inputs {
    if ph, _ := in.Attribute("placeholder"); ph != nil && strings.Contains(*ph, "搜索商品") {
        searchInput = in
        break
    }
}
if searchInput == nil {
    return errors.New("未找到商品搜索框")
}
Defensive patterns

Strategy: validation

Validate before calling

if vis, _ := modal.Visible(); !vis {
    return errors.New("商品弹窗不可见,无法搜索")
}
inputs, _ := modal.Elements("input")
found := false
for _, in := range inputs {
    if ph, _ := in.Attribute("placeholder"); ph != nil && strings.Contains(*ph, "搜索商品") {
        found = true
    }
}
if !found {
    return errors.New("弹窗内未找到商品搜索输入框")
}

Try / catch

searchInput, err := modal.Element(`input[placeholder*="搜索商品"]`)
if err != nil {
    return fmt.Errorf("未找到商品搜索框(placeholder 可能已改版): %w", err)
}

Prevention

When it happens

Trigger: modal 传入了错误的元素引用;弹窗已关闭或被销毁;placeholder 文案被前端改版修改;弹窗加载慢超过 rod 默认超时;弹窗结构变化导致 input 不在 modal 子树内。

Common situations: 小红书改版调整了 placeholder 文案或输入框组件;waitForProductModal 拿到的 modal 在后续操作时已被关闭;页面语言/账号环境不同导致文案差异;网络慢渲染超时。

Related errors


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