Как мне вызвать функцию вне асинхронной функции в puppeteer с помощью NodeJS

#javascript #node.js #puppeteer

#javascript #node.js #puppeteer

Вопрос:

как мне вызвать функцию, передающую объект страницы вне асинхронного метода в puppeteer.

Я хочу реализовать функциональность, при которой, если на странице найдено определенное значение, она должна воспроизводить музыку. Я определил функциональность playmusic() вне асинхронного метода.

 const puppeteer = require('puppeteer');

const playmusic = ()=>{
   page.goto('http://www.noiseaddicts.com/free-samples-mp3/?id=2544');
   page.click('span.map_play');
}

(async () => {
  const browser = await puppeteer.launch({headless : false});
  
  const page = await browser.newPage();

 
  await page.goto('DesiredURL');
  const pricing = await page.evaluate(()=>{
    let pricesOnPage=document.querySelectorAll(".span_price_wrap");
    const priceList=[...pricesOnPage];
    return priceList.map(h=>h.innerText);
    
  });
  console.log(pricing[1]);

  if(pricing[1]>=2316)
  {
    await page.evaluate(() => {
      playmusic ();
    });
  }

 await browser.close();
})();
  

Я получаю ошибку ниже

 index.js
2346.75
(node:17316) UnhandledPromiseRejectionWarning: Error: Evaluation failed: ReferenceError: playmusic is not defined
    at __puppeteer_evaluation_script__:2:6
    at ExecutionContext._evaluateInternal (jswebscrappingnode_modulespuppeteerlibcjspuppeteercommonExecutionContext.js:217:19)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async ExecutionContext.evaluate (jswebscrappingnode_modulespuppeteerlibcjspuppeteercommonExecutionContext.js:106:16)
    at async index.js:24:4
(node:17316) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:17316) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
  

——————————ОБНОВИТЬ———————————————

Делюсь работоспособным кодом: Спасибо всем за помощь, я улучшил свой код в нескольких местах, таких как

  1. добавлено время ожидания до и после воспроизведения музыки.
  2. Преобразованное возвращаемое значение в float (ранее оно обрабатывалось как строка)
 const puppeteer = require('puppeteer');

 const playmusic = async (page)=>{
  await page.goto('http://www.noiseaddicts.com/free-samples-mp3/?id=2544');
  await page.waitFor(4000) ;
  await page.click('span.map_play');
  await page.waitFor(12000);
}

(async () => {
  const browser = await puppeteer.launch({headless : false});
  
  const page = await browser.newPage();

 
  await page.goto('MYURL');
  const pricing = await page.evaluate(()=>{
    let pricesOnPage=document.querySelectorAll(".span_price_wrap");
    const priceList=[...pricesOnPage];
    return priceList.map(h=>h.innerText);
    

  });
  console.log(pricing[1]);
  let PricingFloat= parseFloat(pricing[1]);

  if(PricingFloat<=21)
  {
    await playmusic (page);   
  }
  else
  {
    console.log("No Music for you");
  }

 await browser.close();
})();
  

Комментарии:

1. да, именно так вы вызываете функцию — у вас проблема с кодом? О, теперь я понимаю … если вы хотите передать страницу, вы бы playmusic(page) и определили playmusic следующим образом const playmusic = page =>

2. да, я получаю ошибку при выполнении. Позвольте мне поделиться ошибкой . node . позвольте мне отредактировать мой вопрос с ошибкой

3. неважно, я вижу, что вы сделали не так, и предложил исправление

Ответ №1:

Вам нужно заменить

 const playmusic = ()=>{
   page.goto('http://www.noiseaddicts.com/free-samples-mp3/?id=2544');
   page.click('span.map_play');
}
  

Автор:

 const playmusic = (page) => {
   page.goto('http://www.noiseaddicts.com/free-samples-mp3/?id=2544');
   page.click('span.map_play');
}
  

и

     await page.evaluate(() => {
      playmusic ();
    });
  

Автор:

     await page.evaluate(() => {
      playmusic (page);
    });
  

Из-за того, что диапазон, когда page существует, ограничен, и когда вы определяете функцию, playmusic тогда эта функция не имеет доступа к переменной page . Вы можете прочитать больше о variables scopes в JS.

Ссылка на отличную статью:

https://www.sitepoint.com/demystifying-javascript-variable-scope-hoisting/


Обновить

После анализа вашего кода ошибки, я думаю, вам нужно добавить блок try-catch. Например.

 try {
    await page.evaluate(() => {
      playmusic (page);
    });
} catch(e) {
   console.log(e);
   process.exit(1)
}
  

Вы также должны проверить, нет ли у puppeteer невыполненных обещаний:

https://pptr.dev/#?product=Puppeteeramp;version=v5.3.0amp;show=api-class-page

Например, вы можете написать:

 const playmusic = async (page) => {
   await page.goto('http://www.noiseaddicts.com/free-samples-mp3/?id=2544');
   return page.click('span.map_play');
}
  

и в вашем основном коде:

 try {
    await page.evaluate(async () => {
      try {
         await playmusic();
      } catch(e) {
          console.log(e);
          process.exit(1);
      }
    });
} catch(e) {
   console.log(e);
   process.exit(1)
}
  

Комментарии:

1. Я внес изменения в код в соответствии с вашим предложением, однако он не воспроизводит музыку, даже если условие выполнено. pastebin.com/CZVb0jZr Посмотрите. спасибо за вашу помощь.