{"record":{"id":"d967f8c039a85eef","repo":"xpzouying/xiaohongshu-mcp","slug":"error-d967f8","errorCode":null,"errorMessage":"未找到商品搜索框","messagePattern":"未找到商品搜索框","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/publish.go","lineNumber":1263,"sourceCode":"\t\t\tif visible {\n\t\t\t\tslog.Info(\"商品选择弹窗已出现\")\n\t\t\t\treturn modal, nil\n\t\t\t}\n\t\t}\n\t\ttime.Sleep(100 * time.Millisecond) // 缩短轮询间隔，更快响应\n\t}\n\n\treturn nil, errors.New(\"等待商品选择弹窗超时\")\n}\n\n// searchAndSelectProduct 搜索并选择商品\nfunc searchAndSelectProduct(ctx context.Context, page *rod.Page, modal *rod.Element, keyword string) error {\n\tslog.Info(\"搜索商品\", \"keyword\", keyword)\n\n\t// 1. 获取搜索框\n\tsearchInput, err := modal.Element(`input[placeholder=\"搜索商品ID 或 商品名称\"]`)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"未找到商品搜索框\")\n\t}\n\n\t// 2. 清空并输入关键词。SelectAllText 走 Eval(this.select())，只改选区、不额外\n\t// 派发事件，暂时保留（换键盘全选要区分 Ctrl/Cmd）。\n\tif err := searchInput.SelectAllText(); err != nil {\n\t\tslog.Warn(\"选择搜索框文本失败\", \"error\", err)\n\t}\n\ttime.Sleep(100 * time.Millisecond)\n\n\tif err := humanize.Type(ctx, searchInput, keyword); err != nil {\n\t\treturn errors.Wrap(err, \"输入搜索关键词失败\")\n\t}\n\ttime.Sleep(300 * time.Millisecond)\n\n\t// 3. 触发搜索（模拟键盘 Enter）\n\tif err := page.Keyboard.Press(input.Enter); err != nil {\n\t\treturn errors.Wrap(err, \"触发搜索失败\")\n\t}","sourceCodeStart":1245,"sourceCodeEnd":1281,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/publish.go#L1245-L1281","documentation":"searchAndSelectProduct 在商品选择弹窗内按 placeholder 定位搜索框 input[placeholder=\"搜索商品ID 或 商品名称\"] 失败：弹窗内容未渲染完成或 placeholder 文案变化。","triggerScenarios":"modal 传入了错误的元素引用；弹窗已关闭或被销毁；placeholder 文案被前端改版修改；弹窗加载慢超过 rod 默认超时；弹窗结构变化导致 input 不在 modal 子树内。","commonSituations":"小红书改版调整了 placeholder 文案或输入框组件；waitForProductModal 拿到的 modal 在后续操作时已被关闭；页面语言/账号环境不同导致文案差异；网络慢渲染超时。","solutions":["先确认弹窗仍可见：modal.Visible()，不可见则重新点击添加商品按钮并等待弹窗","打印弹窗内所有 input 的 placeholder（modal.Elements(\"input\") 遍历 Attribute），核对新文案后更新选择器","改用更宽松选择器，如 modal.Elements(\"input[type=text]\") 后按 placeholder contains 过滤","增加超时或改为手动轮询 + 更长 deadline 以适应慢网络"],"exampleFix":"// before\nsearchInput, err := modal.Element(`input[placeholder=\"搜索商品ID 或 商品名称\"]`)\nif err != nil {\n    return errors.Wrap(err, \"未找到商品搜索框\")\n}\n// after\ninputs, err := modal.Elements(\"input\")\nif err != nil {\n    return errors.Wrap(err, \"未找到商品搜索框\")\n}\nvar searchInput *rod.Element\nfor _, in := range inputs {\n    if ph, _ := in.Attribute(\"placeholder\"); ph != nil && strings.Contains(*ph, \"搜索商品\") {\n        searchInput = in\n        break\n    }\n}\nif searchInput == nil {\n    return errors.New(\"未找到商品搜索框\")\n}","handlingStrategy":"validation","validationCode":"if vis, _ := modal.Visible(); !vis {\n    return errors.New(\"商品弹窗不可见，无法搜索\")\n}\ninputs, _ := modal.Elements(\"input\")\nfound := false\nfor _, in := range inputs {\n    if ph, _ := in.Attribute(\"placeholder\"); ph != nil && strings.Contains(*ph, \"搜索商品\") {\n        found = true\n    }\n}\nif !found {\n    return errors.New(\"弹窗内未找到商品搜索输入框\")\n}","typeGuard":null,"tryCatchPattern":"searchInput, err := modal.Element(`input[placeholder*=\"搜索商品\"]`)\nif err != nil {\n    return fmt.Errorf(\"未找到商品搜索框(placeholder 可能已改版): %w\", err)\n}","preventionTips":["选择器用 placeholder 模糊匹配而非精确文案","操作前校验弹窗可见","监控前端改版：报错时打印弹窗 HTML 便于排查","给 Element 查找设置合理超时并轮询","避免复用可能已关闭的 modal 句柄"],"tags":["automation","rod","selector","dom"],"backgroundTag":"selector-not-found","analyzedSha":"332d196854a9eac0d2b8c2c0e3d0cc43139d724c","analyzedAt":"2026-09-05T22:22:55.988Z","contentChangedAt":"2026-09-05T22:22:55.988Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}