【问题标题】:Is there a Puppeteer replacement for PhantomJS onInitialized to evaluate before the page is loaded?是否有 Puppeteer 替代 PhantomJS onInitialized 在页面加载之前进行评估?
【发布时间】:2018-03-13 05:49:42
【问题描述】:

我有一个程序正在使用 PhantomJS onInitialized 方法来设置页面在首次加载时可以使用的窗口全局变量。我还没有找到用 puppeteer 做到这一点的方法。在创建页面之后但转到页面之前调用评估会重置变量。在 domcontentloaded 中这样做似乎为时已晚。

  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.evaluate(pageParams => {
    window.sharedConfig = 1; // Sets it but gets reset when the page loads
  }, pageParams);

  page.on('domcontentloaded', msg => {
    page.evaluate(pageParams => {
      window.sharedConfig = 2; // Sets it but it's too late
    }, pageParams);
  });

  let pageResult = await page.goto(url);

  await page.evaluate(pageParams => {
    window.sharedConfig = 3; // Def too late
  }, pageParams);

【问题讨论】:

    标签: node.js phantomjs puppeteer


    【解决方案1】:

    我认为PhantomJS onInitialized的等效API实际上是通过Browser :: targetcreated事件实现的:

    在创建目标时发出,例如当window.openbrowser.newPage 打开新页面时。

    为所有新创建的页面初始化window.sharedConfig 的示例:

    (async () => {
      const browser = await puppeteer.launch();
    
      browser.on('targetcreated', async target => {
        const page = await target.page();
        await page.evaluate(() => {
          window.sharedConfig = 0;
        });
      });
    
      const page = browser.newPage();
      await page.evaluate(() => console.log(window.sharedConfig)); // => 0
    
      await browser.close();
    })();
    

    如果您在导航时需要额外的页面设置,您可以使用page.evaluateOnNewDocument():

    该函数在文档创建之后但在其任何脚本运行之前被调用。这对于修改 JavaScript 环境很有用,例如播种Math.random

    初始化window.sharedConfig 然后在页面导航中更改该初始值的示例:

    (async () => {
      const browser = await puppeteer.launch();
    
      browser.on('targetcreated', async target => {
        const page = await target.page();
    
        // Initialize window.sharedConfig for new page
        await page.evaluate(() => {
          window.sharedConfig = 0;
        });
    
        // Set window.sharedConfig when the page is navigated (before page loads)
        await page.evaluateOnNewDocument(() => {
          // window.sharedConfig === 0
          window.sharedConfig = 1;
        });
      });
    
      const page = browser.newPage();
      await page.evaluate(() => console.log(window.sharedConfig)); // => 0
      await page.goto('http://google.com');
      await page.evaluate(() => console.log(window.sharedConfig)); // => 1
    
      await browser.close();
    })();
    

    【讨论】:

    • 不错!我无法让 targetcreated 工作,但 page.evaluateOnNewDocument 确实并且不需要在 targetcreated 中
    【解决方案2】:

    显然页面 'framenavigated' 事件是这里的赢家:

      page.on('framenavigated', msg => {
        page.evaluate(pageParams => {
          window.sharedConfig = 3;
        }, pageParams);
      });
    

    【讨论】:

      猜你喜欢
      • 2020-01-06
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多