首页 > 解决方案 > 无法使用 Puppeteer 访问 innerText 属性 - .$$eval 和 .$$ 没有产生结果 - JavaScript

问题描述

我正在开发一个网络爬虫,它在谷歌搜索某些东西,然后从结果页面中提取文本,我在让 Puppeteer 返回我需要的文本时遇到问题。我要返回的是一个字符串数组。

假设我在一个 div 中有几个嵌套的 div,每个 div 都有这样的文本:

 <div class='mainDiv'>
   <div>Mary Doe </div>
   <div> James Dean </div>
 </div>

在 DOM 中,我可以执行以下操作来获得所需的结果:

document.querySelectorAll('.mainDiv')[0].innerText.split('\n')

这产生:["Mary Doe", "James Dean"].

我知道 Puppeteer 不返回 NodeLists,而是使用 JSHandles,但我仍然不知道如何使用规定的方法获取任何信息。有关我在 Puppeteer 中尝试过的内容和相应的控制台输出,请参见下文:

在每种情况下,我都会await page.waitFor('selector')开始。

场景 1(使用.$$eval()):

const genreElements = await page.$$eval('div.mainDiv', el => el);
console.log(genreElements) // [] 

场景 2(使用evaluate):

function extractItems() {
   const extractedElements = document.querySelectorAll('div.mainDiv')[0].innerText.split('\n')
   return extractedElements
}
      
let items = await page.evaluate(extractItems)
console.log(items) // UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: Cannot read property 'innerText' of undefined

场景 3(使用evaluateHandle):

const selectorHandle = await page.evaluateHandle(() => document.querySelectorAll('div.mainDiv'))
const resultHandle = await page.evaluate(x => x[0], selectorHandle)
console.log(resultHandle) // undefined

非常感谢任何关于我如何实施或如何实现我想要做的事情的帮助或指导。谢谢!

标签: javascripthtmldomweb-crawlerpuppeteer

解决方案


使用 page.$$eval() 或 page.evaluate():

您可以使用page.$$eval()或在页面上下文page.evaluate()中运行并将每个元素的结果数组:Array.from(document.querySelectorAll())map()innerText

const names_1 = await page.$$eval('.mainDiv > div', divs => divs.map(div => div.innerText));
const names_2 = await page.evaluate(() => Array.from(document.querySelectorAll('.mainDiv > div'), div => div.innerText));

注意:请记住,如果您使用 Puppeteer 在 Google 上自动搜索,您可能会被暂时阻止并最终收到“来自您的计算机网络的异常流量”通知,要求您解决reCAPTCHA问题。这可能会破坏您的网络抓取工具,因此请谨慎操作。


推荐阅读