如何用Node.js/Puppeteer抓取页面指定元素的完整数据?
解决方案
1. 解决姓名仅获取首字母的问题
先确认目标元素的真实文本结构:
- 打开浏览器开发者工具,检查
cse-ul--name元素,看完整姓名是直接在元素的textContent中,还是存储在data-*属性里,或是有隐藏子元素承载真实姓名。 - 修正选择逻辑,避免误选到首字母占位元素:
// 如果姓名直接在元素文本中 const name = element.querySelector('.cse-ul--name').textContent.trim(); // 如果姓名存储在自定义属性中(比如data-fullname) const name = element.querySelector('.cse-ul--name').dataset.fullname;
2. 解决仅能抓取可见区域数据的问题
这类情况大多是页面采用滚动懒加载,只有进入视口的元素才会被渲染。需要先模拟滚动加载所有数据,再执行抓取:
实现滚动加载的通用逻辑
async function autoScroll(page) { await page.evaluate(async () => { await new Promise((resolve) => { let totalHeight = 0; const scrollStep = 100; const timer = setInterval(() => { const currentScrollHeight = document.body.scrollHeight; window.scrollBy(0, scrollStep); totalHeight += scrollStep; // 当滚动高度不再变化时,说明已加载全部内容 if (totalHeight >= currentScrollHeight) { clearInterval(timer); resolve(); } }, 100); }); }); }
完整抓取流程示例
// 登录完成后执行 await page.waitForSelector('.cse-userslist-user'); // 等待目标元素初始加载 // 滚动加载全部数据 await autoScroll(page); // 可选:等待最后一批元素渲染完成(根据页面加载速度调整时长) await page.waitForTimeout(1000); // 批量抓取所有用户数据 const userData = await page.evaluate(() => { return Array.from(document.querySelectorAll('.cse-userslist-user')).map(userItem => { const nameEl = userItem.querySelector('.cse-ul--name'); const positionEl = userItem.querySelector('.cse-ul--position'); const roleEl = userItem.querySelector('.cse-ul--role'); return { name: nameEl ? nameEl.textContent.trim() : '未知', position: positionEl ? positionEl.textContent.trim() : '未知', role: roleEl ? roleEl.textContent.trim() : '未知' }; }); }); console.log(userData); // 输出全部抓取到的用户数据
3. 将数据存入Excel文件
使用xlsx库实现Excel导出:
- 安装依赖:
npm install xlsx - 写入代码:
const XLSX = require('xlsx'); // 将JSON数据转换为工作表 const worksheet = XLSX.utils.json_to_sheet(userData); // 创建工作簿并添加工作表 const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, '用户列表'); // 导出为Excel文件 XLSX.writeFile(workbook, '用户数据.xlsx');
内容的提问来源于stack exchange,提问作者Julian Zientkowski
相关产品推荐
相关产品推荐

