I am trying to use "puppeteer": "^1.16.0",
and "moment": "^2.24.0",
. When running page.evaluate()
to convert a string to a date obj via moment I get:
Error: Evaluation failed: ReferenceError: moment is not defined
Find below my minimum example:
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()
})
As you can see I tried to pass the moment
instance to the evaluate
function, however I still get the error.
Any suggestions what I am doing wrong?
I appreciate your replies!
You can only pass serializable data to the page.evaluate
function as argument. (see the docs for more information). As moment
is a function and a function cannot be serialized you cannot use it that easy.
To expose a function to the page from your Node.js environment, you can use the page.exposeFunction
. Quote from the docs:
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
.
Code sample:
The following code inside your Node.js environment sets up a function formatDate
which returns the formatted date:
await page.exposeFunction('formatDate', (date) =>
moment(date, 'M/DD/YYYY').toDate()
);
Be aware that you only need to call exposeFunction
once on the page as it survives navigation. That means you can put this code outside of the loop.
Then your puppeteer code could use the function like this:
const data = await page.evaluate(async () => {
const priceData = []
let date = "9/23/2016"
priceData.push({
price_date: await window.formatDate(date)
})
return priceData
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With