等待功能完成,然后呈现页面

时间:2019-03-21 00:22:43

标签: node.js express puppeteer

我有一个函数,它会刮取一个元素并返回元素值。这是 reale-scraper.js 的代码:

module.exports.RealeScraper = function() {

return new Promise((res, rej) => {

var url = 'example.com';
var compagnia;

//Start Puppeteer and scrape element
ptr.launch().then(async browser => {
    const page = await browser.newPage();
    await page.setViewport({ width: 1280, height: 800 });

    await page.goto(url, {waitUntil: "networkidle0"});

    await page.type('input[name="username"]', config.utente);
    await page.type('input[name="password"]', config.pass);

    await Promise.all([
        page.click('input[type="SUBMIT"]'),
        page.waitForNavigation({waitUntil: 'networkidle2'})
    ]);

    await page.waitForSelector('#tableSceltaProfilo > tbody > tr:nth-child(1) > td:nth-child(2)');

    const element = await page.$("#tableSceltaProfilo > tbody > tr:nth-child(1) > td:nth-child(2)");
    compagnia = await page.evaluate(element => element.textContent, element);

    await page.screenshot({path: 'screenshot.png'});

    await browser.close();
});

res(compagnia);
});
} 

然后我调用该函数并尝试将数据发送到 home.js 中的ejs模板:

var scraper = require('../scrapers/reale-scraper');
router.get('/home', function(req, res, next) {

 RealeScraper().then((compagnia) => {
     res.render('nuovo-sinistro', {
        titolo: 'Manager Perizie',
        compagnia: compagnia
     });
 }).catch((error) => {
     console.log(error);
 });
 });

我想等到“ RealeScraper”完成并向我返回一个值,以便可以将其传递给res.render。我已经尝试过使用Promise,但是它不起作用。它不会给我任何错误,但是当我加载页面时,该函数不会启动,因此将在没有变量的情况下呈现。

我也尝试了不同的方法,但最终导致页面永久加载。

任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:0)

您同时呼叫//Start Puppeteer and scrape elementres(compagnia);,而compagnia为空时,它已返回。

res完成后只需调用scrape element

...
await browser.close();
res(compagnia);
...

我认为如果只使用async\await会更好:

module.exports.RealeScraper = async function () {
  var url = 'example.com';
  var compagnia;

  //Start Puppeteer and scrape element
  let browser = await ptr.launch();
  const page = await browser.newPage();
  await page.setViewport({ width: 1280, height: 800 });

  await page.goto(url, { waitUntil: "networkidle0" });

  await page.type('input[name="username"]', config.utente);
  await page.type('input[name="password"]', config.pass);

  await page.click('input[type="SUBMIT"]'); // why you do that in parallel?
  await page.waitForNavigation({ waitUntil: 'networkidle2' });

  await page.waitForSelector('#tableSceltaProfilo > tbody > tr:nth-child(1) > td:nth-child(2)');

  const element = await page.$("#tableSceltaProfilo > tbody > tr:nth-child(1) > td:nth-child(2)");
  compagnia = await page.evaluate(element => element.textContent, element);

  await page.screenshot({ path: 'screenshot.png' });

  await browser.close();

  return compagnia;
}



// ...
var scraper = require('../scrapers/reale-scraper');
router.get('/home', async function (req, res, next) {

  try {
    let compagnia = await RealeScraper();
    res.render('nuovo-sinistro', {
      titolo: 'Manager Perizie',
      compagnia: compagnia
    });
  } catch (error) {
    console.log(error);
  }
});