木偶:goto()和waitForSelector()在Cloud Functions上始终失败

时间:2019-12-09 11:47:46

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

我正在使用Puppeteer进行一些Webscraping,这些Webscraping是在预定的pubsub Cloud Function上执行的。我遇到的问题是,将功能部署到Firebase Cloud Function上时,page.goto()page.waitForSelector()从未完成。该脚本可以在我的计算机上本地正常运行。

到目前为止,这是我的实现方式

//Scheduled pubsub function at ./functions/index.js
exports.scraper = functions.pubsub
.onRun((context) => {
   var scraper = new ScraperManager();
   return scraper.start();
})

//Entry function
ScraperManager.prototype.start = async function() {

    var webpagePromises = []
    for (const agency of agencies) {
        for (page_num = 0; page_num < num_of_pages; page_num++) {
            const url = setupUrl(agency, page_num); //Returns a url
            const webpagePromise = getWebpage(agency, page_num, url)
            webpagePromises.push(webpagePromise)
        }
    }

    return Promise.all(webpagePromises)
}

async function getWebpage(agency, page_num, url) {
    var data = {}

    const browser = await puppeteer.launch(constants.puppeteerOptions);

    try {
        const page = await browser.newPage();
        await page.setUserAgent(constants.userAgent);

        await page.goto(url, {timeout: 0});   
        console.log("goto completes")      

        await page.waitForSelector('div.main_container', {timeout: 0});
        console.log("waitFor completes")

        const body = await page.$eval('body', el => el.innerHTML);
        data['html'] = body;
        return data;                
    } catch (err) {
        console.log("Puppeteer error", err);
        return;
    } finally {
        await browser.close(); 
    }
}

//PuppeteerOptions in constants file
puppeteerOptions: {
    headerless: true,
    args: [    
        '--disable-gpu',
        '--no-sandbox',
    ]
}

请注意,{timeout: 0}是必需的,因为page.gotopage.waitForSelector()花费的时间要比默认超时值30000ms多。即使禁用了超时,gotowaitForSelector()都不会完成,即console.log()语句都不会被记录。上面的脚本在本地运行脚本时可以正常工作,即console.log()确实可以正确打印出来,但是在部署到Cloud Functions上时永远无法工作。整个云功能始终会超时(目前设置为300秒),而不会打印任何日志。

有人可以提供建议吗?

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题:愚蠢的 page。$ eval()来获得一个简单的节点将永远不会返回(实际上花费了3分钟以上的时间...)或崩溃。在虚拟专用服务器上超过5分钟后显示页面,而同一脚本在我的本地计算机上运行正常。

查看虚拟服务器的RAM使用率(大约99%),我得出的结论是,这种脚本不能在只有2 GB或RAM的服务器上运行。

:-(