我正在使用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.goto
和page.waitForSelector()
花费的时间要比默认超时值30000ms多。即使禁用了超时,goto
和waitForSelector()
都不会完成,即console.log()
语句都不会被记录。上面的脚本在本地运行脚本时可以正常工作,即console.log()
确实可以正确打印出来,但是在部署到Cloud Functions上时永远无法工作。整个云功能始终会超时(目前设置为300秒),而不会打印任何日志。
有人可以提供建议吗?
答案 0 :(得分:0)
我遇到了同样的问题:愚蠢的 page。$ eval()来获得一个简单的节点将永远不会返回(实际上花费了3分钟以上的时间...)或崩溃。在虚拟专用服务器上超过5分钟后显示页面,而同一脚本在我的本地计算机上运行正常。
查看虚拟服务器的RAM使用率(大约99%),我得出的结论是,这种脚本不能在只有2 GB或RAM的服务器上运行。
:-(