【问题标题】:Puppeteer: proper selection of inner textPuppeteer:正确选择内部文本
【发布时间】:2019-11-04 10:21:21
【问题描述】:

我想获取一个具有特定类名的字符串,比如说“CL1”。

这是过去常做的事情,它奏效了: (我们在一个 asycn 函数中)

var counter = await page.evaluate(() => {
            return document.querySelector('.CL1').innerText;
        });

现在,几个月后,当我尝试运行代码时,我得到了这个错误:

Error: Evaluation failed: TypeError: Cannot read property 'innerText' of null

我在之前的sn-p代码前后对一些console.log()做了一些调试,发现这是罪魁祸首。

我查看了网页的代码,里面有特定的类。

但是我发现了另外两个同名的类。

它们三个都嵌套在许多类的深处。

既然我知道我感兴趣的类层次结构,那么选择我想要的类的正确方法是什么?

编辑: 由于有三个具有相同名称的类名,并且我想从第一个中提取信息,我可以在 querySelector() 上使用数组表示法来访问第一个中的信息吗?

编辑2: 我运行这个:

return document.querySelector('.CL1').length;

我得到了

Error: Evaluation failed: TypeError: Cannot read property 'length' of null

这变得更加混乱......

编辑 3: 我尝试了 Md Abu Taher 的建议,我看到他提供的代码 sn-p 没有返回 undefined。这意味着选择器对我的代码可见。

然后我运行这段代码:

var counter = await page.evaluate(() => {
            return document.querySelector('#react-root > section > main > div > header > section > ul > li:nth-child(1) > a > span').innerText;
            });

我得到了同样的错误:

Error: Evaluation failed: TypeError: Cannot read property 'innerText' of null

【问题讨论】:

  • 能否提供您要访问的页面的网址?
  • 除了确保类名没有改变之外,在调用querySelector之前确认您正在等待页面加载。
  • @KrzysztofKrzeszewski 感谢您的努力,但这是一个内网 URL
  • @zaquest 是的,处理得很好。
  • 你在等待dom中的内容加载吗?

标签: javascript node.js web-scraping puppeteer


【解决方案1】:

答案分为几部分。获取正确的选择器,并获取数据。

1。正确选择器

使用检查元素

  • 右键单击所需元素并单击检查元素。
  • 然后右键单击并单击复制 > 复制选择器

这将为您提供该特定元素的唯一选择器。

使用选择器工具

有一堆 chrome 扩展可以帮助您找到正确的选择器。

2。获取数据

鉴于您的选择器是 .CL1,您需要做的事情很少。

等待所有网络事件完成

基本上在导航上你可以等到网络空闲。

await page.goto(url, {waitUntil: 'networkidle2'});

等待元素出现在 DOM 中。

即使网络空闲,也可能存在重定向等。最好的选择是等到元素出现。下面会一直等到找到元素,否则会抛出错误。

await page.waitFor('.CL1');

或者,检查元素是否存在,只有存在才返回数据

如果您不想抛出错误或元素随机出现,则需要检查它的存在并返回数据。

await page.evaluate(() => {
  const element = document.querySelector('.CL1');
  return element && element.innerText; // will return undefined if the element is not found
});

【讨论】:

  • 完整阅读我的答案并应用我在那里写的内容。 :) 您使用 domcontentloaded 而不是 networkidle2 或 networkidle0。
【解决方案2】:

尝试验证之前的元素

var x = document.getElementsByClassName("example");

var x = document.getElementsById("example");

然后

var counter = await page.evaluate(() => {
            return x.innerText;
        });

【讨论】:

  • 我这样做了: var counter = await page.evaluate(() => { var x = document.getElementsByClassName("CL1"); console.log(x); return x.innerText; } ); console.log(counter);
  • 我得到了这个 { undefined TypeError: Cannot read property 'replace' of undefined}
  • 尝试使用innerHTML而不是innerText // document.getElementById("demo").innerHTML
  • 这个链接可能对link有帮助
猜你喜欢
  • 2021-01-10
  • 2023-03-23
  • 2022-10-06
  • 2010-12-11
  • 2012-08-17
  • 1970-01-01
  • 2011-03-01
  • 1970-01-01
  • 2018-10-29
相关资源
最近更新 更多