Reputation: 123
I have made a script in node for web scraping a page periodically as a job and save the data as a object in MongoDB. I need to execute the function every 5 - 15 seconds more or less. However, my code has a bad performance for the moment, could you give some advices or any help?
const $ = require('cheerio');
const MarketModel = require('./models/marketModel');
const mongoose = require('mongoose');
const puppeteer = require('puppeteer');
var schedule = require('node-schedule');
//Connection to DataBase:
//To connect to Development environment DB (Comment line below if not using it)
mongoose.connect('mongodb://localhost:27017/Tradheo', {
useNewUrlParser: true
});
//To connect to DB in cloud:
//mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true });
mongoose.connection.on('error', error => console.log(error));
mongoose.Promise = global.Promise;
getMarketData = function () {
console.log("Web scraping to get market data...")
let markets = []
let marketSpain = {
country: 'Spain',
name: 'IBEX 35',
companies: []
}
let marketGermany = {
country: 'Germany',
name: 'DAX',
companies: []
}
puppeteer
.launch()
.then(function (browser) {
return browser.newPage();
})
.then(function (page) {
return page.goto('url', {
timeout: 3000000
}).then(function () {
return page.content();
});
})
.then(function (html) {
$("table[class='genTbl closedTbl crossRatesTbl elpTbl elp30'] > tbody > tr", html).each((i, elem) => {
marketSpain.companies.push({
name: $("td[class='bold left noWrap elp plusIconTd'] > a", html).eq(i).html(),
last: $("td", elem).eq(2).text(),
high: $("td", elem).eq(3).text(),
low: $("td", elem).eq(4).text(),
change: $("td", elem).eq(5).text(),
changePerCent: $("td", elem).eq(6).text(),
volume: $("td", elem).eq(7).text(),
time: $("td", elem).eq(8).text(),
purchase: false,
sale: false
});
});
markets.push(marketSpain);
puppeteer
.launch()
.then(function (browser) {
return browser.newPage();
})
.then(function (page) {
return page.goto('url').then(function () {
return page.content();
});
})
.then(function (html) {
$("table[class='genTbl closedTbl crossRatesTbl elpTbl elp30'] > tbody > tr", html).each((i, elem) => {
marketGermany.companies.push({
name: $("td[class='bold left noWrap elp plusIconTd'] > a", html).eq(i).html(),
last: $("td", elem).eq(2).text(),
high: $("td", elem).eq(3).text(),
low: $("td", elem).eq(4).text(),
change: $("td", elem).eq(5).text(),
changePerCent: $("td", elem).eq(6).text(),
volume: $("td", elem).eq(7).text(),
time: $("td", elem).eq(8).text(),
purchase: false,
sale: false
});
});
markets.push(marketGermany)
MarketModel.create({
markets,
}, (err) => {
if (err) return handleError(err);
})
console.log("Done!")
})
.catch(function (err) {
console.log(err);
});
})
.catch(function (err) {
console.log(err);
});
}
var j = schedule.scheduleJob('*/15 * 8-17 * * 1-5', function () {
getMarketData();
});
The kind of outputs i'm getting are working for the first function calls but then it starts throwing TimeError exception and MaxListenersExceededWarning. For example:
Web scraping to get market data...
Done!
Web scraping to get market data...
Web scraping to get market data...
Web scraping to get market data...
{ TimeoutError: Navigation Timeout Exceeded: 30000ms exceeded
at Promise.then (/home/javier/Workspace/Tradheo/server/node_modules/puppeteer/lib/Lifecycl eWatcher.js:142:21)
at <anonymous>
-- ASYNC --
at Frame.<anonymous> (/home/javier/Workspace/Tradheo/server/node_modules/puppeteer/lib/helper.j s:111:15)
at Page.goto (/home/javier/Workspace/Tradheo/server/node_modules/puppeteer/lib/Page.js:629:49)
at Page.<anonymous> (/home/javier/Workspace/Tradheo/server/node_modules/puppeteer/lib/helper.j s:112:23)
at /home/javier/Workspace/Tradheo/server/scraping.js:69:33
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:189:7) name: 'TimeoutError' }
Web scraping to get market data...
Upvotes: 0
Views: 318
Reputation: 701
I think the issue is that you are not closing the puppeteer browser. Try adding browser.close() at the end of your promise chain and within the catch
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://news.ycombinator.com', {waitUntil: 'networkidle2'});
await page.pdf({path: 'hn.pdf', format: 'A4'});
await browser.close();
})();
https://www.npmjs.com/package/puppeteer
Upvotes: 1