web-dev-qa-db-ja.com

現在のページが残る前にPuppeteerでリクエストをインターセプトするにはどうすればよいですか?

使用事例:

ページからすべてのアウトバウンドルートをキャプチャする必要があります。それらのいくつかは、リンク要素を使用して実装されない場合があります<a src="...">ただし、JavaScriptコードを介して、またはGET/POSTフォームとして。

PhantomJS:

Phantomでは、onNavigationRequestedコールバックを使用してこれを行いました。セレクターで定義されたすべての要素をクリックし、onNavigationRequestedを使用してターゲットURLと、フォームの場合はメソッドまたはPOSTデータ)をキャプチャし、そのナビゲーションイベントをキャンセルしました。 。

人形遣い:

リクエストのインターセプトを試みましたが、リクエストがインターセプトされた時点で、現在のページはすでに失われているため、戻る必要があります。


ブラウザがイベントをトリガーしたページにまだいるときにナビゲーションイベントをキャプチャして停止する方法はありますか?

ありがとうございました。

3
Marek Trunkát

同じ問題が発生しました。Puppeteerは現在この機能をサポートしていません。実際には、サポートしていないのはchrome devtoolです。しかし、chromeを使用して、別の解決方法を見つけました。拡張機能。関連する問題: https://github.com/GoogleChrome/puppeteer/issues/82

問題の作者はここで解決策を共有しました。 https://Gist.github.com/GuilloOme/2bd651e5154407d2d2165278d5cd7cdb

doc が言うように、chrome.webRequest.onBeforeRequest.addListenerを使用して、ページからのすべてのリクエストをインターセプトし、必要に応じてブロックすることができます。

操り人形師の起動オプションに次のコマンドを追加することを忘れないでください。

--load-extension=./your_ext/ --disable-extensions-except=./your_ext/

2
rawidn

次のことができます。

await page.setRequestInterception(true);
page.on('request', request => {
  if (request.resourceType() === 'image')
    request.abort();
  else
    request.continue();
});

ここでの例:

https://github.com/GoogleChrome/puppeteer/blob/master/examples/block-images.js

使用可能なリソースタイプは次のとおりです。

https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#requestresourcetype

2
Ming C.

page.setRequestInterception(true);ドキュメントには非常に徹底的な例があります: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagesetrequestinterceptionvalue 。例(および以下)のようなロジックを追加して、画像リクエストを回避してください。それをキャプチャしてから、各リクエストを中止します。

page.on('request', interceptedRequest => {
     if (interceptedRequest.url.endsWith('.png') || 
                              interceptedRequest.url.endsWith('.jpg'))
         interceptedRequest.abort();
     else
         interceptedRequest.continue();
});
1
Bobby Singh

だから私はついにブラウザ拡張を必要とせず、したがってヘッドレスモードで動作するソリューションを発見しました:

この男へのThx: https://github.com/GoogleChrome/puppeteer/issues/823#issuecomment-46740864

page.on('request', req => {
  if (req.isNavigationRequest() && req.frame() === page.mainFrame() && req.url() !== url) {
    // no redirect chain means the navigation is caused by setting `location.href`
    req.respond(req.redirectChain().length
      ? { body: '' } // prevent 301/302 redirect
      : { status: 204 } // prevent navigation by js
    )
  } else {
    req.continue()
  }
})

編集:これを実装するヘルパー関数をApify SDKに追加しました-- https://sdk.apify.com/docs/api/puppeteer#puppeteer.enqueueLinksByClickingElements

ソースコード全体は次のとおりです。

https://github.com/apifytech/apify-js/blob/master/src/enqueue_links/click_elements.js

リクエストをインターセプトする必要があるだけでなく、新しく開いたウィンドウなどをキャッチする必要があるため、少し複雑です。

0
Marek Trunkát