javascript - 如何将 puppeteer-core 与 Electron 一起使用?

标签 javascript typescript electron puppeteer

我从另一个 Stackoverflow 问题中得到了这段代码:

import electron from "electron";
import puppeteer from "puppeteer-core";

const delay = (ms: number) =>
  new Promise(resolve => {
    setTimeout(() => {
      resolve();
    }, ms);
  });

(async () => {
  try {
    const app = await puppeteer.launch({
      executablePath: electron,
      args: ["."],
      headless: false,
    });
    const pages = await app.pages();
    const [page] = pages;

    await page.setViewport({ width: 1200, height: 700 });
    await delay(5000);
    const image = await page.screenshot();
    console.log(image);
    await page.close();
    await delay(2000);
    await app.close();
  } catch (error) {
    console.error(error);
  }
})();

Typescript 编译器提示 executablePath launch 的属性(property)方法选项对象,因为它需要是 string 类型而不是 Electron .那么如何将 Electron Chrome 可执行路径传递给 puppeteer 呢?

最佳答案

如果没有一些变通方法和标志更改,您不能直接将 Electron 可执行文件与 Puppeteer 一起使用。他们在 API 上有很多不同。特别是 Electron 没有所有 Chrome 。* Chrome 浏览器正常工作所需的 API,许多标志仍然没有适当的替换,例如 the headless flag .

下面您将看到两种方法。但是你需要确保两点,

  • 确保在启动应用程序之前连接 puppeteer。
  • 确保您获得了在 Electron 中运行的 Chrome 版本的正确版本 puppeteer 或 puppeteer-core!

  • 使用puppeteer-in-electron
    有很多解决方法,但最近有一个 puppeteer-in-electron包,它允许您使用 Electron 在 Electron 应用程序中运行 puppeteer。

    首先,安装依赖项,
    npm install puppeteer-in-electron puppeteer-core electron
    

    然后运行它。
    import {BrowserWindow, app} from "electron";
    import pie from "puppeteer-in-electron";
    import puppeteer from "puppeteer-core";
    
    const main = async () => {
      const browser = await pie.connect(app, puppeteer);
    
      const window = new BrowserWindow();
      const url = "https://example.com/";
      await window.loadURL(url);
    
      const page = await pie.getPage(browser, window);
      console.log(page.url());
      window.destroy();
    };
    
    main();
    

    获取调试端口并连接到它

    另一种方法是获取 Electron 应用程序的远程调试端口并连接到它。此解决方案由 trusktr on electron forum 共享.
    import {app, BrowserWindow, ...} from "electron"
    import fetch from 'node-fetch'
    
    import * as puppeteer from 'puppeteer'
    
    app.commandLine.appendSwitch('remote-debugging-port', '8315')
    
    async function test() {
        const response = await fetch(`http://localhost:8315/json/versions/list?t=${Math.random()}`)
        const debugEndpoints = await response.json()
    
        let webSocketDebuggerUrl = debugEndpoints['webSocketDebuggerUrl ']
    
        const browser = await puppeteer.connect({
            browserWSEndpoint: webSocketDebuggerUrl
        })
    
        // use puppeteer APIs now!
    }
    
    // ... make your window, etc, the usual, and then: ...
    
      // wait for the window to open/load, then connect Puppeteer to it:
      mainWindow.webContents.on("did-finish-load", () => { 
        test()
      })
    

    上述两种解决方案都使用 webSocketDebuggerUrl 解决问题。

    额外的

    添加此注释是因为大多数人使用 Electron 捆绑应用程序。

    如果要构建 puppeteer-core 和 puppeteer-in-electron,需要使用 hazardouselectron-builder确保 get-port-cli作品。

    在 main.js 之上添加危险
    // main.js
    require ('hazardous');
    

    确保 get-port-cli 脚本已解压,在 package.json 中添加以下内容
    "build": {
      "asarUnpack": "node_modules/get-port-cli"
    }
    

    构建后的结果:

    关于javascript - 如何将 puppeteer-core 与 Electron 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58213258/

    相关文章:

    javascript - 如何动态(或不)将javascript移动到页脚

    javascript - 你如何判断 HTML5 视频是实时流还是来自 Javascript 的视频?

    javascript - 当删除同级项时,使 flex 元素自动调整大小以填充空间

    javascript - 在半圆内绘制点

    typescript - 为什么 WebStorm 显示 TypeScript 类型错误?

    javascript - Angular 2 (CLI) 路由不起作用(无法读取未定义的属性 'split')

    python - 无法读取 Javascript 文件 Electron JS 中未定义的属性 'join'

    angular - 如何使用 ion-col 响应式设置大型动态表数据

    git - 将仓库克隆到现有目录(已安装依赖项)

    windows - 如何从Windows中的底座或任务栏图标重新打开托盘中的 Electron 应用程序?