Javascript Puppeter:内存泄漏错误和超时处理

Javascript Puppeter:内存泄漏错误和超时处理,javascript,node.js,puppeteer,Javascript,Node.js,Puppeteer,我正试图从中获取数据。下面是代码,它适用于单一地区和医院类型,但当我将其放入循环中时,它会中断。我尝试将语句放入getData函数中,使其异步等待,但它仍然会打开数百个浏览器实例,导致内存泄漏问题。我如何修复它,使它一次运行一个,而不是一次运行所有 const puppeteer = require('puppeteer'); const districtList = ["020", "001", "003", "008&qu

我正试图从中获取数据。下面是代码,它适用于单一地区和医院类型,但当我将其放入循环中时,它会中断。我尝试将语句放入
getData
函数中,使其异步等待,但它仍然会打开数百个浏览器实例,导致内存泄漏问题。我如何修复它,使它一次运行一个,而不是一次运行所有

const puppeteer = require('puppeteer');
const districtList = ["020", "001", "003", "008", "016", "017", "004", "006", "005", "007", "022", "021", "019", "009",
  "012", "013", "023", "010", "002", "011", "014", "015", "018"];
outputJsonArray = [];
const url = "https://excise.wb.gov.in/CHMS/Public/Page/CHMS_Public_Hospital_Bed_Availability.aspx";

async function scrape(did, hospType) {
  // const browser = await puppeteer.launch({headless: false, args: ['--auto-open-devtools-for-tabs']});
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();
  page.setDefaultNavigationTimeout(0);
  await page.goto(url, {waitUntil: 'networkidle0', timeout: 0});
  await page.waitForSelector('#ctl00_ContentPlaceHolder1_ddl_District');
  await page.click(hospType);
  await page.select('#ctl00_ContentPlaceHolder1_ddl_District', did);
  await page.waitForSelector('tbody tr');
  // extracting information from code
  let outputData = await page.evaluate(() => {
    let output = [];
    let dataRows = document.body.querySelectorAll("tbody tr");
    let cityName = document.querySelector("#ctl00_ContentPlaceHolder1_ddl_District").selectedOptions[0].textContent.trim();
    console.log(cityName)
    // return dataRows.length;
    console.log("Num entries == " + dataRows.length);
    dataRows.forEach((dataRow) => {
      let rowJson = {};
      // debugger;
      rowJson["Name"] = dataRow.querySelector('h5').textContent.trim().replace(/\s+/g, ' ');
      // let h3 = dataRow.querySelectorAll('li h3.text-success')[3].textContent;
      rowJson["Contact"] = dataRow.querySelector('.rounded-pill.bg-success').textContent.trim().replace(/\s+/g, ' ');      
      output.push(rowJson);
    })
    return output;
  });
  outputJsonArray = outputJsonArray.concat(outputData);
  console.log("data == ");
  console.log(outputData);
  await browser.close();
};

districtList.forEach(getData);
async function getData(districtId) {
  await scrape(districtId, "[for=ctl00_ContentPlaceHolder1_rdo_Govt_Flag_0]")
  await scrape(districtId, "[for=ctl00_ContentPlaceHolder1_rdo_Govt_Flag_1]")
  await scrape(districtId, "[for=ctl00_ContentPlaceHolder1_rdo_Govt_Flag_2]")
  console.log("+++++++++++++++++Full JSON below+++++++++++++++++");
  console.log(outputJsonArray);
}
此外,在第17行,
waitForSelector
超时并完全停止执行。这是因为在某些情况下没有可用的结果。例如,在district and Second hospital type中选择“ALIPURDUAR”不会返回任何结果,因此它会一直等待,并且应该超时。我如何处理这两个问题

(节点:50036)MaxListenerSexceed矮化:可能的事件发射器内存 检测到泄漏。向[process]添加了11个退出侦听器。使用 setMaxListeners()以增加限制(使用
节点--跟踪警告…
以显示警告的创建位置)(节点:50036)MaxListenerSexceedawranging:可能的事件发射器内存 检测到泄漏。[process]中添加了11个SIGINT侦听器。使用 setMaxListeners()以增加限制(节点:50036) MaxListenerSexceedawarning:可能的事件发射器内存泄漏 检测。[process]中添加了11个SIGTERM侦听器。使用 setMaxListeners()以增加限制(节点:50036) MaxListenerSexceedawarning:可能的事件发射器内存泄漏 检测。[process]中添加了11个SIGHUP侦听器。使用 setMaxListeners()以增加限制


您可能在浏览器上下文中遇到错误。尝试可选链接,看看这是否有帮助:

let data = await page.$$eval('tbody tr', trs => trs.map(tr => {
  return {
    name: tr.querySelector('h5')?.textContent?.trim()?.replace(/\s+/g, ' '),
    contact: tr.querySelector('.rounded-pill.bg-uccess')?.textContent?.trim().replace(/\s+/g, ' ')
  }
}))
编辑

因此,要一次运行一个,您可以执行以下操作:

async function run(districtList){
  for(let districtId of districtList){
    await getData(districtId)
  }
}

run(districtList)

问题出在forEach上,它看起来像一个for循环,但不是。

不确定这将如何解决与同时打开数百个浏览器实例相关的问题。您发布的代码中没有任何内容会导致此问题。您是否尝试运行我的代码?没有,但我猜浏览器上下文错误正在阻止它访问
browser.close()
。你应该看到,在斯特德尔思想中,我甚至还没有达到这一点。只要我运行脚本,它就会打开许多浏览器实例。每次跑步至少需要5分钟,所以你所说的应该在5分钟后发生,而不是立即发生