如何使用Puppeteer获取类名为calendarCellRegularPast的嵌套td元素
Puppeteer 批量获取.calendarCellRegularPast类TD元素的正确方法
前置必要步骤:确保元素已完成渲染
90%拿不到元素的问题都是因为代码执行时目标元素还没渲染到DOM里,执行前先加等待逻辑:
// 等待目标元素出现,超时时间可按需调整,单位毫秒 await page.waitForSelector('td.calendarCellRegularPast', { timeout: 8000 })
如果等待超时说明元素未渲染,可排查是否选择器写错、元素在iframe内、需要滚动后才加载等情况。
两种获取方案按需选择
方案1:获取元素对象(后续需要对元素做点击、hover等交互操作时用)
用page.$$直接批量获取所有符合选择器的ElementHandle对象,后续遍历处理属性即可:
await page.waitForSelector('td.calendarCellRegularPast') // 获取所有目标TD的ElementHandle数组 const targetCells = await page.$$('td.calendarCellRegularPast') // 遍历提取元素属性 for (const cell of targetCells) { // 提取类名 const className = await cell.evaluate(el => el.className) // 提取元素文本内容 const cellText = await cell.evaluate(el => el.textContent.trim()) // 提取自定义属性(比如存储日期的data-date属性,可根据实际DOM结构调整) const dateVal = await cell.evaluate(el => el.getAttribute('data-date')) console.log(className, cellText, dateVal) }
方案2:直接提取数据(不需要交互,只需要拿到日历内容时用)
用page.$$eval直接在浏览器上下文完成数据提取,返回普通JS数组,不需要跨上下文传递DOM对象,效率更高:
await page.waitForSelector('td.calendarCellRegularPast') // 直接返回提取好的日程数组 const scheduleList = await page.$$eval('td.calendarCellRegularPast', cells => { // 此处代码运行在浏览器环境,可直接操作DOM return cells.map(cell => { return { // 以下属性可根据你的实际DOM结构调整 date: cell.dataset.date || '', time: cell.querySelector('.time-label')?.textContent.trim() || '', content: cell.textContent.trim() } }) }) // 拿到的scheduleList是可直接使用的普通数组 console.log(scheduleList)
常见踩坑说明
page.evaluate内只能返回可序列化的普通数据(字符串、数字、数组、纯对象等),不能返回DOM元素对象,DOM对象无法从浏览器上下文传递到Node.js上下文,所以之前你代码中往数组里push DOM元素的操作是无效的- CSS选择器
nth-child需要带括号,比如tr:nth-child(2),不能漏掉括号 - 不要直接用超长的层级选择器,只要目标类名唯一,直接用类选择器
td.calendarCellRegularPast更稳定,页面结构微调也不会失效
内容的提问来源于stack exchange,提问作者ConnerWithAnE
相关产品推荐
相关产品推荐

