Ray
Ray

Reputation: 123

Web scraping periodically job performance

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

Answers (1)

ElioRubens
ElioRubens

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

Related Questions