用 Puppeteer 获取元素的内部文字
Puppeteer 可以查找特定的元素,进一步可以获取元素内部的文字。那么有没有办法获得多个同类型元素的内部文字?答案是有的。本文讨论下具体方法。
基本方法
获取控件内部文字,比较方便的是用 $eval()
配合 DOM 节点的 innerText
属性获得。
单个元素
单个元素,可以用 page.$eval()
获取元素文字,例如下面代码可以获得页面第一个 h1
元素的文字
puppeteer.launch(browserOptions).then(async browser=>{ page = await browser.newPage() await page.setViewport(viewport) await page.goto(url) let h1 = await page.$eval('h1', node => node.innerText) console.log(h1) await browser.close() })
另一种方法是用 page.evaluate()
,例如用下面的语句代替上面的倒数第2,3行:
let h1Handle = await page.$('h1') let h1 = await page.evaluate(node => node.innerText, h1Handle)
多个元素
多个元素就需要 page.$$eval()
同时获取多个元素,注意这里是两个 $
符号。比如下面的代码,可以获得整个页面所有 a
元素的文字
let a = await page.$$eval('a', node => node .map(n => n.innerText) )
如果只希望获取某个父元素下的元素,可以在父元素上执行 $$eval()
,比如下面的代码,可以获得某个 div
下的所有 a
元素
let parent = await page.$('.somediv') let a = await parent.$$eval('a', node => node .map(n => n.innerText) )
特定条件的多个元素
在上面代码的基础上,可以进一步筛选出符合某些条件的元素文字:
let parent = await page.$('.somediv') let a = await parent.$$eval('a', node => node .map(n => n.innerText) .filter(t => t.length>10) )
提取出了所有文字长度超过10的链接文字。