You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

网络爬取中XHR请求拦截与页面异步请求统计方法

爬取场景下XHR拦截与页面加载阶段异步请求统计方案

做网络数据爬取时,要拦截XHR请求、准确统计页面加载窗口期触发的Ajax/Fetch类异步请求总数,可根据你的爬取技术栈、目标站反爬强度选以下三类方案,都能拿到准确结果:

1. 原生JS钩子注入拦截

这是最轻量的实现方式,核心逻辑是在页面脚本执行前,重写浏览器原生的XHR和Fetch方法,在请求发起的节点做计数,同时绑定页面load事件作为统计截止点,避免把加载完成后用户交互触发的请求算进去。

注意:现在大部分站点的异步请求同时存在传统XHR和Fetch两种实现,必须同时拦截两类方法,否则会漏统计。

参考实现代码:

// 初始化计数器,标记页面加载状态
const asyncReqStats = { xhr: 0, fetch: 0, total: 0 };
let isPageLoaded = false;

// 重写XHR原型方法
const originXHROpen = XMLHttpRequest.prototype.open;
const originXHRSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function (method, reqUrl) {
  this._reqUrl = reqUrl;
  this._reqMethod = method;
  return originXHROpen.apply(this, arguments);
};
XMLHttpRequest.prototype.send = function () {
  if (!isPageLoaded) {
    asyncReqStats.xhr += 1;
    asyncReqStats.total += 1;
  }
  return originXHRSend.apply(this, arguments);
};

// 重写Fetch方法
const originFetch = window.fetch;
window.fetch = function (input, config) {
  if (!isPageLoaded) {
    asyncReqStats.fetch += 1;
    asyncReqStats.total += 1;
  }
  return originFetch.apply(this, arguments);
};

// 页面完全加载后停止计数
window.addEventListener('load', () => {
  isPageLoaded = true;
  console.log('页面加载阶段异步请求统计:', asyncReqStats);
});

这个方案的缺点是如果目标站有反爬检测,会识别到原生方法被改写,容易触发拦截。

2. 浏览器调试协议层面拦截

如果用Puppeteer、Playwright、Selenium这类自动化爬取框架,直接基于Chrome DevTools Protocol(CDP)监听网络事件即可,不需要注入脚本改写原生方法,隐蔽性更强,统计也更准确,还能自动识别iframe里的子页面请求,不会漏算。
参考Playwright下的实现逻辑:

const { chromium } = require('playwright');
(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  let asyncReqTotal = 0;
  let stopCount = false;

  // 全局监听所有网络请求
  page.on('request', (req) => {
    const type = req.resourceType();
    // 仅统计加载阶段的xhr、fetch类请求
    if (!stopCount && (type === 'xhr' || type === 'fetch')) {
      asyncReqTotal += 1;
    }
  });

  // 等待页面完全加载
  await page.goto('目标爬取页面地址', { waitUntil: 'load' });
  stopCount = true;
  console.log(`页面加载阶段共触发${asyncReqTotal}个异步请求`);
  await browser.close();
})();

这个方案是目前自动化爬取场景下最常用的,稳定性足够,也能绕过大部分基础反爬检测。

3. 中间人代理层流量拦截

如果目标站反爬强度极高,会检测浏览器环境、甚至改写原生请求逻辑,就直接在传输层做统计:把爬取流量全部转发到Mitmproxy这类中间人代理,代理侧记录所有经过的请求,同时由爬取端给代理发送「页面开始加载」「页面加载完成」的时间标记,在标记的时间窗口内筛选出接口类异步请求(可通过请求头X-Requested-With: XMLHttpRequest标识、返回值格式为JSON、接口路径特征等维度筛选)即可完成统计。
这个方案完全不侵入页面运行环境,不管前端做什么混淆、改写,都能拿到全量流量数据,统计准确率最高,缺点是需要额外搭建代理环境,配置成本稍高。


统计注意事项

  • 不要漏统计同域/跨域iframe内嵌页面里触发的异步请求
  • 注意过滤静态资源请求(js/css/图片/字体等),不要把这类资源请求算进Ajax异步请求的统计里
  • 要做去重处理,避免把前端自动重试、预加载触发的重复请求重复计数
  • 一定要以页面load事件作为统计截止锚点,不要把加载完成后鼠标滚动、点击等交互触发的请求算入页面加载阶段的统计范围

内容的提问来源于stack exchange,提问作者Amritesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:45:44