Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Use Playwright’s asynchronous Python API directly in notebook cells. Install the Python package in the environment used by the active kernel, install matching browser binaries, then run browser code with top-level await. Do not wrap notebook code in asyncio.run(): IPykernel already has an event loop running.

This guide shows a complete setup, reusable notebook patterns, browser and display choices, and fixes for the errors that most often stop Playwright in Jupyter.

What you need before starting

  • A Jupyter Notebook or JupyterLab kernel running Python.
  • Permission to install Python packages and browser binaries in that kernel environment.
  • A supported Playwright browser: Chromium, Firefox, or WebKit.
  • For headed (visible) mode, a notebook host with a usable graphical display. Headless mode is the default.

Playwright’s Python documentation describes both synchronous and asynchronous APIs. In a notebook, the asynchronous API fits the execution model best because IPykernel keeps an asyncio event loop running. The examples below are documented API usage adapted to notebook cells; hosted notebook providers can impose their own package, display, or operating-system restrictions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install Playwright in the active notebook kernel

Run this in a notebook cell rather than assuming your terminal’s Python is the same interpreter as the kernel:

%pip install playwright

The %pip magic asks IPython to install into the environment associated with the current kernel. Restart the kernel if the import is still unavailable after installation.

Install a browser binary

The Python package and browser binaries are separate. Install only the engine you need:

!python -m playwright install chromium

For the other engines, replace chromium with firefox or webkit. Playwright releases expect specific browser revisions, so run the install command again after upgrading Playwright. On Linux, the host may also need operating-system libraries. Playwright documents a combined browser-and-dependency command:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
!python -m playwright install --with-deps chromium

Whether that command succeeds depends on your notebook provider’s permissions; managed environments may not allow system-package installation.

Verify the kernel and import

import sys
print(sys.executable)

from playwright.async_api import async_playwright
print("Playwright import succeeded")

sys.executable should identify the Python environment where you installed the package. If the import fails, install again with %pip in that same kernel instead of using a separate terminal environment.

Run your first Playwright cell

Use top-level await and an asynchronous context manager:

from playwright.async_api import async_playwright

async with async_playwright() as p:
    browser = await p.chromium.launch()
    page = await browser.new_page()
    await page.goto("https://example.com")
    print(await page.title())
    await browser.close()

The expected output is the page title, typically Example Domain. The context manager starts and shuts down Playwright; explicitly closing the browser prevents browser processes from accumulating as you rerun cells.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make navigation and content checks explicit

from playwright.async_api import async_playwright

async with async_playwright() as p:
    browser = await p.chromium.launch()
    page = await browser.new_page()
    response = await page.goto("https://example.com", wait_until="domcontentloaded")
    print("HTTP status:", response.status if response else "no response")
    print("Title:", await page.title())
    print("Heading:", await page.locator("h1").inner_text())
    await browser.close()

A navigation response can be absent for some navigations, so the example checks it before reading status. Locators provide Playwright’s waiting behavior for elements that are not immediately present.

Why asyncio.run() usually fails in Jupyter

In a normal Python script, asyncio.run(main()) creates and owns an event loop. In a notebook, IPykernel already runs one. Calling asyncio.run() from a cell therefore commonly raises an error such as “asyncio.run() cannot be called from a running event loop.” Keep the coroutine at cell level instead:

# Correct in a notebook cell
await some_async_function()

IPython’s autoawait integration supports top-level asynchronous statements when IPykernel 5.0 or later is in use. Inspect or change integration with:

%autoawait

If top-level await is rejected, check the running kernel’s IPython and IPykernel versions and whether autoawait has been disabled. Notebook behavior is not identical to a terminal IPython session, so do not copy event-loop workarounds blindly from command-line examples.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Reusable notebook patterns

Keep a browser open across cells

For exploratory work, you can create objects in one cell and use them later. This is convenient but makes cleanup your responsibility:

from playwright.async_api import async_playwright

pw = await async_playwright().start()
browser = await pw.chromium.launch()
page = await browser.new_page()
await page.goto("https://example.com")
print(await page.title())

When finished, close everything:

await browser.close()
await pw.stop()

If a cell fails before cleanup, rerun the cleanup commands where the variables still exist, or restart the kernel to terminate orphaned processes.

Use a helper for repeated captures

from playwright.async_api import async_playwright

async def read_page_title(url: str) -> str:
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        try:
            page = await browser.new_page()
            await page.goto(url, wait_until="domcontentloaded")
            return await page.title()
        finally:
            await browser.close()

print(await read_page_title("https://example.com"))

The try/finally block closes the browser even when navigation or extraction raises an exception.

Interact with a page

from playwright.async_api import async_playwright

async with async_playwright() as p:
    browser = await p.chromium.launch()
    page = await browser.new_page()
    await page.goto("https://example.com")
    await page.locator("a").click()
    await page.screenshot(path="result.png", full_page=True)
    await browser.close()

Prefer locator actions and their built-in waiting over arbitrary sleeps. Playwright’s guide warns that blocking time.sleep() can leave asynchronous operations unable to progress and produce stale state. If a fixed delay is genuinely required, use Playwright’s timeout helper sparingly:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.wait_for_timeout(1000)

Choose a browser and display mode

Chromium, Firefox, or WebKit

Chromium is a practical default for an introductory notebook because it has a direct install command. Choose Firefox or WebKit when your test or rendering task specifically targets those engines. Install each engine with the matching Playwright command, and keep binaries synchronized with the installed Playwright release.

Headless versus headed

Playwright launches headless by default, which is suitable for most hosted notebooks and automation:

browser = await p.chromium.launch(headless=True)

To request a visible window on a local machine:

browser = await p.chromium.launch(headless=False)

Headed mode requires a usable display. Cloud notebooks may have no GUI, may restrict display forwarding, or may block installation of required libraries. If headed launch fails, return to headless mode or follow the provider’s display instructions.

Windows event-loop detail

Playwright’s Python documentation notes that its driver subprocess on Windows requires asyncio’s ProactorEventLoop; Python 3.8 and later use that policy by default. Most notebook users should not replace the event loop manually. If you have changed the loop policy, restore the documented Windows configuration before troubleshooting Playwright.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Waiting, timeouts, and dynamic pages

Modern pages load content after the initial response. Use a locator or a specific state rather than a blind delay:

await page.goto("https://example.com", wait_until="domcontentloaded")
await page.locator("h1").wait_for(state="visible")
text = await page.locator("h1").inner_text()

You can set a bounded timeout for an operation:

page.set_default_timeout(10_000)
page.set_default_navigation_timeout(30_000)

A timeout is a diagnostic signal: check the selector, network access, redirects, authentication, and whether the page is blocked by the host. Avoid making every operation wait for a long fixed number of seconds; that slows successful runs and still does not guarantee that the desired state exists.

Common failures and precise fixes

“No module named playwright”

Cause: The package was installed into a different Python environment.

Fix: Run %pip install playwright in the active notebook, restart the kernel, print sys.executable, and retry the import.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Executable doesn’t exist or browser was not found

Cause: The Python package is present but its browser binary is not.

Fix: Run !python -m playwright install chromium (or the engine you selected). Reinstall after a Playwright upgrade if the revision is stale.

Linux launch reports missing shared libraries

Cause: The operating-system dependencies required by the browser are absent.

Fix: If you control the machine, run !python -m playwright install --with-deps chromium. If you use a managed notebook, ask the provider for the supported browser image or dependency-install procedure.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

asyncio.run() raises a running-loop error

Cause: IPykernel already owns an event loop.

Fix: Replace the wrapper with top-level await and use async with async_playwright().

Headed mode cannot open a window

Cause: The notebook host has no usable display or blocks GUI processes.

Fix: Launch headless, or configure the host’s supported display forwarding. Do not assume a browser window can appear in a remote notebook UI.

Navigation or locator timeout

Cause: The URL is unreachable, the selector is wrong, content is delayed, or a page is waiting on authentication or another interaction.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fix: Print the current URL, inspect the page title and HTML, verify network access, and wait for a concrete locator state. Increase the timeout only after confirming the operation is expected to take longer.

Results are stale after time.sleep()

Cause: Blocking the thread prevents Playwright’s asynchronous work from being processed normally.

Fix: Use locator auto-waiting, wait_for, navigation conditions, or page.wait_for_timeout() for the narrow case that needs a fixed pause.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Notebook reliability and resource hygiene

  • Put browser startup and shutdown in a context manager for one-cell experiments.
  • Close pages and browsers when a long-lived session is no longer needed.
  • Keep package and browser versions aligned; reinstall binaries after upgrades.
  • Prefer headless execution on remote hosts unless a supported display is documented.
  • Record the URL, operation, and exception when a cell fails so you can distinguish site behavior from environment problems.
  • Use bounded navigation and action timeouts to prevent a stuck cell from holding the kernel indefinitely.

Or skip the browser setup

If your goal is a clean website image or PDF rather than learning browser automation, ScreenshotNeo provides a single screenshot API request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response reports the result in X-Page-Verdict and X-Billed headers.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read the parameter and response details in the ScreenshotNeo documentation. This cURL example saves a WebP image:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Equivalent Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Equivalent Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

FAQ

Can I use Playwright synchronously in a notebook?

Playwright supplies a synchronous API, but the asynchronous API with top-level await is the safer default in an IPykernel notebook because its event loop is already running.

Do I need to install all three browsers?

No. Install only Chromium, Firefox, or WebKit required by your work. Installing a browser binary is separate from installing the Python package.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why does my code work locally but not in a hosted notebook?

Hosted services can restrict system dependencies, browser downloads, network access, and graphical displays. Verify the provider’s runtime permissions and use headless mode when no display is available.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.