【问题标题】:Puppeteer Promise Rejection (Query Selector If Class)Puppeteer Promise Rejection (Query Selector If Class)
【发布时间】:2023-03-15 08:48:01
【问题描述】:

即使我使用 if/else 语句进行检查,我也会收到承诺拒绝。当我遍历 div (const items) 时,"description-main" 类在所有项目上。但是,"description-optional" 类并不总是存在。如何跳过它或将null 分配给它以继续循环而不给出任何错误?

// Imports: Dependencies
const puppeteer = require('puppeteer');

// Puppeteer: Generate CSV
(async () => {
    try {
       // Start Browser And Create New Page
       const browser = await puppeteer.launch({ headless: false });
       const page = await browser.newPage();

       // Go To Page
       await page.goto('http://website.com', { waitUntil: 'networkidle2' });

       const items = await page.$$('.item');

       for (let i = 0; i <= items.length; i ++) {
          const itemDescription = await items[i].$eval('.description-main', div => div.innerText.trim());
          const itemDescription2 = null | await items[i].$eval('description-optional', div => div.innerText.trim());

          console.log('Item: ' + itemDescription + itemDescription2);
       }
   }
   catch (error) {
   console.log(error);
   }
 })()

【问题讨论】:

    标签: javascript node.js asynchronous promise puppeteer


    【解决方案1】:

    您可以使用ternary operator 首先验证await items[i].$('.description-optional') 是否真实(即该元素存在于页面上)。

    如果条件为真(即不是null),那么您可以执行并将await items[i].$eval('.description-optional', div =&gt; div.innerText.trim()) 分配给itemDescription2

    否则,将null 分配给itemDescription2

    const itemDescription2 = await items[i].$('.description-optional') ? await items[i].$eval('.description-optional', div => div.innerText.trim()) : null;
    

    这是一个完整的例子:

    const items = await page.$$('.item');
    
    for (let i = 0; i < items.length; i++) {
      const itemDescription = await items[i].$eval('.description-main', div => div.innerText.trim());
      const itemDescription2 = await items[i].$('.description-optional') ? await items[i].$eval('.description-optional', div => div.innerText.trim()) : null;
    
      console.log('Item: ' + itemDescription + itemDescription2);
    }
    

    【讨论】:

    • 而不是三元运算符可能是短路评估,因为.$() 返回一个空值,类似于const itemDescription2 = await items[i].$('.description-optional') &amp;&amp; await items[i].$eval('.description-optional', div =&gt; div.innerText.trim())
    【解决方案2】:

    这里的问题是$eval 做了很多相互依赖的事情。

    $eval 首先选择元素,然后尝试对结果求值。

    您可以通过几种方式解决您的问题,但最简单的可能是在执行任何其他操作之前检查选择器是否与元素匹配:

    let itemDescription2; if (await items[i].$('.description-optional')) itemDescription2 = await items[i].$eval('description-optional', div => div.innerText.trim());

    或者,您可以在浏览器中获取 innerText 并返回它而不会导致错误。

    阿苏注意:

    i &lt;= items.length; 应该是i &lt; items.length;

    description-optional 必须是.description-optional,因为它是一个类选择器。

    【讨论】:

      猜你喜欢
      • 2018-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-09
      • 2018-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多