我正在開發一個使用 puppeteer 從另一個網站抓取資料的網站。當我在本地電腦上運行 npm 伺服器時,它可以很好地抓取數據,但是當我將其部署到 Heroku 時,它只運行我要查找的前三個文件,然後停止。
我本質上是想從我的學校網站上抓取有關課程的數據,因此我在 for 循環中運行此行,
let data =等待crawler.scrapeData(classesTaken[i].code)
這會在下面運行這個函數。為了我自己的隱私,我已經替換了實際的網站 URL。
const browser = await puppeteer.launch({ args: [ '--no-sandbox', '--disable-setuid-sandbox' ] }) const page = await browser.newPage() await page.goto("website url") await page.type('#crit-keyword', code) await page.click('#search-button') await page.waitForSelector(".result__headline") await page.click(".result__headline") await page.waitForSelector("div.text:nth-child(2)") let data = await page.evaluate(() => { let classTitle = document.querySelector("div.text:nth-child(2)").textContent .toLowerCase().split(' ') .map((s) => s.charAt(0).toUpperCase() + s.substring(1)).join(' ').replace('Ii', "II") let classDesc = document.querySelector(".section--description > div:nth-child(2)").textContent.replace('Lec/lab/rec.', '').trim() return { title: classTitle, desc: classDesc } }) console.log(`== Finished grabbing ${code}`) return data
這在我自己的本地伺服器上運行得很好。然而,當我推送到我的 Heroku 網站時,它只運行前三個類別程式碼。我有一種感覺,這可能是由於我的測功機記憶體不足,但我不知道如何讓它等待可用記憶體。
這是部署日誌
2023-05-22T17:29:18.421015+00:00 app[web.1]: == Finished grabbing CS 475 2023-05-22T17:29:19.098698+00:00 app[web.1]: == Finished grabbing CS 331 2023-05-22T17:29:19.783377+00:00 app[web.1]: == Finished grabbing CS 370 2023-05-22T17:29:49.992190+00:00 app[web.1]: /app/node_modules/puppeteer/lib/cjs/puppeteer/common/util.js:317 2023-05-22T17:29:49.992208+00:00 app[web.1]: const timeoutError = new Errors_js_1.TimeoutError(`waiting for ${taskName} failed: timeout ${timeout}ms exceeded`); 2023-05-22T17:29:49.992209+00:00 app[web.1]: ^ 2023-05-22T17:29:49.992209+00:00 app[web.1]: 2023-05-22T17:29:49.992210+00:00 app[web.1]: TimeoutError: waiting for target failed: timeout 30000ms exceeded 2023-05-22T17:29:49.992211+00:00 app[web.1]: at waitWithTimeout (/app/node_modules/puppeteer/lib/cjs/puppeteer/common/util.js:317:26) 2023-05-22T17:29:49.992230+00:00 app[web.1]: at Browser.waitForTarget (/app/node_modules/puppeteer/lib/cjs/puppeteer/common/Browser.js:405:56) 2023-05-22T17:29:49.992230+00:00 app[web.1]: at ChromeLauncher.launch (/app/node_modules/puppeteer/lib/cjs/puppeteer/node/ChromeLauncher.js:100:31) 2023-05-22T17:29:49.992230+00:00 app[web.1]: at process.processTicksAndRejections (node:internal/process/task_queues:95:5) 2023-05-22T17:29:49.992231+00:00 app[web.1]: at async Object.scrapeData (/app/crawler.js:9:21) 2023-05-22T17:29:49.992231+00:00 app[web.1]: at async getClassData (file:///app/server.mjs:40:16) 2023-05-22T17:29:49.992234+00:00 app[web.1]:
我在某處讀到嘗試使用這些命令清除建置快取
$ heroku plugins:install heroku-builds $ heroku builds:cache:purge --app your-app-name
我已經嘗試過了,但沒有任何作用。我還遵循了 puppeteer GitHub 上 Heroku 的故障排除說明。
我之所以相信這可能與我的動態記憶有關,是因為這篇相關的文章。如果是這種情況,我想弄清楚如何等到有可用記憶體可供使用。
編輯:我現在也在無頭模式下執行瀏覽器,這會導致完全相同的錯誤。
進一步記錄後,我發現問題是我打開瀏覽器然後從不關閉它而導致記憶體洩漏。透過在
scrapeData()
函數的 return 語句之前新增行await browser.close()
,記憶體洩漏停止並且伺服器能夠正確解析所有類別程式碼。