如何从 DOM 获取所有链接?
How to get all links from the DOM?
根据https://github.com/GoogleChrome/puppeteer/issues/628,我应该能够从中获取所有links行:
const hrefs = await page.$$eval('a', a => a.href);
但是当我尝试简单的时候:
console.log(hrefs)
我只得到:
http://example.de/index.html
... 作为输出,这意味着它只能找到 1 link?但是页面在源码中肯定有12link/DOM。为什么找不到所有?
最小示例:
'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);
});;
}
在您的示例代码中,您使用的是 page.$eval
,而不是 page.$$eval
。由于前者使用 document.querySelector
而不是 document.querySelectorAll
,因此您描述的行为是预期的行为。
此外,您应该在 $$eval
参数中更改 pageFunction
:
const hrefs = await page.$$eval('a', as => as.map(a => a.href));
page.$$eval()
方法在页面内运行 Array.from(document.querySelectorAll(selector))
并将其作为第一个参数传递给页面函数。
由于您的示例中的 a
表示一个数组,您需要指定要获取数组的哪个元素 href
from, or you will need to map
所有 href
属性数组。
page.$$eval()
const hrefs = await page.$$eval('a', links => links.map(a => a.href));
或者,您也可以使用page.evaluate()
or a combination of page.$$()
, elementHandle.getProperty()
, or jsHandle.jsonValue()
来实现页面所有链接的数组。
page.evaluate()
const hrefs = await page.evaluate(() => {
return Array.from(document.getElementsByTagName('a'), a => a.href);
});
page.$$() / elementHandle.getProperty() / jsHandle.jsonValue()
const hrefs = await Promise.all((await page.$$('a')).map(async a => {
return await (await a.getProperty('href')).jsonValue();
}));
根据https://github.com/GoogleChrome/puppeteer/issues/628,我应该能够从中获取所有links行:
const hrefs = await page.$$eval('a', a => a.href);
但是当我尝试简单的时候:
console.log(hrefs)
我只得到:
http://example.de/index.html
... 作为输出,这意味着它只能找到 1 link?但是页面在源码中肯定有12link/DOM。为什么找不到所有?
最小示例:
'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);
});;
}
在您的示例代码中,您使用的是 page.$eval
,而不是 page.$$eval
。由于前者使用 document.querySelector
而不是 document.querySelectorAll
,因此您描述的行为是预期的行为。
此外,您应该在 $$eval
参数中更改 pageFunction
:
const hrefs = await page.$$eval('a', as => as.map(a => a.href));
page.$$eval()
方法在页面内运行 Array.from(document.querySelectorAll(selector))
并将其作为第一个参数传递给页面函数。
由于您的示例中的 a
表示一个数组,您需要指定要获取数组的哪个元素 href
from, or you will need to map
所有 href
属性数组。
page.$$eval()
const hrefs = await page.$$eval('a', links => links.map(a => a.href));
或者,您也可以使用page.evaluate()
or a combination of page.$$()
, elementHandle.getProperty()
, or jsHandle.jsonValue()
来实现页面所有链接的数组。
page.evaluate()
const hrefs = await page.evaluate(() => {
return Array.from(document.getElementsByTagName('a'), a => a.href);
});
page.$$() / elementHandle.getProperty() / jsHandle.jsonValue()
const hrefs = await Promise.all((await page.$$('a')).map(async a => {
return await (await a.getProperty('href')).jsonValue();
}));