You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Puppeteer无法访问Canvas函数,Chrome DevTools却可行,求排查

Fixing Puppeteer's Inability to Access React Internal Instance on Canvas

Key Issues in Your Original Code

  • Context Mismatch: Puppeteer runs in Node.js, while the DOM and React's internal properties live in the browser's JavaScript context. page.$ returns an ElementHandle (a reference to the DOM element), not the actual element—you can't iterate over its properties directly in Node.js.
  • Invalid Callback Usage: page.$ does not accept a callback function as its second argument. This is why your "Found the canvas" log never appears—this code never executes.

Corrected Approach

To access the canvas's properties (including React's internal instance), you need to run your inspection code inside the browser's context using page.evaluate(). Here's the fixed code:

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({
        executablePath: "/usr/bin/google-chrome",
        headless: true,
        userDataDir: '/tmp'
    });

    const page = await browser.newPage();

    // Capture browser console logs in Node.js terminal
    page.on('console', msg => console.log('Browser Log:', msg.text()));

    // Set user agent and viewport
    await page.setUserAgent("Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36");
    await page.setViewport({ width: 412, height: 915 });

    await page.goto('https://www.nytimes.com/puzzles/letter-boxed');
    try {
        // Click start button
        await page.waitForSelector("button.pz-moment__button.primary");
        const startButton = await page.$("button.pz-moment__button.primary");
        await startButton.click();
        await delay(3000);

        // Wait for canvas to load
        await page.waitForSelector("#pz-game-root > div > div > div.lb-square-container > canvas");

        // Run inspection code in browser context
        const reactInstanceData = await page.evaluate(() => {
            const canvas = document.querySelector("#pz-game-root > div > div > div.lb-square-container > canvas");
            let reactPropName = '';
            let reactInstance = null;

            for (const prop in canvas) {
                if (prop.includes("__reactInternalInstance")) {
                    console.log(`React Internal Prop Name: ${prop}`);
                    reactPropName = prop;
                    reactInstance = canvas[prop];
                    break;
                }
            }

            // Return serializable data (full React instance can't be sent due to circular references)
            return {
                reactPropName: reactPropName,
                instanceKeys: reactInstance ? Object.keys(reactInstance) : []
            };
        });

        console.log("React Instance Details:", reactInstanceData);

    } catch (error) {
        console.log("Failure occurred");
        console.log(error);
    }
    await browser.close();
})();

function delay(time) {
    return new Promise(resolve => setTimeout(resolve, time));
}

Important Notes

  • page.evaluate() executes code directly in the browser, allowing you to interact with the DOM element just like in DevTools.
  • React's internal instance objects often have circular references, so we can't return the entire object to Node.js. Extract specific data you need inside page.evaluate() if necessary.
  • The page.on('console') listener lets you see logs from the browser's console in your Node.js terminal.

Additional Troubleshooting Tip

If the React instance still isn't found, use page.waitForFunction() to wait until the property exists:

await page.waitForFunction(() => {
    const canvas = document.querySelector("#pz-game-root > div > div > div.lb-square-container > canvas");
    if (!canvas) return false;
    for (const prop in canvas) {
        if (prop.includes("__reactInternalInstance")) return true;
    }
    return false;
});

内容的提问来源于stack exchange,提问作者Marc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:35:23