如何用Google Apps Script点击分页按钮后抓取无URL变化的动态分页内容
结论
你当前使用的UrlFetchApp.fetch是纯静态HTTP请求工具,无法执行页面JavaScript、也无法模拟点击交互,所以不能直接实现你说的点击分页、等待加载的操作。但目标站点是典型的ASP.NET WebForm架构,分页依赖__doPostBack回调实现,你可以通过构造POST请求的方式实现全分页数据抓取,效果和你要的需求完全一致。
实现步骤
- 首次发送GET请求获取第一页内容、会话Cookie和ASP.NET必备的3个隐藏字段:
__VIEWSTATE、__VIEWSTATEGENERATOR、__EVENTVALIDATION - 从分页按钮的
href属性中提取每一页对应的__EVENTTARGET参数(就是__doPostBack方法的第一个入参) - 构造POST请求,携带Cookie、隐藏字段和对应页的
__EVENTTARGET参数,即可直接拿到对应分页的完整HTML内容 - 逐页解析HTML提取表格数据即可,无需额外等待加载,请求返回的就是渲染完成的分页内容
示例代码
// 目标页面地址 const TARGET_URL = "https://www.camara.cl/legislacion/ProyectosDeLey/tramitacion.aspx?prmID=14805&prmBOLETIN=14225-13"; function scrapeAllTablePages() { // 首次GET请求获取第一页数据和基础参数 const firstPageRes = UrlFetchApp.fetch(TARGET_URL); const cookies = firstPageRes.getAllHeaders()['Set-Cookie'].join('; '); let $ = Cheerio.load(firstPageRes.getContentText()); // 处理第一页表格数据 parseTable($); // 提取ASP.NET表单必填隐藏参数 const params = { __VIEWSTATE: $('input[name="__VIEWSTATE"]').val(), __VIEWSTATEGENERATOR: $('input[name="__VIEWSTATEGENERATOR"]').val(), __EVENTVALIDATION: $('input[name="__EVENTVALIDATION"]').val(), __EVENTARGUMENT: "" } // 遍历所有分页按钮(排除当前页的span标签) $('.paginacion.aleft a').each((index, el) => { // 提取当前分页对应的__EVENTTARGET值 const href = $(el).attr('href'); params.__EVENTTARGET = href.match(/__doPostBack\('([^']+)'/)[1]; // 构造POST请求配置 const options = { method: 'POST', headers: { 'Cookie': cookies, 'Content-Type': 'application/x-www-form-urlencoded' }, payload: params, followRedirects: true } // 请求对应分页内容 const pageRes = UrlFetchApp.fetch(TARGET_URL, options); $ = Cheerio.load(pageRes.getContentText()); // 处理当前页表格数据 parseTable($); // 按需添加延迟,避免请求频率过高被站点拦截 Utilities.sleep(1000); }) } // 自定义表格解析逻辑,可根据你的需求修改 function parseTable($) { // 示例:遍历表格行提取内容 $('table tr').each((i, row) => { const rowData = []; $(row).find('td').each((j, cell) => { rowData.push($(cell).text().trim()); }) // 这里可以写数据存储逻辑,比如存入Google Sheet console.log(rowData); }) }
注意事项
- 如果页数较多,可适当调整
Utilities.sleep的延迟时间,避免触发站点的反爬机制 - 如果后续站点更新了表单参数名,只需对应调整隐藏字段的提取逻辑即可
内容的提问来源于stack exchange,提问作者Oliver Mohr Bonometti
相关产品推荐
相关产品推荐

