Получить элементы из page.evaluate в Puppeteer?

Я работаю с Node.js и Puppeteer впервые и не могу найти способ вывода значений из page.evaluate во внешнюю сферу.

Мой алгоритм:

  1. Авторизоваться
  2. Открыть URL
  3. Получить ul
  4. Зацикливайтесь на каждом li и нажмите на него
  5. Ждать innetHTML быть установленным и добавить это src содержание в массив.

Как я могу вернуть данные из page.evaluate()?

const puppeteer = require('puppeteer');

const CREDENTIALS = require(`./env.js`).credentials;
const SELECTORS = require(`./env.js`).selectors;
const URLS = require(`./env.js`).urls;

async function run() {
    try {
        const urls = [];
        const browser = await puppeteer.launch({headless: false});
        const page = await browser.newPage();

        await page.goto(URLS.login, {waitUntil: 'networkidle0'});
        await page.type(SELECTORS.username, CREDENTIALS.username);
        await page.type(SELECTORS.password, CREDENTIALS.password);
        await page.click(SELECTORS.submit);
        await page.waitForNavigation({waitUntil: 'networkidle0'});
        await page.goto(URLS.course, {waitUntil: 'networkidle0'});

        const nodes = await page.evaluate(selector => {
            let elements = document.querySelector(selector).childNodes;
            console.log('elements', elements);
            return Promise.resolve(elements ? elements  : null);
        }, SELECTORS.list);

        const links = await page.evaluate((urls, nodes, VIDEO) => {
            return Array.from(nodes).forEach((node) => {
                node.click();
                return Promise.resolve(urls.push(document.querySelector(VIDEO).getAttribute('src')));
            })
        }, urls, nodes, SELECTORS.video);
        const output = await links;
    } catch (err) {
        console.error('err:', err);
    }
}

run();

1 ответ

Функция page.evaluate()может возвращать только сериализуемое значение, поэтому невозможно вернуть элемент или NodeList вернуться из среды страницы, используя этот метод.

Ты можешь использовать page.$$() вместо этого, чтобы получить ElementHandle массив:

const nodes = await page.$$(`${selector} > *`); // selector children

Если length постоянной nodes является 0, затем убедитесь, что вы ожидаете, что элемент, указанный селектором, будет добавлен в DOM с page.waitForSelector():

await page.waitForSelector(selector);
let elementsHendles = await page.evaluateHandle(() => document.querySelectorAll('a'));
let elements = await elementsHendles.getProperties();
let elements_arr = Array.from(elements.values());

Используйте page.evaluateHandle()

API: здесь

Другие вопросы по тегам