使用puppeteer时,为什么getElementsByClassName()返回未定义?

时间:2019-08-20 16:27:19

标签: javascript html node.js typescript puppeteer

现在,我正在尝试使用puppeteer获取一些元素,以获取一些类item(divs)。我知道getElementsByClassName返回一个列表,您必须解析该列表。但是对我来说,即使我在浏览器(最新版的chrome)中尝试该功能,该功能也会说未定义。

这里有代码(打字稿btw):

private async getElementsFromBrowser(url : string) : Promise<any[]>{
  const page : Page = await goToPage(url)
  const result = await page.evaluate( arr => {
    //this is where the error comes in
    let setOfElements = document.getElementsByClassName('classnamethatexists');

    arr = setOfElements;
    return arr;
  }
  return Promise.resolve(result);
}

和html:

<div class='classnamethatexists'>"This is an example of the text I want to get"</div>
<div class='classnamethatexists'>"This is an example of the text I want to get"</div>
<div class='classnamethatexists'>"This is an example of the text I want to get"</div>
<div class='classnamethatexists'>"This is an example of the text I want to get"</div>

该函数是否有一种方法不返回未定义的内容;

1 个答案:

答案 0 :(得分:1)

您的代码有很多问题。

page.evaluate无法返回HTMLCollection

page.evaluate只能返回可序列化的数据,即可以通过JSON.stringify从浏览器上下文发送到Node.js上下文的数据。 document.getElementsByClassName返回无法序列化的HTMLCollection。

使用page.$page.$$返回元素句柄

要查询具有特定类的元素,最好将page.$$函数与class selector结合使用。这将返回element handle,可用于在Node.js执行上下文中进一步执行。

异步返回值

由于您已经将该函数声明为async,所以任何结果都将隐式成为Promise的结果。因此,返回值时无需使用Promise.resolve


结果代码

将它们放在一起,结果代码如下:

private async getElementsFromBrowser(url : string) : Promise<any[]>{
  const page = await goToPage(url); // I imagine this calls page.goto and returns the page
  const elements = await page.$$('.classnamethatexists');
  return elements;
}