Table of contents

How to evaluate JavaScript expressions using Playwright?

Playwright's JavaScript evaluation capabilities allow you to execute JavaScript code directly in the browser context, making it essential for interacting with dynamic content, extracting data, and performing complex DOM operations.

Core Methods

page.evaluate()

Executes JavaScript and returns serializable values (strings, numbers, booleans, arrays, plain objects).

page.evaluateHandle()

Executes JavaScript and returns a handle to non-serializable objects (DOM elements, functions).

Basic Examples

Python - Simple Evaluation

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto("https://example.com")

    # Get page title
    title = page.evaluate("() => document.title")
    print(f"Title: {title}")

    # Get current URL
    url = page.evaluate("() => window.location.href")
    print(f"URL: {url}")

    browser.close()

JavaScript - Basic Usage

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');

  // Get page title
  const title = await page.evaluate(() => document.title);
  console.log(`Title: ${title}`);

  // Get viewport dimensions
  const viewport = await page.evaluate(() => ({
    width: window.innerWidth,
    height: window.innerHeight
  }));
  console.log(`Viewport: ${viewport.width}x${viewport.height}`);

  await browser.close();
})();

Passing Arguments

You can pass arguments from your script to the evaluated JavaScript:

Python - With Arguments

# Extract text content from multiple elements
selectors = ['h1', 'p', '.highlight']
results = page.evaluate("""
(selectors) => {
  const data = {};
  selectors.forEach(selector => {
    const elements = Array.from(document.querySelectorAll(selector));
    data[selector] = elements.map(el => el.textContent.trim());
  });
  return data;
}
""", selectors)

print(results)

JavaScript - With Arguments

// Get computed styles for elements
const selector = '.main-content';
const properties = ['color', 'font-size', 'background-color'];

const styles = await page.evaluate((sel, props) => {
  const element = document.querySelector(sel);
  if (!element) return null;

  const computedStyle = getComputedStyle(element);
  const result = {};
  props.forEach(prop => {
    result[prop] = computedStyle.getPropertyValue(prop);
  });
  return result;
}, selector, properties);

console.log(styles);

Advanced Use Cases

Data Extraction

// Extract structured data from a table
const tableData = await page.evaluate(() => {
  const table = document.querySelector('table');
  if (!table) return [];

  const headers = Array.from(table.querySelectorAll('th')).map(th => th.textContent.trim());
  const rows = Array.from(table.querySelectorAll('tbody tr')).map(row => {
    const cells = Array.from(row.querySelectorAll('td')).map(td => td.textContent.trim());
    const rowData = {};
    headers.forEach((header, index) => {
      rowData[header] = cells[index] || '';
    });
    return rowData;
  });

  return rows;
});

Waiting for Dynamic Content

# Wait for dynamic content and extract it
page.goto("https://dynamic-content-site.com")

# Wait for content to load and extract it
result = page.evaluate("""
() => {
  return new Promise((resolve) => {
    const checkContent = () => {
      const element = document.querySelector('.dynamic-content');
      if (element && element.textContent.trim()) {
        resolve(element.textContent.trim());
      } else {
        setTimeout(checkContent, 100);
      }
    };
    checkContent();
  });
}
""")

print(f"Dynamic content: {result}")

Using evaluateHandle() for DOM Elements

When you need to work with DOM elements directly:

// Get element handle and interact with it
const elementHandle = await page.evaluateHandle(() => 
  document.querySelector('input[type="text"]')
);

if (elementHandle) {
  await elementHandle.fill('Hello World');
  await elementHandle.press('Enter');
  elementHandle.dispose(); // Clean up the handle
}

Error Handling

try:
    result = page.evaluate("""
    () => {
      const element = document.querySelector('.non-existent');
      if (!element) {
        throw new Error('Element not found');
      }
      return element.textContent;
    }
    """)
except Exception as e:
    print(f"JavaScript evaluation failed: {e}")

Best Practices

  1. Serialization Limits: evaluate() only returns serializable data. Use evaluateHandle() for DOM elements or functions.

  2. Error Handling: Always wrap evaluation code in try-catch blocks, both in JavaScript and your main script.

  3. Performance: Minimize DOM queries by batching operations in a single evaluation.

  4. Security: Never evaluate untrusted user input directly. Validate and sanitize data before evaluation.

  5. Memory Management: Dispose of handles created by evaluateHandle() to prevent memory leaks.

// Good: Batch multiple operations
const pageData = await page.evaluate(() => ({
  title: document.title,
  url: window.location.href,
  links: Array.from(document.querySelectorAll('a')).map(a => ({
    text: a.textContent.trim(),
    href: a.href
  })),
  meta: Array.from(document.querySelectorAll('meta')).map(meta => ({
    name: meta.name || meta.property,
    content: meta.content
  }))
}));

This comprehensive approach to JavaScript evaluation makes Playwright a powerful tool for web scraping, testing, and automation tasks that require deep interaction with web page content.

Try WebScraping.AI for Your Web Scraping Needs

Looking for a powerful web scraping solution? WebScraping.AI provides an LLM-powered API that combines Chromium JavaScript rendering with rotating proxies for reliable data extraction.

Key Features:

  • AI-powered extraction: Ask questions about web pages or extract structured data fields
  • JavaScript rendering: Full Chromium browser support for dynamic content
  • Rotating proxies: Datacenter and residential proxies from multiple countries
  • Easy integration: Simple REST API with SDKs for Python, Ruby, PHP, and more
  • Reliable & scalable: Built for developers who need consistent results

Getting Started:

Get page content with AI analysis:

curl "https://api.webscraping.ai/ai/question?url=https://example.com&question=What is the main topic?&api_key=YOUR_API_KEY"

Extract structured data:

curl "https://api.webscraping.ai/ai/fields?url=https://example.com&fields[title]=Page title&fields[price]=Product price&api_key=YOUR_API_KEY"

Try in request builder

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon