Firebase 云功能 - 网络爬行长网站列表 - 超时

问题描述 投票:0回答:1

我试图实现的目标:

我正在使用 Firebase Cloud Functions 来抓取一些网站。一般来说,一切工作正常,但对于某些网站,我需要抓取一个大约有 300 个页面的列表,每个页面有大约 20 个子页面(与互联网上的一半相同)。

我需要爬行它们,但同时,很明显我无法在 Fibrease Cloud 函数中一次运行 300*20 页面,因为它会超时。

我有:

为了解决超时问题,我在 firestore DB 中创建了新集合,并将其称为“爬行进度”,其中我有一个如下所示的文档:

{
  currentPage: 1,
  maxPage: 300
}

然后我有两个云函数 #1 通过将 currentPage 设置为 1 来初始化爬行

export const prepareCrawling = onSchedule(CRON_EVERY_MONTH, async () => {
  await admin.firestore().collection('scrape-progress').doc('XYZ').update({ currentPage: 1 });
});

#2 onDocumentUpdate 初始化当前页面的抓取,完成后增加一页

export const doCrawl = onDocumentUpdated('crawl-progress/XYZ', async (event: FirestoreEvent<any>) => {
  const newValue = event.data.after.data();
  if (newValue.currentPage < newValue.maxPage) {
    const data = await crawlPage(newValue.currentPage);
    return event.data.after.ref.set({ currentPage: FieldValue.increment(1) }, { merge: true });
  } else {
    console.log('Crawling finished. Current page is equals or greater than Max page');
  }
});

我的问题是什么:

#1 老实说,我什至不确定这是最好的方法,我相信一定有比这更干净的方法。我只是无法弄清楚

#2 我的方法有其局限性。我不知道为什么,因为它在我的模拟器上没有发生在我身上,但是这个函数运行的时间越长,每次执行时间就越长。当进度达到 30-40% 左右时,它最终会完全停止工作。 开始时每次执行大约需要 50 秒,当当前页面值在 100 左右时,爬取需要近 4-5 分钟。

以下是一些日志: 内存使用情况:

实例:

执行时间:

PS:您在图表中看到的下降与它在某一点冻结且未更新当前页面这一事实有关,因为它停止运行大约 15 分钟,直到我注意到并手动将当前页面增加一,再次触发 onDocumentUpdate。

firebase google-cloud-firestore google-cloud-functions web-crawler puppeteer
1个回答
0
投票

您可以使用这些方法中的任何一种

存储进程状态: 我过去遇到过类似的问题。为了解决这个问题,我最初采用了一种战略方法,将流程的状态存储在数据库中,例如 Firestore。然而,在我的具体情况下,我选择使用 Apps 脚本执行的 API 将进程状态存储在 Google Sheet 中。这样,如果发生超时错误,我可以自动重新调用该函数,并且它会从中断的地方恢复。

迁移到 Google Cloud Functions(第二代): 一段时间后,推出了 Google Cloud Functions(第二代)。出于维护和利用增强功能的目的,我将功能迁移到第二代。正如预期的那样,此转换消除了超时错误,为我的用例提供了更强大、更可靠的解决方案。

您可以在此处查看 Google Cloud Functions(第 2 代)版本比较

© www.soinside.com 2019 - 2024. All rights reserved.