Puppeteer爬取chat.kuki.ai时page.evaluate搭配querySelectorAll返回空值问题
Puppeteer爬取chat.kuki.ai对话内容的解决方案
问题根因拆解
- 选择器语法完全错误:你当前传入的选择器
.pb-chat-bubble pb-chat-bubble__bot根本没法匹配到目标元素。CSS选择器里,类名前面必须带点号,两个类写在同一个选择器里如果不加空格,才代表匹配同时带有这两个类的元素;加了空格就变成查找父元素下的子节点。你现在的写法实际是匹配所有.pb-chat-bubble元素内部、标签名叫pb-chat-bubble__bot的节点,这类节点在站点里不存在,自然返回空数组。按照站点的BEM命名规范,机器人对话气泡的专属类就是.pb-chat-bubble--bot,不需要拼接多余的类名。 - 执行上下文错误:站点的整个聊天面板是嵌套在
#chatframe同源iframe里的,你在主页面的上下文中查询DOM,根本访问不到iframe内部的节点。很多人在DevTools里能手动选中元素,是因为DevTools会自动定位到元素所在的iframe上下文,不代表代码在主页面里能直接查到。 - 没有等待动态内容渲染:聊天对话是异步接口返回后才渲染到页面上的,页面刚加载完成就执行查询,DOM里还没有对应的气泡节点,自然拿不到结果。
可直接复用的修正代码
// 等待聊天iframe完成加载 const chatFrameElement = await page.waitForSelector('#chatframe', { timeout: 30000 }); const chatFrame = chatFrameElement.contentFrame(); // 等待机器人回复气泡挂载到DOM await chatFrame.waitForSelector('.pb-chat-bubble--bot', { timeout: 30000 }); // 批量提取所有机器人回复的文本内容 const botResponses = await chatFrame.evaluate(() => { const bubbleNodes = Array.from(document.querySelectorAll('.pb-chat-bubble--bot')); return bubbleNodes.map(node => node.innerText.trim()); });
快速排错方法
- 每次写选择器,先在DevTools控制台执行
document.querySelectorAll('你的选择器'),确认返回的NodeList长度和预期一致,不要靠记忆默写类名。 - 如果查询结果始终为空,可以在evaluate逻辑里打印当前上下文的
window.location.href,确认代码是不是真的在聊天面板所在的iframe里执行,不是在主页面跑的空查询。 - 不要用写死的
setTimeout硬等渲染,统一用waitForSelector触发等待,避免因为网络波动导致元素还没加载出来就提前执行查询。
内容的提问来源于stack exchange,提问作者Isukali
相关产品推荐
相关产品推荐

