javascript - ElementHandle.$eval pageFunction 未执行

标签 javascript puppeteer

我正在使用 Puppeteer 版本 1.6.0 解析 html 表

// inside the rowMarket variable I store all the rows of a table
rowMarket = await.page.$$('#searchTextResults > tbody > tr');

现在我想迭代所有这些,并获取每行的一些 td 列的文本。

如果我使用以下代码,一切正常。

for(i=0<rowMarket.length;i++){
  nameComponent = await rowMarket[i].$('td:nth-child(1) > a');
  iT = await nameComponent .getProperty('innerText');
  json = await iT.jsonValue();

  otherComponent = await rowMarket[i].$(' ... ');
  // ... I repeat the same stuff for every column.
}

为了重用一些代码而不是大量复制和粘贴,我定义了下一个函数

async function getContent(element){
  innerText = await element.getProperty('innerText');
  json = await innerText.jsonValue();
  return json;  
}

所以我可以用这种方式重构以前的代码

for(i=0<rowMarket.length;i++){
  nameComponent = await rowMarket[i].$('td:nth-child(1) > a');
  nameText = getContent(nameComponent);

  otherComponent = await rowMarket[i].$(' ... ');
  otherText = getContent(otherComponent);

  // ...
}

但是深入研究文档我发现了 $eval function对于我想要手工做的事情来说,这似乎是一个很棒的组合。

我用下一种方式重构我的代码。我认为它非常干净和紧凑。

for(i=0<rowMarket.length;i++){
  nameText = await rowMarket[i].$eval('td:nth-child(1) > a', getContent);
  otherText = await rowMarket[i].$eval(' ...', getContent);
  // ...
}

但是我遇到了下一个错误

(node:8056) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: elemento.getProperty is not a function
    at dentroElemento (__puppeteer_evaluation_script__:2:30)
    at ExecutionContext.evaluateHandle (c:\webscraping\node_modules\puppeteer\lib\ExecutionContext.js:97:13)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

我真的不明白这个错误,因为如果在“独立”模式下调用,该函数可以正常工作。

我也尝试过这个

for(i=0<rowMarket.length;i++){
  nameText = await rowMarket[i].$eval('td:nth-child(1) > a', e => console.log('hello?'));
}

但是 hello 字符串永远不会登录到控制台。所以我认为问题是 pageFunction 函数没有被调用。或者我的代码可能做错了什么。

最佳答案

此:await rowMarket[i].$('td:nth-child(1) > a'); 返回一个elementHandle。 elementHandle 具有函数 .getProperty()。 所以,这就是为什么你的第一个代码可以工作:

async function getContent(elementHandle){
  innerText = await elementHandle.getProperty('innerText');
  ...

但是 .$evalElement 作为第一个参数传递给函数。这与 elementHandle 不同。

如果您想这样做:nameText = wait rowMarket[i].$eval('td:nth-child(1) > a', getContent); 然后,您应该重写 getContent 函数以处理这样的元素(因为 Element 没有 .getProperty() 函数):

async function getContent(element){
  innerText = await element.innerText;

关于javascript - ElementHandle.$eval pageFunction 未执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51343211/

相关文章:

google-chrome - 通过 DevTools 协议(protocol)从 Chromium 通信 "out"

node.js - 如何在 linux 上正确使用带有 puppeteer 的沙箱并停止变得不安全?

javascript - Puppeteer 不等待超时

javascript - JS确认后执行post方法

javascript - 如何使用两个按钮导航菜单?

Javascript - 正则表达式 - 如何删除指定长度的单词

javascript - 获取重复表的列值?

html - 如何遍历超市网站并获取产品名称和价格?

javascript - Puppeteer 元素选择返回 null 或超时

javascript - 重新加载后如何保存事件按钮?