3

How to listen for new pages with playwright-python?

In JavaScript it will be documented as:

const playwright = require("playwright");

(async () => {
  const browser = await playwright.chromium.launch();
  const context = await browser.newContext();
  const page = await context.newPage();
  context.on("page", async newPage => {
    console.log("newPage", await newPage.title())
  })

  // emulate some opening in a new tab or popup
  await page.evaluate(() => window.open('https://google.com', '_blank'))
  // Keep in mind to have some blocking action there so that the browser won't be closed. In this case we are just waiting 2 seconds.
  await page.waitForTimeout(2000)
  await browser.close();
})();

Becomes in Python

from playwright import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(
        headless=False,
        executablePath='C:/Program Files/Google/Chrome/Application/chrome.exe'
    )
    context = browser.newContext()
    page = context.newPage()

'''
how to do in Python?
  context.on("page", async newPage => {
    console.log("newPage", await newPage.title())
  })

  // emulate some opening in a new tab or popup
  await page.evaluate(() => window.open('https://google.com', '_blank'))
'''

    page.waitForTimeout(2000)
    browser.close()
576i
  • 7,579
  • 12
  • 55
  • 92
LeMoussel
  • 5,290
  • 12
  • 69
  • 122

3 Answers3

4

If you need to handle new page without event listener (i.e. new tab open by link click), you can try this code:

    from playwright import sync_playwright

    with sync_playwright() as p:
        browser = p.chromium.launch()
        context = browser.newContext()
        page = context.newPage()
        page.goto('<site url>')
        with context.expect_page() as tab:
            page.click('.newTabByLink')
        # do some steps
        ...
        tab.close()
        
        browser.close()
2

Thank you to @hardkoded Here's the solution:

from playwright import sync_playwright

def newPage(page):
   print("newPage() page title:", page.title())

with sync_playwright() as p:
    browser = p.chromium.launch(
        headless=False,
        executablePath='C:/Program Files/Google/Chrome/Application/chrome.exe'
    )
    context = browser.newContext()
    page = context.newPage()

    context.on("page", lambda page: newPage(page))

    page.evaluate('''() => {
        window.open('https://google.com', '_blank')
    }''')
       
    page.waitForTimeout(2000)
    browser.close()
LeMoussel
  • 5,290
  • 12
  • 69
  • 122
1

Finally I got the right answer, playwright-python team should update their doc for multiple pages handle scenarios. It's too hard to get the answer.

Here's the solution:

with context.expect_page() as new_page:
    page.click("#multi")

pages = new_page.value.context.pages
for new_page in pages:
    new_page.wait_for_load_state()
    logging.info(new_page.title())

Reference:

https://playwright.dev/python/docs/pages

https://www.youtube.com/watch?v=DyHQ3G442jY&list=PL699Xf-_ilW7EyC6lMuU4jelKemmS6KgD&index=12

Silence He
  • 111
  • 1
  • 4