Puppeteer: рдЕрдВрддрд┐рдо рдкреГрд╖реНрда рдмрдВрдж рд╣реЛрдиреЗ рдкрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдмрдВрдж рдХрд░рдирд╛ рдХрднреА-рдХрднреА рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрддрд╛ рд╣реИ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 27 рдорд╛рд░реНрдЪ 2018  ┬╖  9рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: puppeteer/puppeteer

рд╣рдореЗрдВ рдЕрдкрдиреЗ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдПрдВ:

  • рдХрдардкреБрддрд▓реА рд╕рдВрд╕реНрдХрд░рдг: 1.2.0
  • рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо / рдУрдПрд╕ рд╕рдВрд╕реНрдХрд░рдг: рд╕реЗрдВрдЯреЛрд╕ 7.4.1708
  • URL (рдпрджрд┐ рд▓рд╛рдЧреВ рд╣реЛ): N / A
  • Node.js рд╕рдВрд╕реНрдХрд░рдг: v8.10.0

рдХреМрди рд╕рд╛ рдХрджрдо рдлрд┐рд░ рд╕реЗ рд╕рдорд╕реНрдпрд╛ рдкреИрджрд╛ рдХрд░ рджреЗрдЧрд╛?

const puppeteer = require('puppeteer');

const run = async () => {
  const browser = await puppeteer.launch();

  // close any open pages
  let pages = await browser.pages();
  await Promise.all(pages.map(async page => await page.close()));

  // handle a page being closed
  browser.on('targetdestroyed', async target => {
    const openPages = await browser.pages();
    console.log('Open pages:', openPages.length);
    if (openPages.length == 0) {
      console.log('Closing empty browser');
      await browser.close();
      console.log('Browser closed');
    }
  });

  pages = await browser.pages();
  for (let i = 0; i < 5; i++) {
    await browser.newPage();
  }

  pages = await browser.pages();
  pages.forEach((page) => page.close());
};

run();

рдкрд░рд┐рдгрд╛рдо рдХреА рдХреНрдпрд╛ рдЙрдореНрдореАрдж рд╣реИ?

Count: 0
Open pages: 4
Open pages: 3
Open pages: 2
Open pages: 1
Open pages: 0
Closing empty browser
Browser closed

рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ?

Open pages: 4
Open pages: 3
Open pages: 2
Open pages: 1
Open pages: 0
Closing empty browser
(node:29074) UnhandledPromiseRejectionWarning: Error: Protocol error (Target.closeTarget): Target closed.
    at Promise (node_modules/puppeteer/lib/Connection.js:86:56)
    at new Promise (<anonymous>)
    at Connection.send (node_modules/puppeteer/lib/Connection.js:85:12)
    at Page.close (node_modules/puppeteer/lib/Page.js:802:36)
    at pages.forEach (test.js:27:32)
    at Array.forEach (<anonymous>)
    at run (test.js:27:9)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
(node:29074) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:29074) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Browser closed

рдРрд╕рд╛ рд╣рд░ рд░рди рдореЗрдВ рдирд╣реАрдВ рд╣реЛрддрд╛

рд╕рднреА 9 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

+1

рдереЛрдбрд╝реА рдЬрд▓реНрджреА рдбрд┐рдмрдЧрд┐рдВрдЧ рдХрд┐рдпрд╛, targetDestroyed рдШрдЯрдирд╛ page.close() рд╕рдВрджреЗрд╢ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдирд┐рдХрд╛рд▓ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдпрд╛ рдмрд▓реНрдХрд┐, рдХрдардкреБрддрд▓реА рдиреЗ рдкрд╛рд╡рддреА рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рд╣реИ)ред

рдореИрдВ рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪ рд╕рдХрддрд╛ рд╣реВрдВ - рдЬреИрд╕реЗ рдХрд┐ targetDestroyed рдЗрд╡реЗрдВрдЯ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ Target.closeTarget рдкрд╛рд╡рддреА рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░реЗрдВред рдХреИрд╕реЗ рдареАрдХ рд╕реЗ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рд╛рд▓рд╛рдВрдХрд┐ рдПрдХ рдФрд░ рд╕рд╡рд╛рд▓ рд╣реИ!

рдЬрд╛рдВрдЪ рдХреЗ рд▓рд┐рдП @MJPA рдХреЛ рдзрдиреНрдпрд╡рд╛рджред

рдореБрджреНрджрд╛ рдЗрд╕ рддрдереНрдп рд╕реЗ рдЖрддрд╛ рд╣реИ рдХрд┐ browser рд╕рдВрдмрдВрдзрд┐рдд рдкреГрд╖реНрдареЛрдВ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕реВрдЪреА рд╕реЗ рд▓рдХреНрд╖реНрдп рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реИред

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдореИрдВ browser.pages() рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП page.close() рдХреЙрд▓ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдХреА рдЙрдореНрдореАрдж рдХрд░реВрдВрдЧрд╛:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const [page] = await browser.pages();
  browser.on('targetdestroyed', async () => console.log('Target destroyed. Pages count: ' + (await browser.pages()).length));
  console.log('closing page...');
  await page.close();
  console.log('page closed.');
  await browser.close();
})();

рдЙрддреНрдкрд╛рджрди:

closing page...
Target destroyed. Pages count: 0
page closed.

@JoelEinbinder рдЖрдкрдХреЛ рдХреНрдпрд╛ рд▓рдЧрддрд╛ рд╣реИ?

@MJPA рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╣реА рдореБрджреНрджрд╛

        await page.waitForSelector('aside.aside a[href="/checkout"]')
    .then(() => {
        logMessage('Checkout is available');
    })
    .catch(err => {
        log('Checkout not available');
        success = false;
        browser.close();
    });
    // click checkout button
    await Promise.all([
        page.click('aside.aside a[href="/checkout"]'),
        page.waitForNavigation()
    ]);

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдореЗрд╢рд╛ рд╡рд╣реА рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реБрдИрдВред

рд╢рд╛рдпрдж рдпрд╣ рдХрдардкреБрддрд▓реА рддреНрд░реБрдЯрд┐ред

рдореИрдВ рдПрдХ рд╕реЗ рдереЛрдбрд╝рд╛ рд╕рдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдХреЛ рд╕реБрдирдиреЗ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ close рдПрдХ рдкрд░ рдШрдЯрдирд╛ page ред рдкреНрд░рд▓реЗрдЦрди "рдХреНрд▓реЛрдЬрд╝" рдХрд╛ рдорддрд▓рдм рдХреНрдпрд╛ рд╣реИ рдкрд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдЕрдиреБрд╕рд╛рд░, close рдирд┐рдХрд╛рд▓ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ _before_ рдкреГрд╖реНрда рдмрдВрдж рд╣реИ, рдЗрд╕рд▓рд┐рдП рдирд┐рдореНрди рдЙрджрд╛рд╣рд░рдг targetdestroyed рд╕рдорд╛рди рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ

const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();

// create 5 test pages
for(let i=0; i<5; i++){

  let page = await browser.newPage();

  // listen to page close event and close browser
  // when all get closed
  page.on('close', async () => {
    let pages = await browser.pages();
    if(!pages.length){
      // will not get here!
      browser.close();
    }
  });

}

let pages = await browser.pages();

pages.forEach(async (page) => await page.close());  

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ _sort__ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдШрдЯрдирд╛ рдХреЛ close рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ closed ред рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдЖрд╕рдкрд╛рд╕ closed close() рд╡рд╛рджрд╛ рдХрд░рдХреЗ рдЕрдкрдиреЗ рдХреЙрд▓рдмреИрдХ рдХреЛ рд╡рд╛рдкрд╕ рд▓реЗ рд▓рд┐рдпрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рд╕реБрди рд░рд╣рд╛ рд╣реВрдВ, рдЬреЛ _does_ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

page.close().then(() => {
  page.emit('closed');
});

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЬрдм рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИ (рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рдмрд┐рдирд╛) рдЬрд╛рдирдиреЗ рдХреА рдХрд╣рд╛рдиреА рдХреА рдиреИрддрд┐рдХрддрд╛ рдХреЛрдИ 100% рдЧрд╛рд░рдВрдЯреАрдХреГрдд рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдмрддрд╛рдПрдВ рдХрд┐ рдХреНрдпрд╛ рдореБрдЭреЗ рдХреБрдЫ рдпрд╛рдж рдЖ рд░рд╣рд╛ рд╣реИред

рд╕рдВрднрд╡рддрдГ # 3423 рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ?

рдореБрдЭреЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рд╕рднреА рдЯреИрдм рдмрдВрдж рдХрд░рдиреЗ рдФрд░ рдлрд┐рд░ рдПрдХ рдирдпрд╛ рдкреГрд╖реНрда рдЦреЛрд▓рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдпрд╣ рдорд┐рд▓рддрд╛ рд╣реИ

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдореИрдВ browser.pages() 1 рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП page.close() рдХреЙрд▓ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рддрдХ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░реВрдВрдЧрд╛:

рдпрд╣ рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдХреЛрдб рдХреЛ рддреЛрдбрд╝ рджреЗрдЧрд╛ред рдЕрдВрддрд┐рдо рдкреГрд╖реНрда рдмрдВрдж рд╣реЛ рдЧрдпрд╛, brower.pages ()ред рд▓рдВрдмрд╛рдИ 1 рд╣реЛрдЧреА, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдмрдВрдж рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рддрдм рдХреЛрдИ рдФрд░ рд▓рдХреНрд╖реНрдп рдирд╖реНрдЯ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдШрдЯрдирд╛рдПрдБ рдирд╣реАрдВ рдЖрдПрдВрдЧреА рдФрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╣рдореЗрд╢рд╛ рдХреЗ рд▓рд┐рдП рдЬреАрд╡рд┐рдд рд░рд╣реЗрдЧрд╛ред

рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рддреНрд░реБрдЯрд┐ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рд╕реВрдХреНрд╖реНрдо рд╣реИред рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рдХреЙрд▓ page.close рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рдереЗ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП browser.close() ред

рдпрджрд┐ рдХреЛрдИ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдкреГрд╖реНрда рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдмрд╕ Promise.all рдкрд░ рд╕рднреА рдкреГрд╖реНрда рдмрдВрдж рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рдлрд┐рд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдмрдВрдж рдХрд░реЗрдВред targetdestroyed рдИрд╡реЗрдВрдЯ рд╕реБрдирдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдпрд╛ рд╕рд┐рд░реНрдл browser.close рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ рдФрд░ рд╕рднреА рдкреЗрдЬреЛрдВ рдХреЛ рдЦреБрдж рд╕реЗ рдмрдВрдж рдХрд░ рджреЗрдВред

рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдкреГрд╖реНрда рд╣реИрдВ, рддреЛ targetdestroyed рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╕реБрдиреЗрдВ, рд▓реЗрдХрд┐рди page.close рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред

+1ред
рдореИрдВрдиреЗ page.on("popup") рд╕рд╛рде рдкреЙрдкрдЕрдк рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдЗрд╕ рддреНрд░реБрдЯрд┐ рдХреЛ рджреЗрдЦрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ред рдЬрдм рдХреЛрдИ рдкреЙрдкрдЕрдк рдлрд╝реНрд░реЗрдо рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдлрд╛рдпрд░ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдХрднреА-рдХрднреА рдореИрдВ рдЗрд╕реЗ "popup.close ()" рдХреЗ рд╕рд╛рде рдмрдВрдж рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдФрд░ рдХрдардкреБрддрд▓реА рдЦреЛрд▓реЗ рд╣реБрдП рдЯреИрдм рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЬрдм рдореИрдВ рд╕рдВрдкреВрд░реНрдг рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдпрд╣ "рд▓рдХреНрд╖реНрдп рдмрдВрдж" рддреНрд░реБрдЯрд┐ рдХреЛ рдлреЗрдВрдХ рджреЗрддрд╛ рд╣реИред рдФрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдмрдВрдж рдХрд░реЛред

рдореИрдВ рдХреНрд░реЛрдореЗрдЯреЗрд░ 1.14 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рдХреНрд░реЛрдо 73 рдХреЗ рд╕рд╛рде (рдореИрдВ рдХреНрд░реЛрдорд┐рдпрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛)
рд╡рд╣ рдХреЛрдб рдЬреЛ рдореИрдВ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ

async close_browser() {
    for (let page of await this.browser.pages()) {
      await page.close({
        "runBeforeUnload": true
      });
    }
   await this.browser.close();
}
рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕