使用 puppeteer 和 MutationObserver 检测 DOM 更改

2024-01-11

我想检测某些加载页面上的 DOM 更改(例如,本地新闻页面上添加的新文章)并在检测后执行某些操作(发送电子邮件)。 在此示例中,我尝试检测子节点是否已从父节点(目标 div 节点)添加或删除,并在检测后在控制台中输出某些内容。

我需要实现暴露功能吗?如果是的话,我该怎么做?

我正在使用 puppeteer 和 MutationObserver 但它不起作用。

这是我的代码:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();
  await page.goto('https://www.example.com/');

  await page.evaluate(() => {
    const target = document.querySelector("body > div.container.upscore-pos-1 > section > div:nth-child(3) > div:nth-child(2) > div.row.hidden-xs > div > section");
    const observer = new MutationObserver( mutations => {
      for (const mutation of mutations) {
          if (mutation.type === 'childList') {
              console.log('Mutation Detected: A child node has been added or removed.');
            }
      }
    });
    observer.observe(target, { childList: true });
  });

})();

提前致谢!


Maybe page.exposeFunction()是最简单的方法:

'use strict';

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto('https://www.example.com/');

  await page.exposeFunction('puppeteerLogMutation', () => {
    console.log('Mutation Detected: A child node has been added or removed.');
  });

  await page.evaluate(() => {
    const target = document.querySelector('body');
    const observer = new MutationObserver( mutations => {
      for (const mutation of mutations) {
        if (mutation.type === 'childList') {
          puppeteerLogMutation();
        }
      }
    });
    observer.observe(target, { childList: true });
  });

  await page.evaluate(() => {
    document.querySelector('body').appendChild(document.createElement('br'));
  });

})();

But page.waitForSelector()(或其他一些waitFor...方法)在某些情况下也足够了:

'use strict';

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto('https://www.example.com/');

  await page.evaluate(() => {
    setTimeout(() => {
      document.querySelector('body')
        .appendChild(document.createElement('br')).className = 'puppeteer-test';
    }, 5000);
  });

  await page.waitForSelector('body br.puppeteer-test');

  console.log('Mutation Detected: A child node has been added or removed.');
})();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 puppeteer 和 MutationObserver 检测 DOM 更改 的相关文章

随机推荐

  • 对于简单到中等复杂度的新项目,我应该选择 MvvmLight 还是 MvvmCross? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我试图找到 MVVMlight 和 MVVMCrossthose 框架之间的主要区别 我计划为 Android 和 Windows Phone
  • 如何将树的结果传递或通过管道传输到Powershell?

    如何通过文件数组找到tree 有人居住吗 posh gt posh gt tree Get Item Directory home nicholas powershell Mode LastWriteTime Length Name d 2
  • css 文件中字体的相对文件路径

    我有一个在标题中引用的样式表 除了以下特定代码之外 所有 css 都可以在其中运行 font face font family icomoon src url fonts icomoon eot hsw0h3 src url fonts i
  • NSDateFormatter 具有自定义格式的相对日期格式

    所以我的目的是列出如下所示的日期 Today August 28 Tomorrow August 29 Friday August 30 etc 问题是我似乎只能如此接近 When I setDoesRelativeDateFormatti
  • Google_Service_OAuth2 是 PHP 中的“未定义类型”

    我正在尝试使用 Google Sign in 登录 但它显示 Google Service OAuth2 为未定义类型 我找到了这个堆栈帖子 Google Service Oauth2 未定义 https stackoverflow com
  • Spark 中的分区和分桶有什么区别?

    我尝试优化两个 Spark 数据帧之间的联接查询 我们称它们为 df1 df2 在公共列 SaleId 上联接 df1非常小 5M 所以我在spark集群的节点之间广播它 df2 非常大 200M 行 所以我尝试通过 SaleId 对其进行
  • BERT 中 NER 的正确格式化数据应该是什么样子?

    我正在使用 Huggingface 的transformers库并希望使用 BERT 执行 NER 我试图找到一个明确的示例 说明如何使用 BERT 正确格式化 NER 的数据 从我发现的论文和评论中 我并不完全清楚 假设我们有以下句子和标
  • 修改C++函数中指针指向的位置

    我一直在修改指针的指针上陷入困境 问题是我不明白为什么我的代码有效 我想做的是修改函数中指针指向的位置 然后在我的主函数中访问该值 我尝试了很多次 这是我让它发挥作用的唯一方法 include
  • Hadoop Nodemanager 和 Resourcemanager 未启动

    我正在尝试在 Ubuntu 13 10 64 位上设置最新的 Hadoop 2 2 单节点集群 操作系统是全新安装的 我尝试过使用 java 6 64 位和 java 7 64 位 按照以下步骤操作后this http raseshmori
  • PHP - Strtotime - 添加时间

    我有这个变量 timestamp strftime Y m d h M S a time 我只是想增加三个小时并重复它 我已经看到了可以执行 60 60 3 方法或硬编码 3 小时 的方法 它可以理解这些单词 获得这个结果的最佳方法是什么
  • 在 ASP.NET Web API 控制器的 nunit 测试中实例化新的 System.Web.Http.OData.Query.ODataQueryOptions

    我有一个 ASP NET MVC4 Web API 项目 其中包含 ApiController 继承控制器 该控制器接受 ODataQueryOptions 参数作为其输入之一 我正在使用 NUnit 和 Moq 来测试该项目 这使我能够从
  • midi 文件解析,无法识别的事件类型

    我在尝试解析 MIDI 文件时遇到问题 我正在尝试解析 frets on fire 游戏使用的注释文件 它只使用 midi 文件 所以我认为这无关紧要 如果你们中的任何人熟悉它 我遇到的问题是一般的 midi 问题 我有一个文件 其中有一个
  • 我需要一个不会弄乱我打开的窗口的消息泵

    我的应用程序 我正在开发的安装程序的引导应用程序 需要启动一些其他应用程序 我的安装程序和满足安装程序先决条件的第三方安装程序 并等待它们完成 为了允许 GUI 进行屏幕更新在等待应用程序完成时 我使用有关空闲循环处理的 Visual St
  • Node.js 在 for 循环中调用回调函数

    我试图在 a 中调用一个函数for循环 问题是该函数在循环完成后被调用 以下面为例 它打印到控制台 here1 here1 here2 here2 代替 here1 here2 here1 here2 report forEach item
  • LINQ Lambda 连接错误 - 无法从使用情况推断

    我在加入两个 DbSet 时遇到问题 并继续收到 无法推断错误 我努力寻找解决方案 所以我想我会分享我的简单答案 乔恩 斯基特 Jon Skeet 和其他人发表了几篇很棒的帖子 但大多数答案都超出了我的理解范围 这是给我带来麻烦的代码 us
  • Rails 在新控制器中结合 RESTful 方法

    我有一个 Rails 应用程序 其中users create projects 目前 这些是嵌套的 并作为单独的操作完成 Auser寄存器 然后从project仪表板创建一个新的project 为了提高转化率 以及跟踪来自 adwords
  • PySpark - 将单个整数列表与列表列进行比较

    我正在尝试检查 Spark 数据帧 带有列表的列 中的哪些条目包含给定列表中最大数量的值 我想出的最好的方法是迭代数据框rdd foreach 并使用 python 比较给定列表与每个条目set1 intersection set2 我的问
  • ??空合并运算符 --> 合并是什么意思?

    我很想撒谎说英语是我的第二语言 但事实是我只是不知道 合并 是什么意思 我知道什么 在 C 中是 does 但这个名字对我来说没有意义 我查了一下这个词 我知道它是 加入 的同义词 空连接运算符 仍然没有意义 有人可以启发我吗 我很想撒谎说
  • 如何使用UIAppearance外观WhenContainedIn:

    我注意到在 iOS5 中我们可以通过以下方式自定义 UIKit 控件UIAppearance我开始使用它 我想用appearanceWhenContainedIn 定制UINavigationBar s tintColor在不同的班级 例如
  • 使用 puppeteer 和 MutationObserver 检测 DOM 更改

    我想检测某些加载页面上的 DOM 更改 例如 本地新闻页面上添加的新文章 并在检测后执行某些操作 发送电子邮件 在此示例中 我尝试检测子节点是否已从父节点 目标 div 节点 添加或删除 并在检测后在控制台中输出某些内容 我需要实现暴露功能