ElementHandle与DOM元素有何不同?

17
page.$(selector) 返回一个包含 ElementHandle 的 Promise。但ElementHandle的文档有点欠缺。它说它“表示DOM元素”,但这到底意味着什么?如果它确实代表了DOM,为什么不能检查ElementHandle的内容?另外,它还说:“除非处理已丢弃,否则会阻止DOM元素被垃圾回收。” 如果浏览器仍在页面上,为什么DOM元素会被垃圾回收呢?我之所以会问这个问题,是因为我认为从页面上的一个元素中获取文本很简单,所以我尝试了一下:
const text = await page.$('#text').textContent;

返回了undefined。所以我尝试了一下,

const text = await page.$('#text').textContent();

出现错误。

事实证明正确的方法是

const text = await page.evaluate(() => document.querySelector('#text').textContent);

1
谢谢您的问题,我还以为只有我遇到了这个问题! - Oly Dungey
1个回答

10

使用ElementHandle仍然可以像“Puppeteer方式”一样访问属性,例如textContent。 首先,您必须在ElementHandle上调用.getProperty(),然后将其转换为.jsonValue()。请记住,所有这些操作都返回承诺,因此您应该像这样await它们:

await (await (await page.$('#text')).getProperty('textContent')).jsonValue();

以下是完整的工作示例:
const puppeteer = require('puppeteer');

const html = `
<html>
  <body>
    <div id="text">Sample content</div>
  </body>
</html>`;

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(`data:text/html,${html}`);

  const text = await page.evaluate(() => document.querySelector('#text').textContent);
  const text2 = await (await (await page.$('#text')).getProperty('textContent')).jsonValue();

  console.log(text);
  console.log(text2);

  await browser.close();
})();

1
嗨。看着 const text = await page.evaluate(() => document.querySelector('#text').textContent); - 谁说 '#text' 在这个时候已经可用了?我知道它不是ajax注入的,但是我们不应该“waitFor*”吗?换句话说,goto是否等待load事件,然后才解决等待? - Royi Namir
是的,我们应该“等待”它。出于简单起见,在这个例子中我没有包含这部分内容。 - Everettss
1
重新阅读文档后,我认为我们可以跳过waitFor: https://i.imgur.com/hKRnkCI.jpg。它默认为“load”事件,这是最后一个事件。 - Royi Namir
5
元素句柄(ElementHandle)是Puppeteer库中的一个对象,它代表网页上与特定元素对应的DOM元素。 - Daniel Viglione

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接