我正在尝试使用 "puppeteer": "^1.16.0",
和 "moment": "^2.24.0",
。当运行 page.evaluate()
将字符串转换为日期对象时,我得到:
Error: Evaluation failed: ReferenceError: moment is not defined
在下面找到我的最小示例:
const puppeteer = require("puppeteer-extra")
const moment = require('moment')
function shuffle(dataObjArr) {
let res = dataObjArr.sort(() => Math.random() - 0.5);
return res
}
let issuerUrls = JSON.parse('[{"id":62,"name":"Product 1","ecomUrl":"/product/252","createdAt":"2019-05-25T07:51:49.000Z","updatedAt":"2019-05-25T07:51:49.000Z"}, {"id":15,"name":"Product 2","ecomUrl":"/product/251","createdAt":"2019-05-25T07:51:49.000Z","updatedAt":"2019-05-25T07:51:49.000Z"}]')
let issuerUrlsShuffled = shuffle(issuerUrls)
let BASE_URL = "https://www.webscraper.io/test-sites/e-commerce/allinone"
// puppeteer usage as normal
puppeteer.launch({
headless: false,
args: ["--disable-notifications"]
}).then(async browser => {
const page = await browser.newPage()
await page.setViewport({
width: 800,
height: 600
})
for (let i = 0; i < issuerUrlsShuffled.length; i++) {
try {
let URL = BASE_URL + issuerUrlsShuffled[i].ecomUrl;
await page.goto(URL)
page.waitForNavigation({
timeout: 60,
waitUntil: 'domcontentloaded'
});
const data = await page.evaluate(() => {
const priceData = []
let date = "9/23/2016" // this is needed for testing purposes only!!!
priceData.push({
price_date: moment(date, 'M/DD/YYYY').toDate()
})
return priceData
}, moment)
// show data
console.log(JSON.stringify(data, null, 2))
await page.waitFor(3000)
} catch (error) {
console.log(error)
}
}
await browser.close()
})
如您所见,我尝试将 moment
实例传递给 evaluate
函数,但我仍然遇到错误。
对我做错了什么有什么建议吗?
感谢您的回复!
最佳答案
您只能将可序列化数据作为参数传递给 page.evaluate
函数。 (有关详细信息,请参阅 docs)。由于 moment
是一个函数,而函数不能被序列化,所以你不能那么容易地使用它。
要从您的 Node.js 环境向页面公开一个函数,您可以使用 page.exposeFunction
.引用自文档:
The method adds a function called
name
on the page'swindow
object. When called, the function executespuppeteerFunction
in node.js and returns a Promise which resolves to the return value ofpuppeteerFunction
.
代码示例:
您的 Node.js 环境中的以下代码设置了一个函数 formatDate
,它返回格式化的日期:
await page.exposeFunction('formatDate', (date) =>
moment(date, 'M/DD/YYYY').toDate()
);
请注意,您只需在页面上调用一次 exposeFunction
,因为它会在导航后继续存在。这意味着您可以将这段代码放在循环之外。
然后你的 puppeteer 代码可以使用这样的函数:
const data = await page.evaluate(async () => {
const priceData = []
let date = "9/23/2016"
priceData.push({
price_date: await window.formatDate(date)
})
return priceData
})
关于javascript - Puppeteer - Page.evaluate 使用 moment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56408206/