【问题标题】:Puppeteer opening chrome instance for each file at oncePuppeteer 一次为每个文件打开 chrome 实例
【发布时间】:2018-11-06 12:27:20
【问题描述】:

我正在尝试自动化一个工作流程,其中我有一个目录中的文件列表并将它们放在一个数组中。然后对于数组中的每个文件,我调用一个 Chrome 自动化函数。

const path = require('path');
const chalk = require('chalk');
const puppeteer = require('puppeteer');

module.exports = {
    generateOutput : async(fileName, url = "https://example.com/") => {
        const filePath = path.join(process.cwd(), fileName);
        const outputFilePath = path.join(process.cwd(), "OutputFiles");
        try{
            const browser = await puppeteer.launch({headless: false});
            process.setMaxListeners(0);
            const page = await browser.newPage();
            await page._client.send('Page.setDownloadBehavior', {behavior: 'allow', downloadPath: outputFilePath});
            page.on('dialog', async dialog => {
                console.log(chalk.magenta("Error Occured: " + dialog.message()));
                await dialog.dismiss();
                await browser.close();
            });
            await page.goto(url, {waitUntil: 'networkidle2'});
            await page.click('#ui-id-9');
            await page.click('#ui-id-18');
            await page
                    .waitForSelector('#ui-id-9')
                    .then(() => console.log(chalk.magenta("Uploader module visible... Uploading the files") ));
            const input = await page.$('#upload-file');
            await input.uploadFile(filePath);
            await page.waitFor(10000);
            await page.click("#up-file");
            await page.waitFor(50000);
            await page
                    .waitForSelector('#ui-id-18')
                    .then(() => console.log(chalk.magenta("Downloader module visible... Downloading the files") ));
            await page.click("#download-td");
            await page.waitFor(100000);
            await browser.close();
        }
        catch(e){
            console.log(chalk.red(fileName + ' has failed in conversion.'));
        }
    }
};

这会同时创建一个 chrome 实例(比如 100 个文件对应 100 个)。有没有办法限制异步进程。 我没有多少经验。在 Node 中,所以我无法搜索正确的术语。

【问题讨论】:

    标签: javascript node.js windows async-await puppeteer


    【解决方案1】:

    一种解决方案是逐个访问每个文件的 url。

    const path = require('path');
    const chalk = require('chalk');
    const puppeteer = require('puppeteer');
    
    module.exports = {
    
        start: async() => {
            const browser = await puppeteer.launch({headless: false});
    
            const page = await browser.newPage();
    
            // for all the files in array call it one by one
            for (i = 0; i < files.length; i++) {
                await module.exports.generateOutput(page, fileName);
            }
    
            await browser.close();
        },
    
        generateOutput : async(page, fileName, url = "https://example.xm/b") => {
            const filePath = path.join(process.cwd(), fileName);
            const outputFilePath = path.join(process.cwd(), "OutputFiles");
            try{
                process.setMaxListeners(0);
                await page._client.send('Page.setDownloadBehavior', {behavior: 'allow', downloadPath: outputFilePath});
                page.on('dialog', async dialog => {
                    console.log(chalk.magenta("Error Occured: " + dialog.message()));
                    await dialog.dismiss();
                    await browser.close();
                });
                await page.goto(coloradoUrl, {waitUntil: 'networkidle2'});
                await page.click('#ui-id-9');
                await page.click('#ui-id-18');
                await page
                        .waitForSelector('#ui-id-9')
                        .then(() => console.log(chalk.magenta("Uploader module visible... Uploading the files") ));
                const input = await page.$('#upload-file');
                await input.uploadFile(filePath);
                await page.waitFor(10000);
                await page.click("#up-file");
                await page.waitFor(50000);
                await page
                        .waitForSelector('#ui-id-18')
                        .then(() => console.log(chalk.magenta("Downloader module visible... Downloading the files") ));
                await page.click("#download-td");
                await page.waitFor(100000);
            }
            catch(e){
                console.log(chalk.red(fileName + ' has failed in conversion.'));
            }
        }
    };
    

    其他是为每个文件打开新标签,一旦完成就关闭它。但这可以一次打开 100 个标签。您可以添加一个上限,例如一次最多打开 10 个选项卡等。以下代码使用delay 函数主动等待数字选项卡小于 10,然后再打开一个新选项卡

    const path = require('path');
    const chalk = require('chalk');
    const puppeteer = require('puppeteer');
    
    module.exports = {
    
        delay: async (milisecs) => {
            return new Promise(function(resolve, reject) {
                setTimeout(resolve, milisecs);
            })
        },
    
        start: async() => {
            const browser = await puppeteer.launch({headless: false});
    
            // for all the files in array call it one by one
            for (i = 0; i < files.length; i++) {
                pages = await browser.pages();
    
                /*
                * if number of tabs is less than 10, skips while. Else
                * waits till number of open tabs become less than 10
                */
                while (pages.length == 10) {
                    pages = await browser.pages();
                    await module.exports.delay(3000);
                }
    
                // then open a new tab
                const page = await browser.newPage();
                module.exports.generateOutput(page, fileName);
            }
    
            await browser.close();
        },
    
        generateOutput : async(page, fileName, url = "https://example.xm/b") => {
            const filePath = path.join(process.cwd(), fileName);
            const outputFilePath = path.join(process.cwd(), "OutputFiles");
            try{
                process.setMaxListeners(0);
                await page._client.send('Page.setDownloadBehavior', {behavior: 'allow', downloadPath: outputFilePath});
                page.on('dialog', async dialog => {
                    console.log(chalk.magenta("Error Occured: " + dialog.message()));
                    await dialog.dismiss();
                    await browser.close();
                });
                await page.goto(url, {waitUntil: 'networkidle2'});
                await page.click('#ui-id-9');
                await page.click('#ui-id-18');
                await page
                        .waitForSelector('#ui-id-9')
                        .then(() => console.log(chalk.magenta("Uploader module visible... Uploading the files") ));
                const input = await page.$('#upload-file');
                await input.uploadFile(filePath);
                await page.waitFor(10000);
                await page.click("#up-file");
                await page.waitFor(50000);
                await page
                        .waitForSelector('#ui-id-18')
                        .then(() => console.log(chalk.magenta("Downloader module visible... Downloading the files") ));
                await page.click("#download-td");
                await page.waitFor(100000);
    
                await page.close()
            }
            catch(e){
                console.log(chalk.red(fileName + ' has failed in conversion.'));
            }
        }
    };
    

    我已经修改了您的代码以传达这个概念。当然,除非您将 files 替换为您自己的变量等,否则它不会运行

    【讨论】:

    • 谢谢。请问我怎样才能实现第二件事,“为应该打开多少个标签添加上限”?
    • 当然,我已经更新了代码以设置最大标签的上限
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多