无需将 Cheerio 与 Puppeteer 一起使用。 Puppeteer 已经可以使用实时页面,因此将页面快照为字符串,然后将其转储到单独的库中通常没有意义。
相反,请使用
page.$$eval(yourSelector, browserCallback)
来完成这项工作:
const puppeteer = require("puppeteer"); // ^21.6.0
const html = `<HTML pasted from your question>`;
let browser;
(async () => {
browser = await puppeteer.launch({headless: "new"});
const [page] = await browser.pages();
await page.setContent(html);
const people = await page.$$eval(
"table td .people .person",
els => els.map(el => el.textContent.trim())
);
console.log(people);
})()
.catch(err => console.error(err))
.finally(() => browser?.close());
输出:
[
'Richard', 'Linus',
'Brian', 'Alan',
'Bill', 'Ada',
'Steve', 'Ken'
]
如果你想保持类别不同,你可以使用嵌套查询:
// ...
const people = await page.$$eval("table td", els =>
els.map(el => ({
category: el.className,
people: [...el.querySelectorAll(".person")].map(e =>
e.textContent.trim()
),
}))
);
// ...
给出:
[
{ category: 'hr', people: [ 'Richard', 'Linus', 'Brian' ] },
{
category: 'manufacturing',
people: [ 'Alan', 'Margret', 'Ken', 'Edsger' ]
},
{ category: 'design', people: [ 'Bill', 'Ada', 'Steve', 'Ken' ] }
]
为了回答您的其他问题,出于演示目的,我使用
setContent
,如上所示,但您可以 运行服务器 并导航到本地主机上的页面。只需确保包含端口即可。