web-dev-qa-db-ja.com

プログラムでAJAXヘッドレスでトラフィックをキャプチャChrome

Chromeは、ブラウザをヘッドレスモードで実行することを公式にサポートしています(Puppeteer APIやCRIライブラリを介したプログラムによる制御を含む)。

ドキュメントを検索しましたが、インスタンスからAJAXトラフィックをプログラムでキャプチャする方法が見つかりません(つまり、Chromeのインスタンスを開始する)コードから、ページに移動し、バックグラウンドの応答/リクエスト呼び出しと生データにアクセスします(すべてコードから開発者ツールまたは拡張機能を使用しません)。

これをどのように達成できるかを詳しく説明した提案や例はありますか?ありがとう!

7
Andrei

更新

@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が定義されています ここ

13
ebidel

私はついに自分がやりたいことをする方法を見つけました。 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)
})();
3
Andrei

Puppeteerのリスナーは、responseおよびrequestイベントを介してxhr応答をキャプチャするのに役立ちます。

最初にrequest.resourceType()xhrであるかfetchであるかを確認する必要があります。

        listener = page.on('response', response => {
            const isXhr = ['xhr','fetch'].includes(response.request().resourceType())
            if (isXhr){
                log(response.url());
                response.text().then(log)
            }
        })
2
ahuigo
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 });
0
Sun