UNPKG

xiaohongshu-mcp-server

Version:

小红书 MCP 服务器 - 支持评论发布、内容获取等功能

177 lines (140 loc) 6.01 kB
# 评论功能冲突修复说明 ## 🔍 问题分析 ### 原始问题 用户反馈:**获取小红书评论工具在运行时会点开评论框,发表评论的工具却不能用** ### 根本原因 经过深入代码分析,发现问题确实是由于两个功能的代码交叉和逻辑冲突导致的: #### 1. **页面状态冲突** - **获取评论功能** (`get_note_comments`) 会主动操作页面: - 滚动到评论区 - 点击评论区展开评论 - 点击"查看更多评论"按钮 - 这些操作会**改变页面的DOM状态** - **发表评论功能** (`post_comment`) 需要查找评论输入框: - 但输入框的状态可能已经被获取评论功能改变 - 导致无法正确定位或操作输入框 #### 2. **元素选择器冲突** ```python # 发表评论时查找输入框的选择器 input_selectors = [ '[contenteditable="true"]', 'div[contenteditable="true"]', 'text="说点什么..."' ] # 获取评论时的操作会影响这些元素的状态 await comment_section.click() # 可能改变DOM结构 ``` #### 3. **时序问题** 如果用户先调用获取评论功能,再调用发表评论功能: - 页面滚动位置已改变 - 评论输入框可能被展开或隐藏 - DOM结构可能动态加载了新内容 ## 🛠️ 修复方案 ### 1. **优化 `find_comment_input` 方法** #### 新增页面状态重置功能 ```python async def find_comment_input(self, reset_page_state=True): if reset_page_state: # 滚动到页面顶部,重置视图 await self.browser.main_page.evaluate('window.scrollTo(0, 0)') # 关闭可能打开的评论展开状态 await self.browser.main_page.evaluate(''' () => { const closeButtons = document.querySelectorAll('[aria-label="关闭"], .close-btn'); closeButtons.forEach(btn => btn.click()); // 重置DOM状态 const expandedComments = document.querySelectorAll('.comment-expanded'); expandedComments.forEach(el => el.classList.remove('comment-expanded')); } ''') ``` #### 智能元素查找策略 ```python # 1. 优先选择包含评论相关文本的元素 for (const el of editableElements) { const text = el.textContent || el.placeholder || ''; if (text.includes('说点什么') || text.includes('评论')) { // 标记为优先目标 el.setAttribute('data-comment-input', 'priority-target'); return { found: true, type: 'priority' }; } } # 2. 备选方案:使用第一个可编辑元素 # 3. 最后方案:查找包含"说点什么"的任何元素并激活 ``` ### 2. **优化 `post_comment` 方法** #### 多策略查找机制 ```python # 策略1: 重置页面状态后查找 comment_input = await self.find_comment_input(reset_page_state=True) # 策略2: 点击触发元素激活输入框 if not comment_input: comment_triggers = ['text="写评论"', 'text="说点什么"'] for trigger_selector in comment_triggers: trigger_element = await self.browser.main_page.query_selector(trigger_selector) if trigger_element: await trigger_element.click() comment_input = await self.find_comment_input(reset_page_state=False) # 策略3: 滚动到不同位置查找 if not comment_input: scroll_positions = [0.3, 0.5, 0.7, 0.9] for position in scroll_positions: await self.browser.main_page.evaluate(f'window.scrollTo(0, document.body.scrollHeight * {position})') comment_input = await self.find_comment_input(reset_page_state=False) ``` ### 3. **优化 `send_comment` 方法** #### 更稳定的输入和发送逻辑 ```python # 分段输入,避免输入过快 for char in comment_text: await self.browser.main_page.keyboard.type(char) await asyncio.sleep(0.05) # 多种发送方法 # 方法1: 查找发送按钮 # 方法2: Enter键 # 方法3: Ctrl+Enter组合键 # 方法4: JavaScript强制发送 # 验证发送结果 input_after_send = await comment_input.evaluate('(el) => el.textContent') if not input_after_send.strip(): return True # 输入框已清空,发送成功 ``` ## ✅ 修复效果 ### 解决的问题 1. **✅ 页面状态冲突** - 通过页面状态重置机制解决 2. **✅ 元素选择器冲突** - 通过智能查找和优先级策略解决 3. **✅ 时序问题** - 通过多策略查找机制解决 4. **✅ 输入稳定性** - 通过分段输入和验证机制解决 5. **✅ 发送可靠性** - 通过多种发送方法和结果验证解决 ### 新增特性 - **智能页面状态重置** - 自动清理可能的冲突状态 - **多策略元素查找** - 提高输入框查找成功率 - **分段输入机制** - 避免输入内容丢失 - **多种发送方法** - 提高评论发送成功率 - **详细调试信息** - 便于问题排查 ## 🧪 测试验证 使用提供的测试脚本 `test_comment_fix.py` 可以验证修复效果: ```bash python test_comment_fix.py ``` 测试流程: 1. 登录验证 2. 获取评论功能测试 3. 发表评论功能测试(在获取评论之后) 4. 再次获取评论(验证状态恢复) 5. 再次发表评论(验证连续使用) ## 📋 使用建议 ### 最佳实践 1. **独立使用** - 尽量避免在短时间内频繁切换获取和发表评论功能 2. **等待间隔** - 两次操作之间建议间隔2-33. **错误处理** - 注意查看详细的错误信息和调试输出 ### 注意事项 - 修复后的代码会自动处理页面状态冲突 - 发表评论功能现在更加稳定和可靠 - 如遇到问题,查看控制台输出的详细调试信息 ## 🔄 向后兼容 所有修改都保持了向后兼容性: - 原有的API接口没有改变 - 原有的功能逻辑得到保留和增强 - 新增的参数都有默认值,不影响现有调用 这次修复彻底解决了获取评论和发表评论功能之间的冲突问题,大大提高了工具的稳定性和可用性。