I am trying to scrape the data from this site. Below is the code, which is working for single district and hospital type but break when I put it in the loop. I tried putting the statements inside getData function to be async await but it still opens hundreds of browser instances leading to memory leak problems. How do I fix it so that it runs one at a time instead of all at once.
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);
}
Further, at line 17, waitForSelector timeouts and halts the execution completely. This is because there are some cases for which no results are available. For example, selecting "ALIPURDUAR" in district and 2nd hospital type does not return any results, therefore it keeps waiting and is supposed to timeout. How do I handle these two issues?
(node:50036) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 exit listeners added to [process]. Use emitter.setMaxListeners() to increase limit (Use
node --trace-warnings ...to show where the warning was created) (node:50036) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGINT listeners added to [process]. Use emitter.setMaxListeners() to increase limit (node:50036) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGTERM listeners added to [process]. Use emitter.setMaxListeners() to increase limit (node:50036) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGHUP listeners added to [process]. Use emitter.setMaxListeners() to increase limit