从 Puppeteer 中的 page.evaluate 获取元素?

Posted

技术标签:

【中文标题】从 Puppeteer 中的 page.evaluate 获取元素?【英文标题】:Get elements from page.evaluate in Puppeteer? 【发布时间】:2019-04-01 15:23:33 【问题描述】:

我是第一次使用 Node.jsPuppeteer,但找不到将值从 page.evaluate 输出到外部范围的方法。

我的算法:

    登录 打开网址 获取ul 遍历每个li 并点击它 等待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();

【问题讨论】:

Wait for innetHTML to be set,你在哪里做这个? 【参考方案1】:

函数page.evaluate()只能返回一个serializable值,所以无法使用该方法从页面环境返回元素或NodeList

您可以改用page.$$() 来获取ElementHandle 数组:

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

如果常量nodeslength0,那么请确保您正在等待选择器指定的元素通过page.waitForSelector() 添加到DOM:

await page.waitForSelector(selector);

【讨论】:

【参考方案2】:
let elementsHendles = await page.evaluateHandle(() => document.querySelectorAll('a'));
let elements = await elementsHendles.getProperties();
let elements_arr = Array.from(elements.values());

【讨论】:

【参考方案3】:

使用 page.evaluateHandle()

API 是:here

【讨论】:

以上是关于从 Puppeteer 中的 page.evaluate 获取元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何解决错误:Puppeteer 中的 net::ERR_CONNECTION

Puppeteer:为什么textarea中的值返回

已在Puppeteer中定义函数后如何调用该函数

如何使用 NodeJS 和 puppeteer 从 udemy 抓取图像

Puppeteer:点击一个标签,等待新页面从链接加载,然后截图

在 puppeteer + Charles 中从本地主机更改为代理时得到 302