如何在 puppeteer 中获得所有 xhr 调用?

Zha*_* Yi 5 javascript xmlhttprequest request node.js puppeteer

我正在使用puppeteer加载网页。

const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  await page.setRequestInterception(true);
  page.on('request', (request) => {
    console.log(request.url())
    request.continue();
    ...
  }
}
await page.goto(
    'https://www.onthehouse.com.au/property-for-rent/vic/aspendale-gardens-3195',
    { waitUntil: 'networkidle2' },
  );
Run Code Online (Sandbox Code Playgroud)

我将请求拦截设置为true并记录所有请求 url。我记录的请求比我在 chrome 浏览器中加载 url 时的请求少得多。至少有一个请求https://www.onthehouse.com.au/odin/api/compositeSearch可以在 chrome 开发工具控制台中找到,但没有显示在上面的代码中。

我想知道如何记录所有请求?

the*_*ton 7

我对该脚本的 4 个变体进行了一些基准测试。对我来说,结果是一样的。注意:我做了多次测试,有时由于本地网络速度的原因,调用次数较少。但经过 2-3 次尝试,Puppeteer 能够捕获所有请求。

https://www.onthehouse.com.au/property-for-rent/vic/aspendale-gardens-3195页面上有一些async脚本defer,我的假设是,当我们使用不同的 Puppeteer 设置或异步时,加载可能会有所不同与内部的同步功能page.on

注 2:我测试了另一个页面,而不是原始问题中的页面,因为我已经需要 VPN 来访问这个澳大利亚网站,通过 Chrome 很容易,使用 Puppeteer 则需要更多:相信我,我测试的页面也有类似的大量内容分析和跟踪请求。


Chrome 网络的基线:28 次调用

首先我访问了 xy 网页,结果是“网络”选项卡上有28 个调用

情况 1:原始(同步、networkidle2)

  await page.setRequestInterception(true);
  page.on('request', (request) => {
    console.log(request.url())
    request.continue();
    ...
  }
}
await page.goto(
    'https://www.onthehouse.com.au/property-for-rent/vic/aspendale-gardens-3195',
    { waitUntil: 'networkidle2' },
  );
Run Code Online (Sandbox Code Playgroud)

结果:28次调用

情况 2:异步,网络空闲2

里面有page.on一个异步函数,所以我们可以等待request.url()

  await page.setRequestInterception(true);
  page.on('request', async request => {
    console.log(await request.url())
    request.continue();
    ...
  }
}
await page.goto(
    'https://www.onthehouse.com.au/property-for-rent/vic/aspendale-gardens-3195',
    { waitUntil: 'networkidle2' },
  );
Run Code Online (Sandbox Code Playgroud)

结果:28次调用

情况 3:同步,networkidle0

与原版类似,但带有networkidle0.

  await page.setRequestInterception(true);
  page.on('request', (request) => {
    console.log(request.url())
    request.continue();
    ...
  }
}
await page.goto(
    'https://www.onthehouse.com.au/property-for-rent/vic/aspendale-gardens-3195',
    { waitUntil: 'networkidle0' },
  );
Run Code Online (Sandbox Code Playgroud)

结果:28次调用

情况 3:异步,networkidle0

里面有page.on一个异步函数,所以我们可以等待request.url()。再加上networkidle0

  await page.setRequestInterception(true);
  page.on('request', async request => {
    console.log(await request.url())
    request.continue();
    ...
  }
}
await page.goto(
    'https://www.onthehouse.com.au/property-for-rent/vic/aspendale-gardens-3195',
    { waitUntil: 'networkidle0' },
  );
Run Code Online (Sandbox Code Playgroud)

结果:28次调用


由于“网络”选项卡上的请求数量与来自 Puppeteer 的请求数量没有区别,因此无论我们启动 puppeteer 的方式还是收集请求的方式,我的想法都是:

  • 您已经在 Chrome 中接受了 Cookie 同意,因此网络将有更多请求(这些请求仅在接受 Cookie 后才会发生),您可以通过简单的导航接受他们的 Cookie 政策,因此在您导航到他们的页面后网络上将立即出现更多请求。

    [...] 继续使用我们的网站即表示您同意使用 cookie。

解决方案:不要直接访问所需的页面,而是通过点击导航到那里,这样您的 Puppeteer 的 Chromium 将接受 cookie 同意,因此您也将拥有所有分析请求。

  • 某些Chrome 插件会影响页面上的请求数量。

建议:根据隐身 Chrome 的“网络”选项卡检查您的 Puppeteer 请求,确保禁用所有扩展/插件。


+ 如果您只对XHR感兴趣,那么您可能需要添加request.resourceType到您的代码中以将它们与其他文档区分开来。