在不阻塞cli的情况下启动puppeteer

问题描述 投票:0回答:1

使用 puppeteer,我编写了一个将从命令行执行的代码,我想打开浏览器,导航到网页,保持浏览器打开并保留对命令行的控制。

// index.js
(async() => { 
  const browser = await puppeteer.launch({
    headless: false,
  });
  const page = await browser.newPage();
  await page.goto("https://stackoverflow.com");
})();

但是当浏览器打开时,命令行永远不会重新获得控制权(必须调用

browser.close()
,但这不是我想要的)。我怎样才能使代码不阻塞命令行? (我不想从命令行执行代码后台(将 & 附加到执行命令))

puppeteer
1个回答
0
投票

听起来您想使用 Puppeteer 启动浏览器,然后在不关闭浏览器的情况下断开连接,然后能够使用另一个脚本重新连接到同一浏览器,或者下次运行同一脚本时。

问题在于,当 Node 进程使用

puppeteer.launch()
生成浏览器进程时,子浏览器进程并未分离,因此杀死父进程也会杀死子进程。根据 this current open issues,目前没有分离浏览器子进程的选项。

在支持之前,这里有一个在 Ubuntu 22.04 上测试的有点 hacky 的解决方法,使用 Chromium 版本 125.0.6422.141(官方版本)snap(64 位)、Node 22.11.1 和 Puppeteer ^22.10.0,使用 Node 的

spawn
来启动浏览器并分离子项。

const {setTimeout} = require("node:timers/promises");
const {spawn} = require("node:child_process");
const puppeteer = require("puppeteer"); // ^22.10.0

const reconnectOrLaunch = async (
  browserURL = "http://localhost:9222"
) => {
  try {
    return await puppeteer.connect({browserURL});
  } catch (err) {
    const childProcess = spawn(
      "chromium",
      [`--remote-debugging-port=${browserURL.split(":").pop()}`],
      {
        detached: true,
        stdio: "ignore",
      }
    );
    childProcess.unref();

    // Hack: poll until browser connection succeeds
    for (let tries = 1_000; tries > 0; tries--) {
      await setTimeout(100);

      try {
        return await puppeteer.connect({browserURL});
      } catch (err) {}
    }

    throw Error("Unable to connect to browser");
  }
};

let browser;
(async () => {
  browser = await reconnectOrLaunch();
  const [page] = await browser.pages();
  await page.goto("https://www.example.com", {
    waitUntil: "domcontentloaded",
  });
  console.log(await page.$eval("h1", el => el.textContent));
})()
  .catch(err => console.error(err))
  .finally(() => browser?.disconnect());

由于浏览器尚未立即准备就绪,因此我将进行轮询,直到其准备就绪。当然还有改进的空间,但这应该可以帮助您开始。

另请参阅在 Puppeteer 中连接浏览器,了解有关连接和断开远程调试端口的一些背景知识。

© www.soinside.com 2019 - 2024. All rights reserved.