将 puppeteer 任务整合为一项任务 [英] Intergrate puppeteer tasks into one single task

查看:67
本文介绍了将 puppeteer 任务整合为一项任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了几个看起来像这样的 javascript 文件:

I created several javascript files which looks like this:

const somedata = ""
const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch();
  const pages = await browser.pages();
  const page = pages[0];
  await page.goto('https://somewebsite.com');

  ///Do some task

  browser.close();
})();

我设法使用每个单独的文件执行单个操作.现在,我只想创建一个浏览器实例并执行这些单个文件中指定的任务.我想在每个任务中传递一些数据.此外,一次只能打开五页.

I managed to perform single operation using each individual file . Now, I want to create only one browser instance and do task specified in those individual files. I want pass some data in each of the task. Also at a time only five pages should be remain open.

我正在使用 puppeteer 和 NodeJS.

I'm using puppeteer and NodeJS.

推荐答案

可以创建一个BrowserService,它是一个单例,封装页面的创建和删除:

You can create a BrowserService that is a singleton and encapsulate the page creation and deletion:

// BrowserService.ts
export class BrowserService {
    public static instance: BrowserService | null = null;

    public static async getInstance(): Promise<BrowserService> {
        if (this.instance == null) {
            this.instance = new BrowserService();
            await this.instance.initialise();
        }

        return this.instance;
    }

    private browser: PuppeteerBrowser;

    private numberPages: number = 0;

    private constructor() { }

    /**
     * Get a browser page.
     */
    public async getPage(): Promise<PuppeteerPage> {
        // Handle the logic of page creation and limit the number of created pages.

        // ...
        const page = (await this.browser.pages())[0];
        // ...

        return page;
    }

    /**
     * Close a page.
     */
    public async closePage(page: PuppeteerPage): Promise<void> {
        // Handle the logic of page deletion and browser closing.

        // ...
        if(this.numberPages === 0) {
            await this.browser.close();
            BrowserService.instance = null;
        }
        // ...
    }

    /**
     * Initialise the instance.
     */
    public async initialise(): Promise<void> {
        this.browser = puppeteer.launch();
    }
}

并在您的代码中使用它:

And use it in your code:

// myPuppeteerTask.ts
const somedata = ""
const puppeteer = require('puppeteer');
(async () => {
    const browserService: BrowserService = await BrowserService.getInstance();
    const page = await browserService.getPage();
    await page.goto('https://somewebsite.com');

    ///Do some task

    browserService.closePage(page);
})();

BrowserService 是手动创建的单例,但您可以使用 NestJs 或 Awilix 等依赖注入来改进此架构.您可以获得更好的可维护性、可读性和可测试性.

The BrowserService is a singleton created by hand but you can improve this architecture using dependency injection using NestJs or Awilix for example. You get better maintanability, readalbility and testability.

它看起来像这样:

// myPuppeteerTask.ts
export class MyPuppeteerTask {

    // Inject the BrowserService into the task.
    public constructor(private browserService: BrowserService) { }

    public async execTask(): Promise<void> {
        const page = await this.browserService.getPage();
        await page.goto('https://somewebsite.com');

        ///Do some task

        this.browserService.closePage(page);
    }
}

这篇关于将 puppeteer 任务整合为一项任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆