puppeteer 13.0.0がリリースされました。
今回のリリースノートは以下のとおり。
BREAKING CHANGES
・typo in ‘already-handled’ constant of the request interception API
Features
・expose HTTPRequest intercept resolution state and clarify docs
・implement Element.waitForSelector
Bug Fixes
・handle multiple/duplicate Fetch.requestPaused events
・revert “feat(typescript): allow using puppeteer without dom lib”
・typo in ‘already-handled’ constant of the request interception API
https://github.com/puppeteer/puppeteer/releases/tag/v13.0.0
目立った変更はありませんが request interception に関するドキュメントがアップデートされてます。
request interceptionとは
puppeteerの強力な機能の1つとして、HTTP requestをinterceptすることができます。具体的には以下のようなコードで、’request’メッセージをonで拾います。この例ではGoogle Analyticsへのリクエストをブロックしています。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', (request) => {
if (/www\.google-analytics\.com/.test(request.url())) {
return request.abort();
}
return request.continue();
});
await page.goto('https://example.com');
await browser.close();
})();
これまではこのような記述でよかったのですが、Cooperative Interception Modeが実装されたことにより、少し書き換えが必要になりました。具体的には以下のように変わります。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', (request) => {
if (/www\.google-analytics\.com/.test(request.url())) {
return request.abort('failed', 0);
}
return request.continue(request.continueRequestOverrides(), 0);
});
await page.goto('https://example.com');
await browser.close();
})();
Cooperative Interception Modeとは
page.on(‘request’)はイベントリスナーですので、同じ’request’メッセージをlistenするイベントリスナーを複数定義することができます。ところがNodeJSは非同期です。そうすると、どのイベントリスナーから順番に実行すればいいのか分からなくなります。
上の例ではGoogle Analyticsをブロックするように書きました。でも、もしかしたらその前にGoogle Analyticsに対して処理するイベントリスナーを定義したいかもしれません。そうなると、どの順番で実行すればいいか保証されなくなってしまいます。
そこで、Cooperative Interception Modeが実装されました。従来の abort() や continue() の第2引数にpriorityを設定できるようになりました。これにより、プライオリティが高い順番にイベントリスナーが処理されるようになります。
なお、引数が指定されていない場合はLegacy Interception Modeとして実行されます。普通の用途では’request’メッセージに対するイベントリスナーは1つしか定義しないことがほとんどだと思いますので、基本的には第1引数、第2引数を設定することをお勧めします。