我正在开发一个使用 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()
,内存泄漏停止并且服务器能够正确解析所有类代码。