playwright-browser

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Playwright Browser Automation

Playwright浏览器自动化

Use this skill for capturing screenshots, web scraping, form automation, and browser-based testing.
本技能可用于截图捕获、网页爬取、表单自动化以及浏览器端测试。

Quick Start

快速开始

The project's venv has Playwright installed. Always use the venv Python:
bash
undefined
项目的venv环境已安装Playwright。请始终使用venv中的Python:
bash
undefined

Run Playwright scripts

Run Playwright scripts

.venv/bin/python scripts/my_playwright_script.py
.venv/bin/python scripts/my_playwright_script.py

Install browsers if needed (one-time)

Install browsers if needed (one-time)

.venv/bin/playwright install chromium
undefined
.venv/bin/playwright install chromium
undefined

Screenshot Capture

截图捕获

Basic Screenshot

基础截图

python
#!/Users/arun/dev/agents_webinar/.venv/bin/python
from playwright.sync_api import sync_playwright

def capture_screenshot(url: str, output_path: str) -> str:
    """Capture a screenshot of a webpage.

    Args:
        url: URL to capture
        output_path: Path to save PNG file

    Returns:
        Path to saved screenshot
    """
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page(viewport={'width': 1280, 'height': 800})
        page.goto(url, wait_until='networkidle')
        page.screenshot(path=output_path)
        browser.close()
    return output_path
python
#!/Users/arun/dev/agents_webinar/.venv/bin/python
from playwright.sync_api import sync_playwright

def capture_screenshot(url: str, output_path: str) -> str:
    """Capture a screenshot of a webpage.

    Args:
        url: URL to capture
        output_path: Path to save PNG file

    Returns:
        Path to saved screenshot
    """
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page(viewport={'width': 1280, 'height': 800})
        page.goto(url, wait_until='networkidle')
        page.screenshot(path=output_path)
        browser.close()
    return output_path

Usage

Usage

capture_screenshot('https://example.com', 'screenshot.png')
undefined
capture_screenshot('https://example.com', 'screenshot.png')
undefined

Full Page Screenshot

整页截图

python
def capture_full_page(url: str, output_path: str) -> str:
    """Capture full-page screenshot (scrolls entire page)."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page(viewport={'width': 1280, 'height': 800})
        page.goto(url, wait_until='networkidle')
        page.screenshot(path=output_path, full_page=True)
        browser.close()
    return output_path
python
def capture_full_page(url: str, output_path: str) -> str:
    """Capture full-page screenshot (scrolls entire page)."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page(viewport={'width': 1280, 'height': 800})
        page.goto(url, wait_until='networkidle')
        page.screenshot(path=output_path, full_page=True)
        browser.close()
    return output_path

Above-the-Fold Screenshot

首屏截图

python
def capture_above_fold(url: str, output_path: str, width: int = 1280, height: int = 800) -> str:
    """Capture only the visible viewport (above-the-fold content)."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page(viewport={'width': width, 'height': height})
        page.goto(url, wait_until='networkidle')
        # Viewport screenshot (not full_page)
        page.screenshot(path=output_path, full_page=False)
        browser.close()
    return output_path
python
def capture_above_fold(url: str, output_path: str, width: int = 1280, height: int = 800) -> str:
    """Capture only the visible viewport (above-the-fold content)."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page(viewport={'width': width, 'height': height})
        page.goto(url, wait_until='networkidle')
        # Viewport screenshot (not full_page)
        page.screenshot(path=output_path, full_page=False)
        browser.close()
    return output_path

Element Screenshot

元素截图

python
def capture_element(url: str, selector: str, output_path: str) -> str:
    """Capture screenshot of a specific element."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url, wait_until='networkidle')
        element = page.locator(selector)
        element.screenshot(path=output_path)
        browser.close()
    return output_path
python
def capture_element(url: str, selector: str, output_path: str) -> str:
    """Capture screenshot of a specific element."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url, wait_until='networkidle')
        element = page.locator(selector)
        element.screenshot(path=output_path)
        browser.close()
    return output_path

Usage

Usage

capture_element('https://example.com', 'header.hero', 'hero_section.png')
undefined
capture_element('https://example.com', 'header.hero', 'hero_section.png')
undefined

Async API (Recommended for Multiple Pages)

异步API(多页面场景推荐)

python
#!/Users/arun/dev/agents_webinar/.venv/bin/python
import asyncio
from playwright.async_api import async_playwright

async def capture_multiple_pages(urls: list[str], output_dir: str) -> list[str]:
    """Capture screenshots of multiple pages concurrently."""
    async with async_playwright() as p:
        browser = await p.chromium.launch()

        async def capture_one(url: str) -> str:
            page = await browser.new_page(viewport={'width': 1280, 'height': 800})
            await page.goto(url, wait_until='networkidle')
            filename = url.replace('https://', '').replace('/', '_') + '.png'
            path = f"{output_dir}/{filename}"
            await page.screenshot(path=path)
            await page.close()
            return path

        results = await asyncio.gather(*[capture_one(url) for url in urls])
        await browser.close()
    return results
python
#!/Users/arun/dev/agents_webinar/.venv/bin/python
import asyncio
from playwright.async_api import async_playwright

async def capture_multiple_pages(urls: list[str], output_dir: str) -> list[str]:
    """Capture screenshots of multiple pages concurrently."""
    async with async_playwright() as p:
        browser = await p.chromium.launch()

        async def capture_one(url: str) -> str:
            page = await browser.new_page(viewport={'width': 1280, 'height': 800})
            await page.goto(url, wait_until='networkidle')
            filename = url.replace('https://', '').replace('/', '_') + '.png'
            path = f"{output_dir}/{filename}"
            await page.screenshot(path=path)
            await page.close()
            return path

        results = await asyncio.gather(*[capture_one(url) for url in urls])
        await browser.close()
    return results

Usage

Usage

asyncio.run(capture_multiple_pages([ 'https://example.com', 'https://example.com/pricing', 'https://example.com/about' ], 'screenshots'))
undefined
asyncio.run(capture_multiple_pages([ 'https://example.com', 'https://example.com/pricing', 'https://example.com/about' ], 'screenshots'))
undefined

Wait Strategies

等待策略

Wait Until Options

等待选项

python
undefined
python
undefined

'load' - Wait for load event (default)

'load' - Wait for load event (default)

page.goto(url, wait_until='load')
page.goto(url, wait_until='load')

'domcontentloaded' - Wait for DOMContentLoaded

'domcontentloaded' - Wait for DOMContentLoaded

page.goto(url, wait_until='domcontentloaded')
page.goto(url, wait_until='domcontentloaded')

'networkidle' - Wait until no network requests for 500ms (RECOMMENDED)

'networkidle' - Wait until no network requests for 500ms (RECOMMENDED)

page.goto(url, wait_until='networkidle')
page.goto(url, wait_until='networkidle')

'commit' - Wait for first byte of response

'commit' - Wait for first byte of response

page.goto(url, wait_until='commit')
undefined
page.goto(url, wait_until='commit')
undefined

Wait for Specific Elements

等待特定元素

python
undefined
python
undefined

Wait for element to be visible

Wait for element to be visible

page.wait_for_selector('.hero-cta', state='visible')
page.wait_for_selector('.hero-cta', state='visible')

Wait for element to be hidden

Wait for element to be hidden

page.wait_for_selector('.loading-spinner', state='hidden')
page.wait_for_selector('.loading-spinner', state='hidden')

Wait with timeout

Wait with timeout

page.wait_for_selector('.lazy-loaded-content', timeout=10000) # 10 seconds
undefined
page.wait_for_selector('.lazy-loaded-content', timeout=10000) # 10 seconds
undefined

Wait for Network Idle After Interaction

交互后等待网络空闲

python
undefined
python
undefined

Click and wait for network to settle

Click and wait for network to settle

page.click('button.load-more') page.wait_for_load_state('networkidle')
page.click('button.load-more') page.wait_for_load_state('networkidle')

Then capture

Then capture

page.screenshot(path='after_load_more.png')
undefined
page.screenshot(path='after_load_more.png')
undefined

Element Selection

元素选择

Locator Strategies

定位器策略

python
undefined
python
undefined

CSS selector (most common)

CSS selector (most common)

page.locator('button.cta') page.locator('#signup-form') page.locator('[data-testid="hero-section"]')
page.locator('button.cta') page.locator('#signup-form') page.locator('[data-testid="hero-section"]')

Text content

Text content

page.locator('text=Sign Up Now') page.get_by_text('Get Started')
page.locator('text=Sign Up Now') page.get_by_text('Get Started')

Role-based (accessibility)

Role-based (accessibility)

page.get_by_role('button', name='Submit') page.get_by_role('link', name='Pricing')
page.get_by_role('button', name='Submit') page.get_by_role('link', name='Pricing')

Label (forms)

Label (forms)

page.get_by_label('Email address')
page.get_by_label('Email address')

Placeholder

Placeholder

page.get_by_placeholder('Enter your email')
page.get_by_placeholder('Enter your email')

Chained selectors

Chained selectors

page.locator('form').locator('button[type="submit"]')
undefined
page.locator('form').locator('button[type="submit"]')
undefined

Extract Text Content

提取文本内容

python
def extract_page_content(url: str) -> dict:
    """Extract key text content from a page."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url, wait_until='networkidle')

        content = {
            'title': page.title(),
            'h1': page.locator('h1').first.text_content() if page.locator('h1').count() > 0 else None,
            'meta_description': page.locator('meta[name="description"]').get_attribute('content'),
            'cta_buttons': [btn.text_content() for btn in page.locator('a.cta, button.cta').all()],
        }

        browser.close()
    return content
python
def extract_page_content(url: str) -> dict:
    """Extract key text content from a page."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url, wait_until='networkidle')

        content = {
            'title': page.title(),
            'h1': page.locator('h1').first.text_content() if page.locator('h1').count() > 0 else None,
            'meta_description': page.locator('meta[name="description"]').get_attribute('content'),
            'cta_buttons': [btn.text_content() for btn in page.locator('a.cta, button.cta').all()],
        }

        browser.close()
    return content

Form Automation

表单自动化

Fill and Submit Form

填写并提交表单

python
def fill_form(url: str, form_data: dict) -> str:
    """Fill out a form and capture result."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url, wait_until='networkidle')

        # Fill text fields
        page.fill('input[name="email"]', form_data['email'])
        page.fill('input[name="company"]', form_data['company'])

        # Select dropdown
        page.select_option('select[name="country"]', form_data['country'])

        # Check checkbox
        page.check('input[name="agree_terms"]')

        # Click submit
        page.click('button[type="submit"]')

        # Wait for navigation/result
        page.wait_for_load_state('networkidle')

        # Capture result
        page.screenshot(path='form_result.png')
        browser.close()
    return 'form_result.png'
python
def fill_form(url: str, form_data: dict) -> str:
    """Fill out a form and capture result."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url, wait_until='networkidle')

        # Fill text fields
        page.fill('input[name="email"]', form_data['email'])
        page.fill('input[name="company"]', form_data['company'])

        # Select dropdown
        page.select_option('select[name="country"]', form_data['country'])

        # Check checkbox
        page.check('input[name="agree_terms"]')

        # Click submit
        page.click('button[type="submit"]')

        # Wait for navigation/result
        page.wait_for_load_state('networkidle')

        # Capture result
        page.screenshot(path='form_result.png')
        browser.close()
    return 'form_result.png'

Mobile Screenshots

移动端截图

python
from playwright.sync_api import sync_playwright

def capture_mobile(url: str, output_path: str) -> str:
    """Capture screenshot with mobile viewport."""
    with sync_playwright() as p:
        # Use iPhone 12 device profile
        iphone = p.devices['iPhone 12']
        browser = p.chromium.launch()
        context = browser.new_context(**iphone)
        page = context.new_page()
        page.goto(url, wait_until='networkidle')
        page.screenshot(path=output_path)
        browser.close()
    return output_path
python
from playwright.sync_api import sync_playwright

def capture_mobile(url: str, output_path: str) -> str:
    """Capture screenshot with mobile viewport."""
    with sync_playwright() as p:
        # Use iPhone 12 device profile
        iphone = p.devices['iPhone 12']
        browser = p.chromium.launch()
        context = browser.new_context(**iphone)
        page = context.new_page()
        page.goto(url, wait_until='networkidle')
        page.screenshot(path=output_path)
        browser.close()
    return output_path

Available device profiles include:

Available device profiles include:

'iPhone 12', 'iPhone 12 Pro Max', 'iPhone SE'

'iPhone 12', 'iPhone 12 Pro Max', 'iPhone SE'

'iPad Pro', 'iPad Mini'

'iPad Pro', 'iPad Mini'

'Pixel 5', 'Galaxy S9+'

'Pixel 5', 'Galaxy S9+'

'Desktop Chrome', 'Desktop Firefox', 'Desktop Safari'

'Desktop Chrome', 'Desktop Firefox', 'Desktop Safari'

undefined
undefined

PDF Generation

PDF生成

python
def generate_pdf(url: str, output_path: str) -> str:
    """Generate PDF from webpage (Chromium only)."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url, wait_until='networkidle')
        page.pdf(
            path=output_path,
            format='A4',
            print_background=True,
            margin={'top': '1cm', 'bottom': '1cm', 'left': '1cm', 'right': '1cm'}
        )
        browser.close()
    return output_path
python
def generate_pdf(url: str, output_path: str) -> str:
    """Generate PDF from webpage (Chromium only)."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url, wait_until='networkidle')
        page.pdf(
            path=output_path,
            format='A4',
            print_background=True,
            margin={'top': '1cm', 'bottom': '1cm', 'left': '1cm', 'right': '1cm'}
        )
        browser.close()
    return output_path

Error Handling

错误处理

python
from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeout

def safe_capture(url: str, output_path: str, timeout: int = 30000) -> dict:
    """Capture with comprehensive error handling."""
    result = {'success': False, 'path': None, 'error': None}

    try:
        with sync_playwright() as p:
            browser = p.chromium.launch()
            page = browser.new_page(viewport={'width': 1280, 'height': 800})

            response = page.goto(url, wait_until='networkidle', timeout=timeout)

            if response and response.status >= 400:
                result['error'] = f"HTTP {response.status}"
            else:
                page.screenshot(path=output_path)
                result['success'] = True
                result['path'] = output_path

            browser.close()

    except PlaywrightTimeout:
        result['error'] = f"Timeout after {timeout}ms"
    except Exception as e:
        result['error'] = str(e)

    return result
python
from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeout

def safe_capture(url: str, output_path: str, timeout: int = 30000) -> dict:
    """Capture with comprehensive error handling."""
    result = {'success': False, 'path': None, 'error': None}

    try:
        with sync_playwright() as p:
            browser = p.chromium.launch()
            page = browser.new_page(viewport={'width': 1280, 'height': 800})

            response = page.goto(url, wait_until='networkidle', timeout=timeout)

            if response and response.status >= 400:
                result['error'] = f"HTTP {response.status}"
            else:
                page.screenshot(path=output_path)
                result['success'] = True
                result['path'] = output_path

            browser.close()

    except PlaywrightTimeout:
        result['error'] = f"Timeout after {timeout}ms"
    except Exception as e:
        result['error'] = str(e)

    return result

Performance Tips

性能优化技巧

1. Reuse Browser Instance

1. 复用浏览器实例

python
undefined
python
undefined

Bad: Launch browser for each page

Bad: Launch browser for each page

for url in urls: with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() page.goto(url) page.screenshot(...) browser.close()
for url in urls: with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() page.goto(url) page.screenshot(...) browser.close()

Good: Reuse browser

Good: Reuse browser

with sync_playwright() as p: browser = p.chromium.launch() for url in urls: page = browser.new_page() page.goto(url) page.screenshot(...) page.close() # Close page, not browser browser.close()
undefined
with sync_playwright() as p: browser = p.chromium.launch() for url in urls: page = browser.new_page() page.goto(url) page.screenshot(...) page.close() # Close page, not browser browser.close()
undefined

2. Disable Unnecessary Resources

2. 禁用非必要资源

python
def fast_capture(url: str, output_path: str) -> str:
    """Fast capture by blocking non-essential resources."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        context = browser.new_context()

        # Block images, fonts, stylesheets for faster load
        context.route('**/*.{png,jpg,jpeg,gif,svg,woff,woff2,ttf}',
                     lambda route: route.abort())

        page = context.new_page()
        page.goto(url, wait_until='domcontentloaded')
        page.screenshot(path=output_path)
        browser.close()
    return output_path
python
def fast_capture(url: str, output_path: str) -> str:
    """Fast capture by blocking non-essential resources."""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        context = browser.new_context()

        # Block images, fonts, stylesheets for faster load
        context.route('**/*.{png,jpg,jpeg,gif,svg,woff,woff2,ttf}',
                     lambda route: route.abort())

        page = context.new_page()
        page.goto(url, wait_until='domcontentloaded')
        page.screenshot(path=output_path)
        browser.close()
    return output_path

3. Headless vs Headed Mode

3. 无头模式与有头模式

python
undefined
python
undefined

Headless (default, faster, no UI)

Headless (default, faster, no UI)

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

Headed (shows browser, useful for debugging)

Headed (shows browser, useful for debugging)

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

Slow motion (for demos)

Slow motion (for demos)

browser = p.chromium.launch(headless=False, slow_mo=500) # 500ms between actions
undefined
browser = p.chromium.launch(headless=False, slow_mo=500) # 500ms between actions
undefined

CRO Analysis Pattern (Demo 6)

CRO分析模式(演示6)

python
#!/Users/arun/dev/agents_webinar/.venv/bin/python
"""Capture landing page for CRO analysis."""

from playwright.sync_api import sync_playwright
import json

def capture_for_cro_analysis(url: str, output_dir: str) -> dict:
    """Capture screenshots and metadata for CRO analysis.

    Returns dict with paths to:
    - above_fold.png: What users see first
    - full_page.png: Complete page
    - metadata.json: Page info (title, CTAs, etc.)
    """
    with sync_playwright() as p:
        browser = p.chromium.launch()

        # Desktop viewport
        page = browser.new_page(viewport={'width': 1280, 'height': 800})
        page.goto(url, wait_until='networkidle')

        # Above-the-fold
        above_fold_path = f"{output_dir}/above_fold.png"
        page.screenshot(path=above_fold_path, full_page=False)

        # Full page
        full_page_path = f"{output_dir}/full_page.png"
        page.screenshot(path=full_page_path, full_page=True)

        # Extract metadata
        metadata = {
            'url': url,
            'title': page.title(),
            'h1': page.locator('h1').first.text_content() if page.locator('h1').count() > 0 else None,
            'cta_count': page.locator('a.cta, button.cta, [class*="cta"], [class*="btn-primary"]').count(),
            'form_count': page.locator('form').count(),
            'image_count': page.locator('img').count(),
        }

        metadata_path = f"{output_dir}/metadata.json"
        with open(metadata_path, 'w') as f:
            json.dump(metadata, f, indent=2)

        browser.close()

    return {
        'above_fold': above_fold_path,
        'full_page': full_page_path,
        'metadata': metadata_path
    }

if __name__ == '__main__':
    import sys
    url = sys.argv[1] if len(sys.argv) > 1 else 'https://www.reform.app/done-for-you-forms'
    output_dir = sys.argv[2] if len(sys.argv) > 2 else 'demos/06-vision-audit/outputs'

    result = capture_for_cro_analysis(url, output_dir)
    print(f"Captured: {result}")
python
#!/Users/arun/dev/agents_webinar/.venv/bin/python
"""Capture landing page for CRO analysis."""

from playwright.sync_api import sync_playwright
import json

def capture_for_cro_analysis(url: str, output_dir: str) -> dict:
    """Capture screenshots and metadata for CRO analysis.

    Returns dict with paths to:
    - above_fold.png: What users see first
    - full_page.png: Complete page
    - metadata.json: Page info (title, CTAs, etc.)
    """
    with sync_playwright() as p:
        browser = p.chromium.launch()

        # Desktop viewport
        page = browser.new_page(viewport={'width': 1280, 'height': 800})
        page.goto(url, wait_until='networkidle')

        # Above-the-fold
        above_fold_path = f"{output_dir}/above_fold.png"
        page.screenshot(path=above_fold_path, full_page=False)

        # Full page
        full_page_path = f"{output_dir}/full_page.png"
        page.screenshot(path=full_page_path, full_page=True)

        # Extract metadata
        metadata = {
            'url': url,
            'title': page.title(),
            'h1': page.locator('h1').first.text_content() if page.locator('h1').count() > 0 else None,
            'cta_count': page.locator('a.cta, button.cta, [class*="cta"], [class*="btn-primary"]').count(),
            'form_count': page.locator('form').count(),
            'image_count': page.locator('img').count(),
        }

        metadata_path = f"{output_dir}/metadata.json"
        with open(metadata_path, 'w') as f:
            json.dump(metadata, f, indent=2)

        browser.close()

    return {
        'above_fold': above_fold_path,
        'full_page': full_page_path,
        'metadata': metadata_path
    }

if __name__ == '__main__':
    import sys
    url = sys.argv[1] if len(sys.argv) > 1 else 'https://www.reform.app/done-for-you-forms'
    output_dir = sys.argv[2] if len(sys.argv) > 2 else 'demos/06-vision-audit/outputs'

    result = capture_for_cro_analysis(url, output_dir)
    print(f"Captured: {result}")

Troubleshooting

故障排除

"Browser not found"

"浏览器未找到"

bash
undefined
bash
undefined

Install Chromium browser

Install Chromium browser

.venv/bin/playwright install chromium
.venv/bin/playwright install chromium

Or install all browsers

Or install all browsers

.venv/bin/playwright install
undefined
.venv/bin/playwright install
undefined

"Timeout waiting for page"

"页面等待超时"

python
undefined
python
undefined

Increase timeout

Increase timeout

page.goto(url, timeout=60000) # 60 seconds
page.goto(url, timeout=60000) # 60 seconds

Or use less strict wait

Or use less strict wait

page.goto(url, wait_until='domcontentloaded') # Faster than 'networkidle'
undefined
page.goto(url, wait_until='domcontentloaded') # Faster than 'networkidle'
undefined

"Element not found"

"元素未找到"

python
undefined
python
undefined

Check if element exists first

Check if element exists first

if page.locator('.cta-button').count() > 0: page.locator('.cta-button').click() else: print("CTA button not found")
undefined
if page.locator('.cta-button').count() > 0: page.locator('.cta-button').click() else: print("CTA button not found")
undefined

SSL/Certificate Errors

SSL/证书错误

python
undefined
python
undefined

Ignore HTTPS errors (use cautiously)

Ignore HTTPS errors (use cautiously)

context = browser.new_context(ignore_https_errors=True)
undefined
context = browser.new_context(ignore_https_errors=True)
undefined

Quick Reference

快速参考

Screenshot types:
  • page.screenshot(path='file.png')
    - Viewport only
  • page.screenshot(path='file.png', full_page=True)
    - Full scrollable page
  • element.screenshot(path='file.png')
    - Specific element
Wait strategies:
  • wait_until='networkidle'
    - Most reliable for dynamic pages
  • wait_until='domcontentloaded'
    - Faster, for static pages
  • page.wait_for_selector('.class')
    - Wait for specific element
Viewport sizes:
  • Desktop: 1280x800 or 1920x1080
  • Tablet: 768x1024
  • Mobile: Use
    p.devices['iPhone 12']
Best practices:
  1. Always use
    with sync_playwright()
    context manager
  2. Use
    wait_until='networkidle'
    for JS-heavy pages
  3. Close pages/browsers to free resources
  4. Handle timeouts gracefully
  5. Use async API for multiple concurrent captures
截图类型:
  • page.screenshot(path='file.png')
    - 仅视口区域
  • page.screenshot(path='file.png', full_page=True)
    - 完整可滚动页面
  • element.screenshot(path='file.png')
    - 特定元素
等待策略:
  • wait_until='networkidle'
    - 动态页面最可靠
  • wait_until='domcontentloaded'
    - 速度更快,适用于静态页面
  • page.wait_for_selector('.class')
    - 等待特定元素
视口尺寸:
  • 桌面端:1280x800 或 1920x1080
  • 平板端:768x1024
  • 移动端:使用
    p.devices['iPhone 12']
最佳实践:
  1. 始终使用
    with sync_playwright()
    上下文管理器
  2. 针对JS重页面使用
    wait_until='networkidle'
  3. 关闭页面/浏览器以释放资源
  4. 优雅处理超时
  5. 多页面并发捕获使用异步API