Cloud Functions Puppeteer TimeoutError:尝试连接到Chrome时30000毫秒后超时

时间:2019-12-07 14:46:22

标签: javascript node.js google-cloud-functions puppeteer

我正在使用Puppeteer进行一些网络抓取,并使用Firebase Cloud Functions将其放置在预定的pubsub上。我收到上述错误消息,但无法解决。我已经审查了此post,并且了解到我需要等到伪造者完成之后。

执行pubsub函数时,代码需要转到网站的几页以提取所选项目。提取项目后,我将对它们执行其他任务,即比较并保存到firestore。

我当前的实现似乎已经做到了,所以我不知道该如何修改我的代码。这是我的实现:

//Entry function in functions/index.js
exports.scrapeWeb = functions.pubsub
.onRun((context) => {
    var scraper = new Scraper();
    return scraper.start();
})

//Scraper's start() function
Scraper.prototype.scrape = async function() {
    var scraped_items = []
    var promises = []

    //Loop over agencies
    for (const agency of agencies) {

        //Loop over required number of pages
        for (page_num = 0; page_num < num_of_pages; page_num++) {
            var promise = new Promise(async (resolve, reject) => {
                const url = setupUrl(agency, page_num);
                var data = {
                    ...
                }
                try {
                    const browser = await puppeteer.launch(constants.puppeteerOptions);
                    const page = await browser.newPage();
                    await page.setUserAgent(constants.userAgent);
                    await page.goto(url, {timeout: 0});            
                    await page.waitForSelector('div.container', {timeout: 0});
                    const body = await page.$eval('body', el => el.innerHTML);
                    data['html'] = body;
                    resolve(data);
                    await browser.close();                    
                } catch (err) {
                    reject(err);
                    console.log("Puppeteer error", err);
                }
            });

            promises.push(promise)
        }
    }

    const results = await Promise.all(promises)
    for (const result of results) {
        const scraped = scrapeHtml(result);
        console.log(`Scrapped ${scraped.length}`)
        scraped_items.push.apply(scraped_circulars, scraped);
    }

    //Do other stuffs with scraped_items
    return;
}

//Puppeteer options
puppeteerOptions: {
        headerless: true,
        args: [
            '--no-sandbox',
        ]
    }

任何人都可以提供建议吗?

1 个答案:

答案 0 :(得分:0)

您的函数需要返回一个诺言,当所有工作完成时,诺言就会解决。现在,它始终不返回任何内容:

return scraper.start();

start()的最后一行:

//Do other stuffs with scraped_items
return;

start()应该返回声明的承诺。

您使用的异步/等待代码实际上并没有阻止start()的执行。从广义上讲,您不是在正确处理async / await和诺言,并且将new Promise与async / await语法混在一起也不是一个好主意。

一般建议-如果要在函数中的任何位置使用异步/等待,则应在所有位置使用它。使顶级功能回调回调异步,并使所有其他方法异步,这样就可以更轻松地推断出代码在做什么。