【问题标题】:Is it safe to run multiple instances of Puppeteer at the same time?同时运行多个 Puppeteer 实例是否安全?
【发布时间】:2018-01-18 09:23:34
【问题描述】:

同时运行多个 Puppeteer 实例是否安全/受支持,无论是在

  1. 进程级别(多个node screenshot.js同时)或
  2. 在脚本级别(多个puppeteer.launch()同时)?

并行进程的推荐设置/限制是什么?

(在我的测试中,(1) 似乎工作正常,但我想知道 Puppeteer 与 Chrome 的单个 (?) 实例交互的可靠性。我没有尝试过 (2) 但这似乎不太可能解决。)

【问题讨论】:

    标签: google-chrome-devtools puppeteer


    【解决方案1】:

    可以并行运行多个浏览器、上下文甚至页面。限制取决于您的网络/磁盘/内存和任务设置。

    我爬了几百万页,有时(在我的设置中,每个~10,000 pages)puppeteer 会崩溃。因此,您应该有办法自动重启浏览器并重试该作业。

    您可能想查看puppeteer-cluster,它负责合并浏览器实例、重新启动和崩溃检测/重新启动。 (免责声明:我是作者)

    创建集群的示例如下:

    // create a cluster that handles 10 parallel browsers
    const cluster = await Cluster.launch({
        concurrency: Cluster.CONCURRENCY_BROWSER,
        maxConcurrency: 10,
    });
    
    // Queue your jobs (one example)
    cluster.queue(async ({ page }) => {
        await page.goto('http://www.wikipedia.org');
        await page.screenshot({path: 'wikipedia.png'});
    });
    

    这只是一个最小的例子。使用集群的方法还有很多。

    【讨论】:

    • 感谢您的包裹。我见过的最好的之一。对于想要自动重启浏览器并重试作业的人,他们可以使用 pm2。
    • @Thomas 遇到过.type("text") 会在不同实例之间混淆的情况吗?我打开了几个窗口(不使用 puppeteer-cluster),它出现在我发送 .type 命令时,字符会在窗口之间混淆(用于窗口 1 的部分字符串会被输入到窗口 2 中,等等。 )。意识到这一点?有什么技巧可以避免这个问题吗?你们的图书馆会处理这种情况吗?
    • @AryehArmon 我最终不得不“单一实例”我的应用程序并一次将类型命令发送到一个浏览器/页面/文本框。我不确定 puppeteer 如何实现type API,但看起来它基本上将键盘事件发送到操作系统,操作系统确定哪个“窗口”和“文本框”具有焦点并将关键事件发送到该输入。所以,是的,我不能同时输入多个输入,我不得不限制我的应用一次只向 1 个输入框发送按键事件。
    • 单线程并不意味着 javascript 不能与在其上下文之外运行的多个并发进程进行交互。异步编程允许单个线程在其他线程等待时跳转并处理许多任务。就像餐厅的服务员提供多张桌子一样。
    【解决方案2】:

    每个puppeteer.launch() 都会启动一个新的浏览器供您的脚本驱动,因此最好让一个脚本与多个puppeteer.launch 调用交互,而不是运行多个脚本实例。即使 node 是单线程的,事件也会通过 WebSockets 发送到浏览器,这意味着您将从 node 的异步行为中受益。换一种说法:这些进程都不是串行运行的,而是并行运行,即使考虑到单线程性质。

    在某些背景下,我运行了一个名为 browserless (https://browserless.io) 的服务,旨在生产化基于 Web 的工作。我也在 docker 上维护了一些图片:https://hub.docker.com/r/browserless/chrome/

    【讨论】:

      【解决方案3】:

      两者都可以,但第二个并没有真正的意义。原因是因为 nodeJS 我是单线程的。因此,即使进程可以工作,在一个进程中而不是在多个进程中使用多个浏览器实例也不会更快更容易。最好的选择是像以前一样运行 (1),唯一需要记住的是保持测试自包含。

      【讨论】:

      • 我不明白为什么第二个没有意义。为什么多个同时 puppeteer.launch() 不能以与多个同时 fetch() 相同的方式工作?
      • 当 nodeJS 与外界(浏览器)通信时,它一次只能执行一项任务。因此,即使您打开多个 chrome,您也无法从多个 chrome 中接收数据。您的脚本将正常工作,但仅在一个浏览器运行时不会出现任何性能差异(如果您的网站速度非常慢并且您将在两个浏览器实例之间切换,则可能会有差异)。 fetch 以同样的方式工作顺便说一句,您不能“完全”同时处理两个响应,因此如果您在同一毫秒收到两个响应,您将一个接一个地处理它们。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多