首页 > 解决方案 > 如何在 puppeteer 中访问全局变量

问题描述

在这个示例代码中,当它读取数组contactListj说两者都没有定义时,出了什么问题?


const { join } = require('path');
const puppeteer = require('puppeteer');

(async () => {

    // 1. Launch the browser
    const browser = await puppeteer.launch({   
          "args": [
              '--remote-debugging-port=9222'
          ],
          "defaultViewport": {
            "height": 1080,
            "width": 1920
          },
          "headless": false
        });

    // 2. Open a new page
    const page = await browser.newPage();

    // 3. Navigate to URL
    await page.goto('https://');

    await new Promise(r => setTimeout(r, 10000));
    console.log('Ready');

    var contactList = ['cesar','gab','777','81411579','34353'];
    var fLen = contactList.length;
    var j = 0;

    for (i = 0; i < fLen; i++) {

        await page.evaluate(() => {

            function searchContact(contact_name = "") {
                //search = document.querySelector('#side > div._1Ra05 > div > label > div > div._1awRl.copyable-text.selectable-text');
                search = document.querySelector('#side > div._1Ra05 > div > label > div > div._1awRl.copyable-text.selectable-text');
            }
            j++;
            searchContact(contactList[j]);

        }
    }

标签: javascriptpuppeteer

解决方案


看一看 Puppeteer 的page.evaluate(pageFunction[,...args]). 它指出:

pageFunction <function|string> 要在页面上下文中评估的函数

注意(我的粗体)“在页面上下文中评估”。变量jcontactList不存在于页面的上下文中。

然而幸运的是,Puppeteer 有一种从页面上下文调用服务器端代码的方法page.exposeFunction(name, puppeteerFunction)

该方法在页面的窗口对象上添加了一个名为 name 的函数。调用时,该函数执行 node.js 中的 puppeteerFunction 并返回一个 Promise,该 Promise 解析为 puppeteerFunction 的返回值。

对于您的用例,它看起来类似于以下内容:

const puppeteer = require('puppeteer');

(async function()
{
    const browser = await puppeteer.launch({
        headless: false,
        args: [
            "--no-sandbox", // I needed these args for it to run on my machine, you probably don't need them.
            "--disable-setuid-sandbox"
        ]
    });
    const page = await browser.newPage();
    const contacts = ["Charlie", "Carl", "Dennis", "Conrad"];
    await page.exposeFunction("getContacts", function()
    {
        return contacts;
    });
    await page.exposeFunction("addContact", function(contact)
    {
        contacts.push(contact);
    });
    await page.evaluate(async function()
    {
        await addContact("Henry");
        await addContact("Olav");
        const contacts = await getContacts();
        contacts.forEach(function(contact)
        {
            const div = document.createElement("div");
            div.innerHTML = contact;
            document.body.appendChild(div);
        });
    });
    console.log("Contacts after evaluating page function: ", contacts.join(", "));
})()

请注意,这是一个玩具示例,虽然是一个完整且可运行的示例。你应该能够从中找出其余的。您在 OP 中的示例中发布的代码没有多大意义(即无限递归函数searchContact()),因此您只需要根据您的用例进行调整。


推荐阅读