page.evaluate 和 page.$ 具有后续函数的不同行为



我有一个正在加载的页面。以下page.$eval()代码有效:

const productName = await page.$eval('h1[role="main"]', el =>
[].reduce.call(
el.childNodes,
(a, b) =>
a +
(b.nodeType === 3
? b.textContent
.replace(/[rn]+/gm, "")
.replace(/s+/g, " ")
.trim()
: ""),
""
)
);

通过工作,我的意思是它返回预期的产品名称。我在主函数中运行它。

我现在想将代码外包给原始上下文之外的自己的函数(要重用(。

我在主函数中调用函数,如下所示:

const productName = await page
.$('h1[role="main"]')
.then(el => getProductNameFromSelector(el))
.catch(err => console.log("failure product name", err));

外包功能是这样的:

const getProductNameFromSelector = async el =>
el
.evaluate(
el,
[].reduce.call(
el.childNodes,
(a, b) =>
a +
(b.nodeType === 3
? b.textContent
.replace(/[rn]+/gm, "")
.replace(/s+/g, " ")
.trim()
: ""),
""
)
)
.then(result => result)
.catch(err => console.log("error in function", err, el));

它遇到以下错误:

failure product name TypeError: Cannot read property 'evaluate' of null
at reduce (<anonymous>)
at getProductNameFromSelector (pathToFile.js:395:17)
at page.$.then.el (pathToFile.js:119:21)
at process._tickCallback (internal/process/next_tick.js:68:7)

我应该收到page.$('h1[role="main"]')ElementHandle.不过它说undefined

evaluate函数需要期望el作为参数

const getProductNameFromSelector = async el =>
el
.evaluate(el =>  //HERE
[].reduce.call(
el.childNodes,
(a, b) =>
a +
(b.nodeType === 3
? b.textContent
.replace(/[rn]+/gm, "")
.replace(/s+/g, " ")
.trim()
: ""),
""
)
)
.then(result => result)
.catch(err => console.log("error in function", err, el));

您也可以等待选择器:

const productName = await page
.waitForSelector('h1[role="main"]')
.then(el => getProductNameFromSelector(el))
.catch(err => console.log("failure product name", err));

最新更新