> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zenrows.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrating ZenRows Scraping Browser with Playwright

> Step-by-step guide to connect ZenRows Scraping Browser with Playwright for Python and Node.js web scraping and browser automation.

Learn to extract data from any website using ZenRows' Scraping Browser with Playwright. This guide walks you through creating your first browser-based scraping request that can handle complex JavaScript-heavy sites with full browser automation.

ZenRows' Scraping Browser provides cloud-based Chrome instances you can control using Playwright. Whether dealing with dynamic content, complex user interactions, or sophisticated anti-bot protection, you can get started in minutes with Playwright's powerful automation capabilities.

## 1. Set Up Your Project

### Set Up Your Development Environment

Before diving in, ensure you have the proper development environment and Playwright installed. The Scraping Browser works seamlessly with both Python and Node.js versions of Playwright.

<Note>While previous versions may work, we recommend using the latest stable versions for optimal performance and security.</Note>

<Tabs>
  <Tab title="Python">
    Python 3+ installed (latest stable version recommended). Using an IDE like <a href="https://www.jetbrains.com/pycharm/" target="_blank" rel="noopener noreferrer nofollow">PyCharm</a> or <a href="https://code.visualstudio.com/docs/languages/python" target="_blank" rel="noopener noreferrer nofollow">Visual Studio Code</a> with the Python extension is recommended.

    ```bash theme={null}
    # Install Python (if not already installed)
    # Visit https://www.python.org/downloads/ or use package managers:

    # macOS (using Homebrew)
    brew install python

    # Ubuntu/Debian
    sudo apt update && sudo apt install python3 python3-pip

    # Windows (using Chocolatey)
    choco install python

    # Install Playwright
    pip install playwright
    playwright install
    ```

    <Tip>
      If you need help setting up your environment, check out our detailed [Playwright web scraping guide](https://www.zenrows.com/blog/playwright-scraping)
    </Tip>
  </Tab>

  <Tab title="Node.js">
    Node.js 18+ installed (latest LTS version recommended). Using an IDE like <a href="https://code.visualstudio.com/" target="_blank" rel="noopener noreferrer nofollow">Visual Studio Code</a> or <a href="https://www.jetbrains.com/idea/" target="_blank" rel="noopener noreferrer nofollow">IntelliJ IDEA</a> will enhance your coding experience.

    ```bash theme={null}
    # Install Node.js (if not already installed)
    # Visit https://nodejs.org/ or use package managers:

    # macOS (using Homebrew)
    brew install node

    # Ubuntu/Debian (using NodeSource)
    curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
    sudo apt-get install -y nodejs

    # Windows (using Chocolatey)
    choco install nodejs

    # Install Playwright
    npm install playwright
    npx playwright install
    ```

    <Tip>
      If you need help setting up your environment, check out our detailed [Playwright web scraping guide](https://www.zenrows.com/blog/playwright-scraping)
    </Tip>
  </Tab>
</Tabs>

### Get Your API Key and Connection URL

[Sign Up](https://app.zenrows.com/register?prod=scraping_browser) for a free ZenRows account and get your API key from the [Scraping Browser dashboard](https://app.zenrows.com/scraping-browser). You'll need this key to authenticate your WebSocket connection.

## 2. Make Your First Request

Start with a simple request to understand how the Scraping Browser works with Playwright. We'll use the <a href="https://www.scrapingcourse.com/ecommerce/" target="_blank" rel="noopener noreferrer nofollow">E-commerce Challenge</a> page to demonstrate how to connect to the browser and extract the page title.

<CodeGroup>
  ```python Python theme={null}
  # pip install playwright
  import asyncio
  from playwright.async_api import async_playwright

  # scraping browser connection URL
  connection_url = "wss://browser.zenrows.com?apikey=YOUR_ZENROWS_API_KEY"

  async def scraper():
      async with async_playwright() as p:
          # connect to the scraping browser
          browser = await p.chromium.connect_over_cdp(connection_url)
          context = browser.contexts[0] if browser.contexts else await browser.new_context()
          page = await context.new_page()
          
          await page.goto('https://www.scrapingcourse.com/ecommerce/')
          print(await page.title())
          
          await browser.close()

  if __name__ == "__main__":
      asyncio.run(scraper())
  ```

  ```javascript Node.js theme={null}
  // npm install playwright
  const { chromium } = require('playwright');

  // scraping browser connection URL
  const connectionURL = 'wss://browser.zenrows.com?apikey=YOUR_ZENROWS_API_KEY';

  const scraper = async () => {
      // connect to the scraping browser
      const browser = await chromium.connectOverCDP(connectionURL);
      const page = await browser.newPage();
      
      await page.goto('https://www.scrapingcourse.com/ecommerce/');
      console.log(await page.title());
      
      await browser.close();
  };

  scraper();
  ```
</CodeGroup>

Replace `YOUR_ZENROWS_API_KEY` with your actual API key and run the script:

<CodeGroup>
  ```bash Python theme={null}
  python scraper.py
  ```

  ```bash Node.js theme={null}
  node scraper.js
  ```
</CodeGroup>

### Expected Output

The script will print the page title:

```plaintext theme={null}
ScrapingCourse.com E-commerce Challenge
```

Perfect! You've just made your first web scraping request with the ZenRows Scraping Browser using Playwright.

## 3. Build a Real-World Scraping Scenario

Let's scale up to a practical scraping scenario by extracting product information from the e-commerce site. Using Playwright's powerful selectors and data extraction methods, we'll modify our code to extract product names, prices, and URLs from the page.

<CodeGroup>
  ```python Python theme={null}
  # pip install playwright
  import asyncio
  from playwright.async_api import async_playwright

  # scraping browser connection URL
  connection_url = "wss://browser.zenrows.com?apikey=YOUR_ZENROWS_API_KEY"

  async def scraper(url):
      async with async_playwright() as p:
          # connect to the scraping browser
          browser = await p.chromium.connect_over_cdp(connection_url)
          page = await browser.new_page()
          
          try:
              await page.goto(url)
              
              # extract the desired data
              await page.wait_for_selector(".product")
              products = await page.query_selector_all(".product")
              data = []
              
              for product in products:
                  name = await product.query_selector(".product-name")
                  price = await product.query_selector(".price")
                  product_url = await product.query_selector(".woocommerce-LoopProduct-link")
                  
                  data.append({
                      "name": await name.text_content() or "",
                      "price": await price.text_content() or "",
                      "productURL": await product_url.get_attribute("href") or "",
                  })
              
              return data
          except Exception as error:
              return error
          finally:
              await page.close()
              await browser.close()

  if __name__ == "__main__":
      url = "https://www.scrapingcourse.com/ecommerce/"
      products = asyncio.run(scraper(url))
      print(products)
  ```

  ```javascript Node.js theme={null}
  // npm install playwright
  const { chromium } = require('playwright');

  // connection URL
  const connectionURL = 'wss://browser.zenrows.com?apikey=YOUR_ZENROWS_API_KEY';

  const scraper = async (url) => {
      // connect to the scraping browser
      const browser = await chromium.connectOverCDP(connectionURL);
      const page = await browser.newPage();
      
      try {
          await page.goto(url);
          await page.waitForSelector('.product');
          
          // extract the desired data
          const data = await page.$$eval('.product', (products) =>
              products.map((product) => ({
                  name: product.querySelector('.product-name')?.textContent.trim() || '',
                  price: product.querySelector('.price')?.textContent.trim() || '',
                  productURL: product.querySelector('.woocommerce-LoopProduct-link')?.href || '',
              }))
          );
          
          return data;
      } finally {
          await page.close();
          await browser.close();
      }
  };

  // execute the scraper function
  (async () => {
      const url = 'https://www.scrapingcourse.com/ecommerce/';
      const products = await scraper(url);
      console.log(products);
  })();
  ```
</CodeGroup>

### Run Your Application

Execute your script to test the scraping functionality:

<CodeGroup>
  ```bash Python theme={null}
  python scraper.py
  ```

  ```bash Node.js theme={null}
  node scraper.js
  ```
</CodeGroup>

**Example Output**

The script will extract and display product information:

```json theme={null}
[
    {
        "name": "Abominable Hoodie",
        "price": "$69.00",
        "productURL": "https://www.scrapingcourse.com/ecommerce/product/abominable-hoodie/"
    },
    {
        "name": "Artemis Running Short",
        "price": "$45.00",
        "productURL": "https://www.scrapingcourse.com/ecommerce/product/artemis-running-short/"
    }
    // ... more products
]
```

Congratulations! 🎉 You've successfully built a real-world scraping scenario with Playwright and the ZenRows Scraping Browser.

## 4. Alternative: Using the ZenRows Browser SDK

For a more streamlined development experience, you can use the ZenRows Browser SDK instead of managing WebSocket URLs manually. The SDK simplifies connection management and provides additional utilities.

<Note>The ZenRows Browser SDK is currently only available for JavaScript. For more details, see the <a href="https://github.com/ZenRows/browser-js-sdk" target="_blank" rel="noopener noreferrer nofollow">GitHub Repository</a>.</Note>

### Install the SDK

```bash Node.js theme={null}
npm install @zenrows/browser-sdk
```

### Quick Migration from WebSocket URL

If you have existing Playwright code using the WebSocket connection, migrating to the SDK requires minimal changes:

**Before (WebSocket URL):**

```javascript Node.js theme={null}
const { chromium } = require('playwright');
const connectionURL = 'wss://browser.zenrows.com?apikey=YOUR_ZENROWS_API_KEY';

const browser = await chromium.connectOverCDP(connectionURL);
```

**After (SDK):**

```javascript Node.js theme={null}
const { chromium } = require('playwright');
const { ScrapingBrowser } = require('@zenrows/browser-sdk');

const scrapingBrowser = new ScrapingBrowser({ apiKey: 'YOUR_ZENROWS_API_KEY' });
const connectionURL = scrapingBrowser.getConnectURL();
const browser = await chromium.connectOverCDP(connectionURL);
```

### Complete Example with SDK

```javascript Node.js theme={null}
// npm install @zenrows/browser-sdk playwright
const { chromium } = require('playwright');
const { ScrapingBrowser } = require('@zenrows/browser-sdk');

const scraper = async () => {
    // Initialize SDK
    const scrapingBrowser = new ScrapingBrowser({ apiKey: 'YOUR_ZENROWS_API_KEY' });
    const connectionURL = scrapingBrowser.getConnectURL();
    
    const browser = await chromium.connectOverCDP(connectionURL);
    const page = await browser.newPage();
    
    await page.goto('https://www.scrapingcourse.com/ecommerce/');
    console.log(await page.title());
    
    await browser.close();
};

scraper();
```

### SDK Benefits

* **Simplified configuration:** No need to manually construct WebSocket URLs
* **Better error handling:** Built-in error messages and debugging information
* **Future-proof:** Automatic updates to connection protocols and endpoints
* **Additional utilities:** Access to helper methods and advanced configuration options

<Tip>The SDK is particularly useful for production environments where you want cleaner code organization and better error handling.</Tip>

## How Playwright with Scraping Browser Helps

Combining Playwright with ZenRows' Scraping Browser provides powerful advantages for web scraping:

### Key Benefits

* **Cloud-based browser instances:** Run Playwright scripts on remote Chrome instances, freeing up local resources for other tasks.

* **Seamless integration:** Connect your existing Playwright code to ZenRows with just a WebSocket URL change - no complex setup required.

* **Advanced automation:** Use Playwright's full feature set, which includes page interactions, form submissions, file uploads, and complex user workflows.

* **Built-in anti-detection:** Benefit from residential proxy rotation and genuine browser fingerprints automatically.

* **Cross-browser support:** While we use Chromium for optimal compatibility, Playwright's API remains consistent across different browser engines.

* **High concurrency:** Scale your Playwright scripts with up to 150 concurrent browser instances, depending on your plan.

* **Reliable execution:** Cloud infrastructure ensures consistent performance without local browser management overhead.

## Troubleshooting

Below are common issues you might encounter when using Playwright with the Scraping Browser:

<Steps>
  <Step title="Connection Refused">
    If you receive a Connection Refused error, it might be due to:

    * **API Key Issues:** Verify that you're using the correct API key.
    * **Network Issues:** Check your internet connection and firewall settings.
    * **WebSocket Endpoint:** Ensure that the WebSocket URL (`wss://browser.zenrows.com`) is correct.
  </Step>

  <Step title="Empty Data or Timeout Errors">
    * Use `page.waitForSelector()` to ensure elements load before extraction

    * Increase timeout values for slow-loading pages

      ```javascript scraper.js theme={null}
      await page.goto('https://example.com', { timeout: 60000 });  // 60 seconds
      ```

    * Verify CSS selectors are correct using browser developer tools

    * Add `page.waitForLoadState('networkidle')` for dynamic content
  </Step>

  <Step title="Browser Context Issues">
    * Use existing context when available: `browser.contexts[0] if browser.contexts else await browser.new_context()`
    * Properly close pages and browsers to prevent resource leaks
    * Handle exceptions properly to ensure cleanup occurs
  </Step>

  <Step title="Geolocation Blocks">
    Although ZenRows rotates IPs, some websites may block them based on location. Try adjusting the region or country settings.

    <Info>
      For more information, check our Scraping Browser [Region Documentation](https://docs.zenrows.com/scraping-browser/features/world-region) and [Country Documentation](https://docs.zenrows.com/scraping-browser/features/country).
    </Info>
  </Step>

  <Step title="Get Help From ZenRows Experts">
    Our support team is available to assist you if issues persist despite following these solutions. Use the [Scraping Browser dashboard](https://app.zenrows.com/scraping-browser) or <a href="mailto:success@zenrows.com">email us</a> for personalized help from ZenRows experts.
  </Step>
</Steps>

## Next Steps

You now have a solid foundation for Playwright-based web scraping with ZenRows. Here are some recommended next steps:

* **[Practical Use Cases](/scraping-browser/help/practical-use-cases)**: <br />Learn common scraping patterns, including screenshots, custom JavaScript execution, and form handling.
* **[Complete Scraping Browser Documentation](/scraping-browser/introduction)**: <br />Explore all available features and advanced configuration options for the Scraping Browser.
* **[Playwright Web Scraping Guide](https://www.zenrows.com/blog?q=playwright)**: <br />Dive deeper into Playwright techniques for sophisticated scraping scenarios.
* **[Pricing and Plans](/first-steps/pricing)**: <br />Understand how browser usage is calculated and choose the plan that fits your scraping volume.

## Frequently Asked Questions (FAQ)

<Accordion title="Can I use ZenRows® Scraping Browser with Puppeteer?">
  Yes, ZenRows Scraping Browser is compatible with Puppeteer as well. The integration is similar, requiring only a change in the connection method to utilize our WebSocket endpoint.
  <Tip>For detailed instructions, refer to our [Puppeteer Integration article](/scraping-browser/get-started/puppeteer).</Tip>
</Accordion>

<Accordion title="Do I need to configure proxies manually with ZenRows® Scraping Browser?">
  No, ZenRows Scraping Browser handles proxy configuration and IP rotation automatically. You don't need to set up proxies manually.
</Accordion>

<Accordion title="Can the Scraping Browser solve CAPTCHAs?">
  Currently, ZenRows® Scraping Browser does not support CAPTCHA solving. For handling CAPTCHAs, you may need to use third-party services.
  <Tip>Consider using our [Universal Scraper API](/universal-scraper-api/api-reference) for additional features like CAPTCHA solving, advanced anti-bot bypass, and more.</Tip>
</Accordion>

<Accordion title="Can I use all Playwright features with the Scraping Browser?">
  Yes! The Scraping Browser supports the full Playwright API. You can use page interactions, screenshots, PDF generation, network interception, and all other Playwright features seamlessly.
</Accordion>

<Accordion title="How do I handle multiple pages or tabs?">
  You can create multiple pages within the same browser context using `await browser.newPage()` or `await context.newPage()`. Each page operates independently while sharing the same browser session.
</Accordion>

<Accordion title="Can I use Playwright's built-in retry mechanisms?">
  Absolutely! Playwright's `expect()` assertions, `waitForSelector()`, and other built-in retry mechanisms work perfectly with the Scraping Browser. These features help handle dynamic content and improve scraping reliability.
</Accordion>

<Accordion title="How do I take screenshots with Playwright and Scraping Browser?">
  Use Playwright's standard screenshot methods:

  ```python theme={null}
      await page.screenshot(path='screenshot.png')
  ```

  The screenshot will be saved locally while the browser runs in the cloud.
</Accordion>

<Accordion title="Can I use Playwright's network interception features?">
  Yes! You can intercept requests, modify responses, and monitor network traffic using Playwright's `page.route()` and `page.on('request')` methods with the Scraping Browser.
</Accordion>

<Accordion title="What's the difference between using Playwright locally vs. with Scraping Browser?">
  The main difference is that the browser runs in ZenRows' cloud infrastructure instead of locally. This provides better IP rotation, fingerprint management, and resource efficiency while maintaining the exact same Playwright API.
</Accordion>

<Accordion title="How do I handle file downloads with Playwright and Scraping Browser?">
  File downloads work with Playwright's standard download handling. Use `page.waitForDownload()` and the download will be transferred from the cloud browser to your local environment automatically.
</Accordion>
