Chromeは、ブラウザをヘッドレスモードで実行することを公式にサポートしています(Puppeteer APIやCRIライブラリを介したプログラムによる制御を含む)。
ドキュメントを検索しましたが、インスタンスからAJAXトラフィックをプログラムでキャプチャする方法が見つかりません(つまり、Chromeのインスタンスを開始する)コードから、ページに移動し、バックグラウンドの応答/リクエスト呼び出しと生データにアクセスします(すべてコードから開発者ツールまたは拡張機能を使用しません)。
これをどのように達成できるかを詳しく説明した提案や例はありますか?ありがとう!
更新
@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
を使用してリクエストをインターセプトすることもできますが、この例では、リクエストを変更しない場合は必要ありません。
画像リクエストを傍受する例 適応できるものがあります。
resourceType
sが定義されています ここ 。
私はついに自分がやりたいことをする方法を見つけました。 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)
})();
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)
}
})
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 });