Saya sedang membangunkan tapak web yang menggunakan dalang untuk mengikis data daripada tapak web lain. Apabila saya menjalankan pelayan npm pada mesin tempatan saya ia mengikis data dengan baik, tetapi apabila saya menggunakan ia ke Heroku ia hanya menjalankan tiga fail pertama yang saya cari dan kemudian berhenti.
Saya pada asasnya ingin mengikis data tentang kursus dari tapak web sekolah saya, jadi saya menjalankan baris ini di dalam gelung for,
let data =等待crawler.scrapeData(classesTaken[i].code)
Ini akan menjalankan fungsi di bawah. Saya telah menggantikan URL tapak web sebenar untuk privasi saya sendiri.
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
Ini berfungsi dengan baik pada pelayan tempatan saya sendiri. Walau bagaimanapun, apabila saya menolak ke tapak Heroku saya, ia hanya menjalankan tiga kelas pertama kod. Saya rasa ini mungkin disebabkan dyno saya kehabisan ingatan, tetapi saya tidak tahu bagaimana untuk membuatnya menunggu memori yang tersedia.
Ini ialah log penggunaan
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]:
Saya membaca di suatu tempat untuk cuba mengosongkan cache binaan menggunakan arahan ini
$ heroku plugins:install heroku-builds $ heroku builds:cache:purge --app your-app-name
Saya sudah mencubanya tetapi tiada hasil. Saya juga mengikuti arahan penyelesaian masalah untuk Heroku pada GitHub dalang.
Sebab saya percaya ini mungkin berkaitan dengan ingatan dinamik saya adalah kerana artikel berkaitan ini. Jika ini berlaku, saya ingin memikirkan bagaimana untuk menunggu sehingga terdapat memori kosong untuk digunakan.
EDIT: Saya juga kini menjalankan penyemak imbas dalam mod tanpa kepala, yang mengakibatkan ralat yang sama.
Selepas log lebih lanjut, saya mendapati bahawa masalahnya ialah saya membuka penyemak imbas dan kemudian tidak pernah menutupnya, menyebabkan kebocoran memori. Oleh
scrapeData()
函数的 return 语句之前添加行await browser.close()
, kebocoran memori berhenti dan pelayan dapat menghuraikan semua kod kelas dengan betul.