我正在使用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',
]
}
任何人都可以提供建议吗?
答案 0 :(得分:0)
您的函数需要返回一个诺言,当所有工作完成时,诺言就会解决。现在,它始终不返回任何内容:
return scraper.start();
start()
的最后一行:
//Do other stuffs with scraped_items
return;
start()
应该返回声明的承诺。
您使用的异步/等待代码实际上并没有阻止start()的执行。从广义上讲,您不是在正确处理async / await和诺言,并且将new Promise
与async / await语法混在一起也不是一个好主意。
一般建议-如果要在函数中的任何位置使用异步/等待,则应在所有位置使用它。使顶级功能回调回调异步,并使所有其他方法异步,这样就可以更轻松地推断出代码在做什么。