根据https://github.com/GoogleChrome/puppeteer/issues/628,我应该可以从<获取所有链接a href =“xyz”> 这一行:
const hrefs = await page.$$eval('a', a => a.href);
但是当我尝试一个简单的
时console.log(hrefs)
我只得到
http://example.de/index.html
作为输出,这意味着它只能找到1个链接?但该页面在源代码/ DOM中肯定有12个链接。为什么找不到它们呢?
最小例子:
'use strict';
const puppeteer = require('puppeteer');
crawlPage();
function crawlPage() {
(async () => {
const args = [
"--disable-setuid-sandbox",
"--no-sandbox",
"--blink-settings=imagesEnabled=false",
];
const options = {
args,
headless: true,
ignoreHTTPSErrors: true,
};
const browser = await puppeteer.launch(options);
const page = await browser.newPage();
await page.goto("http://example.de", {
waitUntil: 'networkidle2',
timeout: 30000
});
const hrefs = await page.$eval('a', a => a.href);
console.log(hrefs);
await page.close();
await browser.close();
})().catch((error) => {
console.error(error);
});;
}
答案 0 :(得分:7)
在您的示例代码中,您使用的是page.$eval
,而不是page.$$eval
。由于前者使用document.querySelector
而不是document.querySelectorAll
,因此您描述的行为是预期的行为。
此外,您应该更改pageFunction
参数中的$$eval
:
const hrefs = await page.$$eval('a', as => as.map(a => a.href));
答案 1 :(得分:2)
page.$$eval()
方法在页面内运行Array.from(document.querySelectorAll(selector))
,并将其作为第一个参数传递给页面函数。
由于示例中的a
表示一个数组,因此您将需要指定要从中获取href
的数组元素,或者您需要全部map
href
属性中的一个到数组。
const hrefs = await page.$$eval('a', links => links.map(a => a.href));
或者,您也可以使用page.evaluate()
或page.$$()
,elementHandle.getProperty()
或jsHandle.jsonValue()
的组合来获得页面中所有链接的数组。
const hrefs = await page.evaluate(() => {
return Array.from(document.getElementsByTagName('a'), a => a.href);
});
const hrefs = await Promise.all((await page.$$('a')).map(async a => {
return await (await a.getProperty('href')).jsonValue();
}));