javascript - 如何使用 nodeJS 在 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 (\jswebscrapping\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:217:19)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async ExecutionContext.evaluate (\jswebscrapping\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.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形式的返回值(之前被当成string)
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();
})();

最佳答案

你需要更换

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。您可以阅读有关 JS 中的变量作用域的更多信息。

链接到一篇很棒的文章:

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


更新

在分析了您的错误代码后,我认为您需要添加一个 try-catch block 。例如。

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

你还应该检查 puppeteer 是否没有未拒绝的 promise :

https://pptr.dev/#?product=Puppeteer&version=v5.3.0&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)
}

关于javascript - 如何使用 nodeJS 在 puppeteer 中调用异步函数之外的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63913846/

相关文章:

javascript - 有选择地激活特定页面的通用 jQuery/javascript 模块的最简单方法?

javascript - 如何在 puppeteer 中使用 querySelector 获取特定元素 <dl>

javascript - 如何在 Puppeteer 上跟踪弹出模式

javascript - 我可以在 TypeScript 中将函数限制为纯函数吗?

Javascript:API 调用期间出现 'Self signed certificate' 错误

javascript - 在 JavaScript 中取消转义 HTML 实体?

javascript - Puppeteer 无法在 VPS (DigitalOcean) 上工作

javascript - 问 Promise 解析/拒绝逻辑 - 为什么 Promise 不返回为被拒绝?

javascript - 如何在此node.js应用程序的警报中获取err.message?

Node.js - 试图避免全局变量...我如何跟踪用户对象?