如何使用Axios get获取scroll pagination场景下的全量数据
axios拉取滚动分页站点全量数据实现方案
滚动分页本质是前端触发的分段接口请求,不存在“必须模拟滚动才能拿到数据”的情况,直接按接口规则循环拉取即可,步骤如下:
- 先定位真实分页接口
打开目标页面的浏览器开发者工具,切到「网络」面板筛选Fetch/XHR请求,手动滚动页面到底触发分页加载,观察连续几次分页请求的规律:- 记录分页参数类型:常见的分两类,一类是页码参数(比如
page/pageNum,从1开始逐次递增),一类是游标参数(比如cursor/lastId/after,每次取上一页最后一条数据的ID、或者接口直接返回下一页的游标值作为请求参数) - 记录终止判定规则:通常接口返回数据条数小于单页约定大小、返回
hasNext: false字段、直接返回空数组时,代表已经到最后一页 - 记录校验规则:注意接口是否需要带Cookie、Referer、User-Agent、动态签名等校验参数,避免请求被拦截
- 记录分页参数类型:常见的分两类,一类是页码参数(比如
- 编写循环拉取逻辑
直接用循环/递归逐次发起axios请求,每次请求带上对应分页参数,拉到的数据合并到总结果集,直到触发终止条件即可。参考实现代码(以最常见的游标分页为例):
const axios = require('axios'); const fs = require('fs'); async function fetchAllData(apiUrl, pageSize = 20) { const totalResult = []; let nextCursor = null; // 第一页请求游标传空 let isEnd = false; // 基础请求配置,模拟普通浏览器请求,避免被基础反爬拦截 const baseConfig = { headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36', 'Referer': apiUrl, // 有登录校验的话把浏览器里的Cookie贴到这里 // 'Cookie': '你的登录Cookie' } }; while (!isEnd) { try { const resp = await axios.get(apiUrl, { ...baseConfig, params: { pageSize, cursor: nextCursor // 如果是页码型分页,就把上面的cursor换成page参数,初始值设为1,每次请求后自增即可 } }); // 注意按实际接口的返回结构调整取值路径,常见的结构有resp.data.list、resp.data.data.records等 const currentPageData = resp.data?.data?.list || []; totalResult.push(...currentPageData); // 判定是否到最后一页 if (currentPageData.length < pageSize) { isEnd = true; } else { // 取下一页游标:如果接口直接返回nextCursor字段就直接用,否则取当前页最后一条数据的id作为游标 nextCursor = resp.data?.data?.nextCursor || currentPageData.at(-1).id; // 加300-1000ms的随机延迟,避免请求太频繁触发限流 await new Promise(resolve => setTimeout(resolve, 300 + Math.random() * 700)); } } catch (e) { console.error(`拉取出错,已获取${totalResult.length}条数据`, e.message); // 这里可以加重试逻辑,比如重试3次失败再终止 break; } } return totalResult; } // 调用示例 fetchAllData('你抓包拿到的真实分页接口地址') .then(res => { console.log(`拉取完成,共${res.length}条数据`); // 数据存本地文件 fs.writeFileSync('./full_data.json', JSON.stringify(res, null, 2)); });
- 注意事项
- 不要用Puppeteer/Playwright模拟页面滚动的方案拉数,这类方案内存占用高、拉取效率极低,只要能拿到接口规则直接调用接口是性价比最高的方案
- 如果接口带动态签名校验,需要先逆向页面前端的签名生成逻辑,每次请求前生成合法签名参数再发起请求
- 拉取过程中如果触发IP限流,适当调大请求间隔,或者轮换代理IP即可,不要高频请求占用目标站点过多服务器资源
内容的提问来源于stack exchange,提问作者Luk Martins
相关产品推荐
相关产品推荐

