13

Chrome 官方支持以无头模式运行浏览器(包括通过 Puppeteer API 和/或 CRI 库进行编程控制)。

我已经搜索了文档,但我还没有找到如何以编程方式从实例中捕获 AJAX 流量(即从代码启动 Chrome 实例,导航到页面,并访问后台响应/请求调用和原始数据(全部来自不使用开发人员工具或扩展的代码)。

您是否有任何建议或示例详细说明如何实现这一目标?谢谢!

4

4 回答 4

16

更新

正如@Alejandro 在评论中指出的那样,resourceType是一个函数,返回值是小写的

page.on('request', request => {
    if (request.resourceType() === 'xhr')
    // do something
});

原始答案

Puppeteer 的 API 让这变得非常简单:

page.on('request', request => {
  if (request.resourceType === 'XHR')
    // do something
});

您也可以使用 拦截请求setRequestInterception,但如果您不打算修改请求,则在此示例中不需要它。

有一个你可以适应的拦截图像请求的例子。

resourceTypes 在这里定义。

于 2017-09-06T22:02:28.390 回答
4

我终于找到了如何做我想做的事。它可以用chrome-remote-interface(CRI) 和node.js. 我附上了所需的最少代码。

const CDP = require('chrome-remote-interface');

(async function () {

    // you need to have a Chrome open with remote debugging enabled
    // ie. chrome --remote-debugging-port=9222
    const protocol = await CDP({port: 9222});

    const {Page, Network} = protocol;
    await Page.enable();
    await Network.enable(); // need this to call Network.getResponseBody below

    Page.navigate({url: 'http://localhost/'}); // your URL

    const onDataReceived = async (e) => {
        try {
            let response = await Network.getResponseBody({requestId: e.requestId})
            if (typeof response.body === 'string') {
                console.log(response.body);
            }
        } catch (ex) {
            console.log(ex.message)
        }
    }

    protocol.on('Network.dataReceived', onDataReceived)
})();
于 2017-09-06T18:50:37.387 回答
3

Puppeteer 的侦听器可以帮助您通过事件捕获 xhrresponse响应request

你应该先检查request.resourceType()xhr还是fetch先。

        listener = page.on('response', response => {
            const isXhr = ['xhr','fetch'].includes(response.request().resourceType())
            if (isXhr){
                console.log(response.url());
                response.text().then(console.log)
            }
        })
于 2019-03-09T15:24:30.790 回答
1
const browser = await puppeteer.launch();
const page = await browser.newPage();
const pageClient = page["_client"];
pageClient.on("Network.responseReceived", event => {
  if (~event.response.url.indexOf('/api/chart/rank')) {
    console.log(event.response.url);
    pageClient.send('Network.getResponseBody', {
      requestId: event.requestId
    }).then(async response => {
      const body = response.body;
      if (body) {
        try {
          const json = JSON.parse(body);

        }
        catch (e) {
        }
      }
    });
  }
});

await page.setRequestInterception(true);
page.on("request", async request => {
  request.continue();
});
await page.goto('http://www.example.com', { timeout: 0 });
于 2019-07-31T06:25:50.687 回答