Puppeteer Chromium 实例管理

Puppeteer Chromium instance management

所以我看到了 puppeteer-cluster 包,但它有非常手动的示例我的情况非常多变,所以我会尽力解释。

好的,所以我有一个应用程序,用户可以在其中安排 posts。一旦 posting 时间到了,木偶操纵者就会运行,转到站点,使用我应用程序数据库中的凭据登录用户,posts 内容相当简单。

现在,当说 20 个用户都决定今天下午 1 点 post 时,问题就出现了。现在 puppeteer 产生了 25 个 chromium 实例,这些实例由于 RAM 有限而扰乱了服务器。我基本上要问的是如何实现以下目标: 1).将 puppeteer 的并发限制为 10 个实例。再多的话,它基本上应该分批进行,比如先做 10 次,然后关闭它们,然后再开始 10 次,等等。 2).如果小于 10,则保持正常功能。

我知道这好像是我在给你做作业,但请相信我,我只需要一些指导、一点帮助或为我指明正确的方向就足够了。或者,如果你能告诉我如何使用它:puppeteer-cluster 动态地满足我的需要。非常感谢!

  1. 首先,你需要有一个先进的消息队列系统 捕获所有传入的并发请求,如 Kafka / RabbitMQ
  2. 以 10 个请求和 运行 一个 for 循环的形式获取消息 这些块和每个循环为每个块创建一个集群。
  3. 下面的代码解释了如何完成它,这段代码回答了你列出的所有问题。

代码片段:

const { Cluster } = require('puppeteer-cluster');
const runChunks = async (chunkArr, chunkSize) => {
    //Launching cluster for each chunk
    const cluster = await Cluster.launch({
        concurrency: Cluster.CONCURRENCY_CONTEXT,
        maxConcurrency: chunkSize, //Defined max chunksize
    });
    //Task to complete
    await cluster.task(async ({ page, data: url }) => {
        await page.goto(url);
        console.log('Reached: ', url);
        // Here goes the code for scraping task to complete ...
    });
    //Chunked array URLs queued for task completion
    chunkArr.forEach(data => {
        cluster.queue(data.url);
    });
    //Closing the cluster instance after it becomes idle
    await cluster.idle();
    await cluster.close();
};

function chunkArrGenerator(arr, chunkSize) {
    let chunksArr = [];
    let indexCounter = 0;
    while (indexCounter <= (arr.length - 1)) {
        chunksArr.push(arr.splice(0, chunkSize));
        indexCounter++;
    }
    return chunksArr;
}

// assume request array having 100 objects with url data
let arr = [{ url: "https://www.amazon.in/" }, { url: "https://www.flipkart.com/" }, { url: "https://www.crateandbarrel.com/" }, { url: "https://www.cb2.com/" } /* so on ... */];

let size = 2;  //chunk size
//Following line creates chunks of size 2, you change it to 10 as per your need
let chunks = chunkArrGenerator(arr, size);
//Executing each cluster on each chunk
chunks.forEach(async (chunk) => {
    await runChunks(chunk, size);
});