【问题标题】:Puppeteer innerHTML page evaluate functions returning null and undefined errorsPuppeteer innerHTML 页面评估返回 null 和未定义错误的函数
【发布时间】:2020-05-16 08:16:29
【问题描述】:

await page.$eval('.class1' + variable + 'img.class2', el => el.ParentElement.innerHTML = '要替换的文本');

我也试过了

await page.evaluate((variable) '.class1' + variable + 'img.class2', el => el.ParentElement.innerHTML = '要替换的文本');

我知道包含此函数的所有 if 语句都是正确的,并且在检查器中,.class1VARIABLE img.class2 选择的 .ParentElement 返回适当的元素。

然而,当我运行第一个函数时,我在查找未定义的 ParentElement 时遇到错误,而当我运行第二个函数时,我在查找为 null 的 ParentElement 时遇到错误。是什么赋予了?我没有正确传递变量吗?我在评估错误的 DOM 吗? 'variable' 正在做正确的事情,在 for 语句中递增,并且我已经验证了它在将我带到这里的逻辑中的 console.log 调试语句是正确的。我什至尝试在函数内部对变量进行硬编码,例如

await page.evaluate(() '.class1VARIABLE img.class2', el => el.ParentElement.innerHTML = '要替换的文本');

我什至无法理解它是如何失败的,而且它也因 null 或 undefined 错误而崩溃。

我有点不知所措。

附:如果重要,则图像的 ParentElement 是 td。

【问题讨论】:

  • 您的示例中似乎有一些错误:await page.evaluate((variable) '.class1' + variable + ' img.class2', el => el.ParentElement.innerHTML = 'text to substitute');await page.evaluate(() '.class1VARIABLE img.class2', el => el.ParentElement.innerHTML = 'text to substitute'); 在语法上是错误的。
  • ...好的...你要指定如何?
  • 抱歉,我不能确定,这些片段应该会引发语法错误。至少应该尝试这样的事情:await page.evaluate((selector) => { document.querySelector(selector).ParentElement.innerHTML = 'text to substitute'; }, '.class1' + variable + ' img.class2');await page.evaluate((selector) => { document.querySelector(selector).ParentElement.innerHTML = 'text to substitute'; }, '.class1VARIABLE img.class2');
  • 它们不会抛出语法错误。我会试试你的建议。例如,选择器是“.class1VARIABLE img.class2”。
  • 也许您引用它们时有一些遗漏或不准确的版本?对我来说,他们会抛出 SyntaxError: missing ) after argument listSyntaxError: Unexpected token ')'

标签: node.js puppeteer


【解决方案1】:

如何使用 .class 选择器更改元素的 innerHTML 的示例:

'use strict';

const html = `
  <!doctype html>
  <html>
    <head><meta charset='UTF-8'><title>Test</title></head>
    <body><p class='test'>Text.</p></body>
  </html>`;

const puppeteer = require('puppeteer');

(async function main() {
  try {
    const browser = await puppeteer.launch({ headless: false });
    const [page] = await browser.pages();

    await page.goto(`data:text/html,${html}`);

    const pSelector = '.test';
    const newHTML = '<i>New text.</i>';

    await page.evaluate((selector, html) => {
      document.querySelector(selector).parentElement.innerHTML = html;
    }, pSelector, newHTML);
  } catch (err) {
    console.error(err);
  }
})();

【讨论】:

  • 我很困惑。函数中的“选择器”在做什么?不是声明了吗?某种占位符? pSelector 在做什么?
  • pSelector 是在 Node.js 范围(主脚本范围)中定义的变量。 page.evaluate() 的函数参数在文档(浏览器)范围内执行,无法访问主脚本范围(包括pSelector 变量)。要将主脚本范围的任何变量转移到文档(浏览器)范围,我们需要将它们作为第二个、第三个等参数添加到 page.evaluate() 函数中,它们将成为评估函数的参数(在此示例中 — @987654326 @ 范围)。所以querySelectorselector 具有相同的值,但从不同的范围访问。
  • 如果足够的话,您可以在评估函数中硬编码选择器值。但是如果我理解正确的话,你需要在循环中调用相同的函数,计数器递增,所以你需要使用这个作用域交互:在 Node.js 作用域中定义递增变量并将其传递给在文档作用域中评估的函数.
  • 运行该代码,再次得到“错误:评估失败:TypeError:无法设置属性 'innerHTML' of null”。也许这与 .ParentElement 部分有关。你会在哪里插入父母身份?传入 pSelector.ParentElement?定义 pSelector = '.test.ParentElement'?请记住,我必须按类获取一个 img,然后使用 .innerHTML 更改其父级 (a td)。
  • 除此之外,是否有任何理由尝试{ 整个主要功能? Puppeteer 基本上已经做到了这一点。我在我的代码中尝试了 page.evaluate 函数。
猜你喜欢
  • 1970-01-01
  • 2018-03-13
  • 2020-10-28
  • 2019-05-23
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 2022-12-05
  • 1970-01-01
相关资源
最近更新 更多