【问题标题】:Puppeteer & Chromium using large CPU?Puppeteer 和 Chromium 使用大型 CPU?
【发布时间】:2022-01-30 15:40:34
【问题描述】:

我有一个 nodejs 脚本在我的 Macbook 24/7 上运行,每隔 20 分钟左右它就会运行 Puppeteer 来解析网站的内容。每隔两天,风扇就会变得非常响亮,我看到 Chromium 正在使用大量 CPU 和 RAM。有什么办法可以解决这个问题吗?

这是我正在运行的代码:

const options = {
                args: [
                    '--no-sandbox',
                    '--disable-setuid-sandbox',
                    '--disable-dev-shm-usage',
                    '--disable-accelerated-2d-canvas',
                    '--no-first-run',
                    '--no-zygote',
                    '--single-process', 
                    '--disable-gpu'
                ],
                headless: true
            }

const browser = await puppeteer.launch(options);

const page = await browser.newPage();

await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36')

await page.setViewport({ width: 1920, height: 1080 });


await page.setRequestInterception(true);
page.on('request', (req) => {
if(req.resourceType() === 'stylesheet' || req.resourceType() === 'font' || req.resourceType() === 'image'){
    req.abort();
 } else {
      req.continue();
  }
});

await page.goto(url, { waitUntil: 'networkidle0' });


// ... do stuff

await page.close();
await browser.close();

【问题讨论】:

  • (1) 这种“风扇声音很大”的现象只有在你的木偶表演日程发生时才会发生? (2) 如果您在同一台 Macbook 上使用 chrome 手动访问同一网站,是否会消耗相同的资源?老实说,我不知道“// ... do stuff”部分会发生什么,但我认为 puppeteer 在正常情况下不会吃掉这么多资源,这对你的机器来说并不是最好的,特别是如果你正在运行它 24 /7 只因为这个任务。 在您的情况下,是否可以选择从 Github Actions、Heroku 等运行此作业?

标签: javascript node.js puppeteer chromium


【解决方案1】:

我有一个想法,每 20 分钟自动杀死并启动 puppeteer。抓取/解析工作完成后,Puppeteer 浏览器 (chromium) 会自动关闭,然后在 20 分钟后重新启动新的浏览器,因此不会占用更多资源。 我正在为这种方法使用浏览器池(集群)。


import cluster from 'cluster'
import * as os from 'os'
import * as process from 'process'
import * as puppeteer from 'puppeteer'

const launchOptions = {
    args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-dev-shm-usage',
        '--disable-accelerated-2d-canvas',
        '--no-first-run',
        '--no-zygote',
        '--single-process',
        '--disable-gpu'
    ],
    headless: true
}

let lastProcessUptime = []
let userAgentString = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36'
let viewportSize = { width: 1920, height: 1080 }
let CPUsNum = os.cpus().length
CPUsNum = 1 // Set this number as how many browser page do you want to launch simultaneously

const runThis = async (processID) => {
    const browser = await puppeteer.launch(launchOptions)
    const page = await browser.newPage()
    await page.setUserAgent(userAgentString)
    await page.setViewport(viewportSize)
    await page.setRequestInterception(true)
    page.on('request', (request) => {
        let blockedResources = ['stylesheet', 'font', 'image']
        if (blockedResources.includes(request.resourceType())) {
            await request.abort()
        } else {
            await request.continue()
        }
    });
    await page.goto(url, { waitUntil: 'networkidle0' })
    // ... and do stuff
    // ... then close the page and browser and also kill the process
    await page.close()
    await browser.close()
    lastProcessUptime.push({
        pid: process.pid,
        uptime: Math.round(process.uptime() * 1000)
    })
    process.kill(processID)
    process.exit(0)
}

if (!cluster.isWorker) {
    console.log(`Primary ${process.pid} is running`)

    // Fork workers.
    for (let i = 0; i < CPUsNum; i++) {
        cluster.fork()
    }

    cluster.on('exit', (worker, code, signal) => {
        console.log(`worker ${worker.process.pid} died`) /*with code: ${code} and signal ${signal}*/
        setTimeout(() => cluster.fork(), (20 * 60 * 1000) - lastProcessUptime[lastProcessUptime.findIndex(process => process.pid === worker.process.pid)].uptime) //lets recreate the worker that died
    })
} else {
    let processID = process.pid
    console.log(`Worker ${processID} started`)
    ;(async (processID: number) => {
        await runThis(processID)
    })(processID)
}


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    • 1970-01-01
    相关资源
    最近更新 更多