【发布时间】:2021-05-12 07:04:40
【问题描述】:
我正试图在 puppeteer 的帮助下从网站获取一些链接。
async function getLinks(){
const first = 'first';
const last = 'last';
const browser = await browserControl.startBrowser();
const page = await browser.newPage();
await page.goto(url_baseStats);
// await page.waitForNavigation();
let links = await page.evaluate((first, last) => {
try {
let links = Array.from(document.querySelectorAll('a'), a => a.getAttribute('href'));
links = links.slice(links.indexOf(first), links.indexOf(last));
return links;
} catch(err) {
throw err;
}
});
console.log("links:", links);
return links;
}
我有两个问题:
-
当我运行调试器时,他会到达“await page.evaluate((...”-point,然后跳转 直接到“console.log(...”。他为什么不等?
-
为什么我需要将变量 first 和 last 作为参数传递给评估函数? 我上面定义的,应该在评估函数的范围内吧?!?
提前致谢 ;_)
【问题讨论】:
-
是时候进行更多的调试了:让你的函数在你的catch之后返回一个值,这样你就可以检查它是否真的立即出错了。至于为什么需要先和最后传递:you don't,除非您希望“不在浏览器中运行”上下文中的值传递到浏览器上下文中,否则您可以这样做。在这种情况下,您似乎忘记设置
evaluate(..., first, last)以便将这两个值放入您的函数中。 -
显然(根据文档)
page.evaluate()仅在函数回调返回 Promise 时才等待。 (但是文档不是很清楚。) -
我不知道为什么
first和last也在那里;.evaluate()回调的参数应该在.evaluate()调用本身的回调函数之后传递。他们为什么在那里?你期望他们有什么价值观? 编辑哦等等;是的,将参数first, last从回调函数中取出。实际上,它们将是undefined,因此回调不会像您预期的那样工作。 -
那么您必须将
first和last作为第二个和第三个参数传递给.evaluate()调用。 (并将参数放回去。) -
函数作为文本从Node域传输到浏览器域,所以正常的范围规则没有意义。
标签: javascript node.js async-await puppeteer