本文通过一个完整示例,演示如何使用Puppeteer自动访问后台系统、设置 Cookie、切换分页大小,并循环点击「下一页」抓取所有表格 HTML 数据。
一、应用场景说明
在实际项目中,我们经常遇到以下需求:
- 后台系统需要登录才能访问
- 数据列表有分页,需要自动翻页
- 希望批量抓取每一页的表格数据
- 页面基于 Element UI(
el-pager、btn-next)
本文将一步步实现:
✅ 打开后台页面
✅ 使用 Cookie 模拟登录
✅ 切换为50 条/页
✅ 自动计算总页数
✅ 循环点击「下一页」
✅ 抓取所有表格 HTML
二、环境准备
1. 安装 Puppeteer
npminstallpuppeteer2. Node.js 版本
建议使用:
- Node.js ≥ 14
- Puppeteer ≥ 19
三、完整示例代码
下面是完整可运行的示例代码:
constpuppeteer=require('puppeteer');constfs=require('fs');// 封装一个延时方法functionwaitForTimeout(time){returnnewPromise(resolve=>setTimeout(resolve,time));}(async()=>{constbrowser=awaitpuppeteer.launch({headless:false// 关闭无头模式,方便调试});try{constpage=awaitbrowser.newPage();awaitpage.setViewport({width:1920,height:800});// 1. 进入后台登录页面awaitpage.goto('http://localhost:8093/admin');// 2. 设置登录 Cookie(模拟已登录)constcookies=[{name:'Admin-Token',value:'你的 token',domain:'localhost',path:'/'}];// 如果需要启用 Cookie,取消注释// await page.setCookie(...cookies);// 3. 跳转到数据列表页awaitpage.goto('http://localhost:8093/category');// 4. 切换分页大小为 50 条/页constpageSizeXPath='//span[text()="50条/页"]';awaitpage.waitForXPath(pageSizeXPath);const[pageSizeBtn]=awaitpage.$x(pageSizeXPath);if(pageSizeBtn){awaitpageSizeBtn.evaluate(el=>el.click());console.log('已切换为 50 条/页');}// 5. 获取总页数awaitpage.waitForSelector('ul.el-pager');constliElements=awaitpage.$$('ul.el-pager li');constlastLi=liElements[liElements.length-1];lettotalPages=1;if(lastLi){totalPages=parseInt(awaitpage.evaluate(li=>li.textContent,lastLi));console.log('总页数:',totalPages);}// 6. 循环点击下一页并抓取表格consttableSelector='table';constnextBtnSelector='button.btn-next';awaitpage.waitForSelector(nextBtnSelector,{visible:true});letcurrentPage=1;letallTableHTML='';while(currentPage<=totalPages){console.log(`正在抓取第${currentPage}页`);// 抓取当前页表格consttables=awaitpage.$$(tableSelector);for(consttableoftables){consthtml=awaittable.evaluate(el=>el.outerHTML);allTableHTML+=html+'\n\n';}// 点击下一页constnextBtn=awaitpage.$(nextBtnSelector);if(!nextBtn)break;awaitnextBtn.click();awaitwaitForTimeout(3000);currentPage++;}console.log('分页抓取完成');// 7. 可选:保存为 HTML 文件fs.writeFileSync('tables.html',allTableHTML,'utf-8');console.log('表格 HTML 已保存到 tables.html');// await browser.close();}catch(e){console.error('发生错误:',e);}})();四、关键代码讲解
1️⃣ 模拟登录(Cookie)
awaitpage.setCookie({name:'Admin-Token',value:'xxx',domain:'localhost',path:'/'});适用于:
- 后台 token 登录
- 无需输入账号密码
- 常见于 Vue / Element UI 项目
2️⃣ XPath 精准点击「50条/页」
constxpath='//span[text()="50条/页"]';const[el]=awaitpage.$x(xpath);awaitel.evaluate(e=>e.click());优点:
- 不依赖 class
- 文本唯一即可定位
3️⃣ 获取 Element UI 总页数
ul.el-pager li:last-childElement UI 的分页结构非常规整,最后一个li就是最大页数。
4️⃣ 自动翻页核心逻辑
while(currentPage<=totalPages){awaitnextBtn.click();awaitwaitForTimeout(3000);}建议:
- 使用显式等待
- 避免点击过快导致请求丢失