继续处理结果的 Null 值(Nodejs、Puppeteer)

2024-04-11

我刚刚开始使用 Puppeteer (Headless Chrome) 和 Nodejs。我正在抓取一些测试站点,当所有值都存在时,一切都很好,但如果该值丢失,我会收到如下错误:

Cannot read property 'src' of null(所以在下面的代码中,前两遍可能有所有值,但第三遍没有图片,所以它只是出错)。

在我使用之前if(!picture) continue;但我认为由于 for 循环,它现在不起作用。

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

for (let i = 1; i <= 3; i++) {
//...Getting to correct page and scraping it three times
  const result = await page.evaluate(() => {
      let title = document.querySelector('h1').innerText;
      let article = document.querySelector('.c-entry-content').innerText;
      let picture = document.querySelector('.c-picture img').src;

      if (!document.querySelector('.c-picture img').src) {
        let picture = 'No Link';     }  //throws error

      let source = "The Verge";
      let categories = "Tech";

      if (!picture)
                continue;  //throws error

      return {
        title,
        article,
        picture,
        source,
        categories
      }
    });
}

let picture = document.querySelector('.c-picture img').src;

if (!document.querySelector('.c-picture img').src) {
    let picture = 'No Link';     }  //throws error

如果没有图片的话document.querySelector()返回 null,它没有src财产。在尝试读取之前,您需要检查查询是否找到了元素src财产。

将空值检查移至函数顶部还有一个额外的好处,即当您打算退出时可以节省不必要的计算。

async function scrape3() {
  // ... 
  for (let i = 1; i <= 3; i++) {
  //...Getting to correct page and scraping it three times
    const result = await page.evaluate(() => {
        const pictureElement = document.querySelector('.c-picture img');
      
        if (!pictureElement) return null;
      
        const picture = pictureElement.src;
        const title = document.querySelector('h1').innerText;
        const article = document.querySelector('.c-entry-content').innerText;

        const source = "The Verge";
        const categories = "Tech";

        return {
          title,
          article,
          picture,
          source,
          categories
        }
    });

    if (!result) continue;

    // ... do stuff with result
  }

回答评论问题:“有没有办法跳过任何空白内容,然后返回其余内容?”

是的。您只需要在尝试读取其中的属性之前检查可能丢失的每个元素是否存在。在这种情况下,我们可以省略提前返回,因为您始终对所有结果感兴趣。

async function scrape3() {
  // ...
  for (let i = 1; i <= 3; i++) {
    const result = await page.evaluate(() => {
        const img = document.querySelector('.c-picture img');
        const h1 = document.querySelector('h1');
        const content = document.querySelector('.c-entry-content');

        const picture = img ? img.src : '';
        const title = h1 ? h1.innerText : '';
        const article = content ? content.innerText : '';
        const source = "The Verge";
        const categories = "Tech";

        return {
          title,
          article,
          picture,
          source,
          categories
        }
    });
    // ... 
  }
}

进一步的想法

由于我仍在讨论这个问题,让我更进一步,并使用您可能感兴趣的一些更高级别的技术对其进行重构。不确定这是否正是您所追求的,但它应该会给您一些帮助关于编写更易于维护的代码的想法。

// Generic reusable helper to return an object property
// if object exists and has property, else a default value
// 
// This is a curried function accepting one argument at a
// time and capturing each parameter in a closure.
//
const maybeGetProp = default => key => object =>
  (object && object.hasOwnProperty(key)) ? object.key : default

// Pass in empty string as the default value
//
const getPropOrEmptyString = maybeGetProp('')

// Apply the second parameter, the property name, making 2
// slightly different functions which have a default value
// and a property name pre-loaded. Both functions only need
// an object passed in to return either the property if it
// exists or an empty string.
//
const maybeText = getPropOrEmptyString('innerText')
const maybeSrc = getPropOrEmptyString('src')

async function scrape3() {
  // ...

  // The _ parameter name is acknowledging that we expect a
  // an argument passed in but saying we plan to ignore it.
  //
  const evaluate = _ => page.evaluate(() => {
    
    // Attempt to retrieve the desired elements
    // 
    const img = document.querySelector('.c-picture img');
    const h1 = document.querySelector('h1')
    const content = document.querySelector('.c-entry-content')

    // Return the results, with empty string in
    // place of any missing properties.
    // 
    return {
      title: maybeText(h1),
      article: maybeText(article),
      picture: maybeSrc(img),
      source: 'The Verge',
      categories: 'Tech'
    }
  }))

  // Start with an empty array of length 3
  // 
  const evaluations = Array(3).fill()

    // Then map over that array ignoring the undefined
    // input and return a promise for a page evaluation
    //
    .map(evaluate)

  // All 3 scrapes are occuring concurrently. We'll
  // wait for all of them to finish.
  //
  const results = await Promise.all(evaluations)

  // Now we have an array of results, so we can 
  // continue using array methods to iterate over them
  // or otherwise manipulate or transform them
  // 
  return results
    .filter(result => result.title && result.picture)
    .forEach(result => {
      //
      // Do something with each result
      // 
    })
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

继续处理结果的 Null 值(Nodejs、Puppeteer) 的相关文章

随机推荐

  • 将 Null 值分配给数据表中的整数列

    我有一个数据表 其中一个列名称为 CustomerID 数据类型为整数 我想动态地将行添加到数据表中 为此 我创建了一个 DataRow 对象 例如 DataTable dt new DataTable DataRow DR dt NewR
  • Terraform 配置程序无法 winrm 到 Azure 上新建的 Windows VM

    我正在尝试使用 Terraform 在 Azure 上配置 Windows VM 并同时引导它 我能想到的方法是terraform provisioner 出于测试目的 我这样编写了配置程序 provisioner remote exec
  • Android 中带有房间数据库的多线程

    最近我开始在我的 Android 应用程序中使用房间数据库 尝试从多个线程访问数据库时遇到一些问题 我在所有线程中使用相同的数据库实例 据我所知 如果所有线程都有相同的数据库实例 那么 数据库访问是序列化的 我读过一个blog https
  • keras.utils.to_categorical() - 名称 keras 未定义

    我正在运行测试脚本喀拉斯网站 https keras io getting started sequential model guide 用于多层感知器 MLP 用于多类 softmax 分类 在 jupyter 笔记本中运行时 出现错误
  • 扩展的 VSCode 错误日志在哪里?

    当我收到扩展错误时 我无法知道为什么会发生错误 您可能正在寻找 cmd shift p gt 搜索Show Logs gt Extension Host
  • 如何使 HSQL 驱动程序正常工作?

    我目前正在学习 Java 中的一些数据库技巧 我发现我正在读的这本好书 在某些时候 它鼓励我尝试与以下类进行手动数据库连接 import java sql DriverManager import java sql Connection i
  • Serialized接口的DTO实现

    Java DTO 模型对象是否必须实现序列化 如果是这样为什么 如果不是 对性能等有何影响 DTO 通常是数据传输对象 它不必使用 Java 序列化 但如果不使用 则需要遵循一些其他约定 这不是性能问题 就像您使用 Java 序列化一样 它
  • ruby 中的 ||= 是什么? [复制]

    这个问题在这里已经有答案了 可能的重复 在 Ruby 中是什么意思 https stackoverflow com questions 995593 what does mean in ruby ruby 中的 是什么 这是一个条件分配 如
  • 用原始图像替换蒙版 opencv Python

    我正在尝试用原始图像像素替换使用蒙版找到的对象 我有一个遮罩 在未检测到物体的情况下显示黑色 如果检测到物体则显示白色 然后我在 where 语句中使用该图像 image np where image2 255 255 255 any ax
  • Hibernate:CRUD 通用 DAO

    我的网络应用程序有很多服务表 实体 例如payment methods tax codes province codes etc 每次添加一个新实体时 我都必须编写一个 DAO 问题是 基本上 它们都是相同的 但唯一的区别是实体类本身 我知
  • Android 平台源代码中的断点

    使用 Intelllj idea 我尝试调试 Android 源 API 17 但是当我在平台源中设置断点时 它们在运行时会被忽略 在调试时查看断点 其中有一个十字 并显示一条消息 在类 android view 的第 15 508 行找不
  • Spring - applicationContext.xml 无法打开,因为它不存在

    我有一个 Spring MVC 应用程序 并且与文件 applicationContext xml 结合使用 JUnit 测试时遇到问题 在我的 JUnit 测试类中我写道 final ApplicationContext context
  • 使用 XML 包将 html 表抓取到 R 数据帧中

    如何使用 XML 包抓取 html 表 以维基百科页面为例巴西足球队 http en wikipedia org wiki Brazil national football team 我想在 R 中阅读它并获取 巴西与 FIFA 认可球队对
  • 在 GIT 中处理 Rails db/schema.rb 文件的正确方法是什么?

    我们应该包括schema rb同时致力于 GIT 或者我们应该忽略它 什么是正确的做法 好标准schema rbRails 2 文件在文件顶部的注释块末尾有这样的内容 It s strongly recommended to check t
  • 警告:本机不支持快速启动/快照

    我在使用 android studio 运行我的应用程序时遇到错误 但在此之前它工作正常 直到更新 Android API27 我尝试卸载它但没有任何结果 收到的警告是 模拟器 警告 本机不支持快速启动 快照 A 目前需要CPU UG功能
  • 是否可以使用 TagLibSharp 从 MP3 文件中删除 Lyrics3v2 标签?

    我想知道是否可以删除歌词3v2使用 MP3 文件中的标签类型标签库夏普 https github com mono taglib sharp图书馆 This http id3 org Lyrics3v2文档说块条目以单词 开头歌词开始 并以
  • Android ViewPager:从 URL 下载图像

    我正在尝试使用创建一个图片库ViewPager 我找到了几个例子并且我已经让它们全部工作了 示例没有展示的一件事是如何使用从 URL 下载的图像填充 ViewPager 所有教程都有图像Drawables文件夹或 SD 卡上 有谁知道 Vi
  • 使用 SF 库读取 GeoJSON 文件?

    我一天前刚开始使用 R 我正在尝试使用 SF 库读取 geojson 文件 但我不确定正确的方法是什么 library dplyr library sf geo lt system file my path zones geojson pa
  • 由于函数 asprintf 无法编译程序

    找到此代码 需要停止将戴尔笔记本电脑中的 CPU 节流至 20 这是由于电源适配器无法被计算机识别而发生的 尝试在 Kubuntu 上编译并得到以下结果 warning implicit declaration of function as
  • 继续处理结果的 Null 值(Nodejs、Puppeteer)

    我刚刚开始使用 Puppeteer Headless Chrome 和 Nodejs 我正在抓取一些测试站点 当所有值都存在时 一切都很好 但如果该值丢失 我会收到如下错误 Cannot read property src of null