Кукловод - PullRequest
       12

Кукловод

2 голосов
/ 01 июня 2019

Я пытаюсь использовать "puppeteer": "^1.16.0", и "moment": "^2.24.0",. При запуске page.evaluate() для преобразования строки в дату obj через момент я получаю:

Ошибка: ошибка оценки: ReferenceError: момент не определен

Найдите ниже моего минимального примера:

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, однако я все еще получаю сообщение об ошибке.

Есть предложения, что я делаю не так?

Я ценю ваши ответы!

1 Ответ

3 голосов
/ 01 июня 2019

Вы можете передавать только сериализуемые данные в функцию page.evaluate в качестве аргумента. (см. документы для получения дополнительной информации). Поскольку moment является функцией, а функция не может быть сериализована, вы не можете использовать ее так просто.

Чтобы открыть функцию на странице из среды Node.js, вы можете использовать page.exposeFunction. Цитата из документов:

Метод добавляет функцию с именем name к объекту window страницы. При вызове функция выполняет puppeteerFunction в файле node.js и возвращает Promise, который преобразуется в возвращаемое значение puppeteerFunction.

Пример кода:

Следующий код в вашей среде Node.js устанавливает функцию formatDate, которая возвращает отформатированную дату:

await page.exposeFunction('formatDate', (date) =>
  moment(date, 'M/DD/YYYY').toDate()
);

Имейте в виду, что вам нужно всего лишь один раз набрать exposeFunction на странице, чтобы она выдержала навигацию. Это означает, что вы можете поместить этот код вне цикла.

Тогда ваш код кукловода может использовать такую ​​функцию:

const data = await page.evaluate(async () => {
  const priceData = []
  let date = "9/23/2016"
  priceData.push({
    price_date: await window.formatDate(date)
  })
  return priceData
})
...