gpt4 book ai didi

javascript - Node.js/Puppeteer - DOM NodeList 到 JS 对象

转载 作者:行者123 更新时间:2023-11-30 09:19:12 25 4
gpt4 key购买 nike

我想将一个 NodeList 转换成一个对象。

H1 ​​是 object.name 等等。

我仍然无法理解 page.evaluate() 的确切行为。

这是我需要的:

enter image description here

这是我的尝试之一,但 gp 始终未定义:

await page.waitForNavigation();

const selG = 'body > div.content-home > div > div.box > div > div:nth- child(2) > div.col-md-12.no-padding > div:nth-child(4) > div:nth-child(2) > div.col-xs-12';
await page.waitForSelector(selG);
const g = await page.evaluate( (selG) => {
let gp = document.querySelector(selG); //null
let n = Array.from(gp.querySelectorAll('h1'), element => element.textContent);
console.log(n[0]);
return n;
});

最佳答案

page.evaluate() 运行您直接传递给浏览器的函数,它没有 NodeJS 脚本的作用域(访问变量)启动了 Puppetter。

要完全理解,试试这个:

1 - 按原样复制你的函数

2 - 将其包装成一个自调用函数([your-function])(),结果如下(我又加了一个console.log(selG); 行)

((selG) => {
console.log(selG); // I added this line
let gp = document.querySelector(selG);
let n = Array.from(gp.querySelectorAll('h1'), element => element.textContent);
console.log(n[0]);
return n;
})()

3 - 直接粘贴到开发工具控制台

这样做你正在做更多更少(从理解的 Angular 来看)page.evaluate() 所做的,即运行你直接传递给它的函数进入浏览器。结果如何?它是 Cannot read property 'querySelectorAll' of null 因为,如您所述,gp 为 null。

但专注于 console.log(selG); 我添加...它记录 undefined...这是个大问题!

为什么会这样?

看看函数本身,selG 变量不存在,所以 let gp = document.querySelector(selG); 不能返回任何东西。 selG 被定义到您用来启动 Puppeteer 的脚本中,但是您传递给 page.evaluate() 的函数将在浏览器中运行,而不是在 Node 执行上下文中运行。

直接引用 Puppeteer 文档

page.evaluate(pageFunction, ...args)

pageFunction Function to be evaluated in the page context

...args <...Serializable|JSHandle> Arguments to pass to pageFunction

使用(如 Grant 所说)第二个剩余 argsselG 变量传递给您的函数。

按照您的原始代码稍作更改

await page.waitForNavigation();

const selG = 'body > div.content-home > div > div.box > div > div:nth- child(2) > div.col-md-12.no-padding > div:nth-child(4) > div:nth-child(2) > div.col-xs-12';
await page.waitForSelector(selG);
const g = await page.evaluate( (SELECTOR) => {
let gp = document.querySelector(SELECTOR);
let n = Array.from(gp.querySelectorAll('h1'), element => element.textContent);
console.log(n[0]);
return n;
}, selG);

请注意:

  • 我将 selG 变量(最后一行)传递给 pageFunction(您的函数)

  • pageFunction 接收一个变量并将其存储到 SELECTOR 变量中

  • pageFunction 消费接收到的 SELECTOR

总结:传递给 page.evaluate() 的函数不能使用在它外部声明的变量,因为它会在浏览器中运行,一个上下文分隔从您的 NodeJS 脚本(编写以启动 Puppeteer 本身)。

试试我的代码,它应该可以正常工作而无需任何更改。让我知道是否足够清楚。

奖金

请记住,如果您想使用一些与 DOM 相关的数据,您至少可以使用三种不同的方法来执行相同的操作。

下面是我的一个例子,我想读取我在页面中找到的第一个链接的 href 属性。第一个示例像您一样使用 page.evaluate(),后两个示例向您展示了使用其他一些 Puppeteer API 的不同方法。

const SELECTOR = '[href]:not([href=""])';
let link;

// compare the three following examples, they all do the same
link = await page.evaluate((sel) =>
document.querySelector(sel).getAttribute('href')
, SELECTOR);
link = await page.$eval(SELECTOR, el => el.getAttribute('href'));
link = await page.$(SELECTOR).getProperty('href').jsonValue();

关于javascript - Node.js/Puppeteer - DOM NodeList 到 JS 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52918634/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com