【问题标题】:How to intercept request in Puppeteer before current page is left?如何在离开当前页面之前拦截 Puppeteer 中的请求?
【发布时间】:2018-04-14 16:33:36
【问题描述】:

用例:

我们需要从一个页面捕获所有出站路由。其中一些可能不是使用链接元素<a src="..."> 实现的,而是通过一些javascript 代码或GET/POST 表单实现的。

PhantomJS:

在 Phantom 中,我们使用 onNavigationRequested 回调来完成此操作。我们只需单击某个选择器定义的所有元素并使用onNavigationRequested 来捕获目标 url 以及可能的方法或表单数据,然后取消该导航事件。

木偶师:

我尝试了请求拦截,但在请求被拦截的那一刻,当前页面已经丢失,所以我不得不返回。


有没有办法在浏览器仍在触发事件的页面时捕获导航事件并停止它?

谢谢。

【问题讨论】:

    标签: puppeteer


    【解决方案1】:

    您可以执行以下操作。

    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】:

      所以我终于找到了不需要浏览器扩展的解决方案,因此可以在无头模式下工作:

      感谢这个人:https://github.com/GoogleChrome/puppeteer/issues/823#issuecomment-467408640

      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

      稍微复杂一点,因为它不仅需要拦截请求,还需要捕获新打开的窗口等。

      【讨论】:

        【解决方案3】:

        我遇到了同样的问题。Puppeteer 现在不支持该功能,实际上是 chrome devtool 不支持它。但是我找到了另一种方法来解决它,使用 chrome extension。相关问题:https://github.com/GoogleChrome/puppeteer/issues/823

        问题的作者分享了一个解决方案 这里。 https://gist.github.com/GuilloOme/2bd651e5154407d2d2165278d5cd7cdb

        正如doc 所说,我们可以使用chrome.webRequest.onBeforeRequest.addListener 拦截来自页面的所有请求,如果您愿意,可以阻止它。

        不要忘记在 puppeteer 启动选项中添加以下命令:

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

        【讨论】:

          【解决方案4】:

          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();
          });
          

          【讨论】:

            猜你喜欢
            • 2019-12-31
            • 2014-12-01
            • 2019-07-08
            • 2022-01-22
            • 2018-03-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多