> ## 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 Puppeteer

> Step-by-step tutorial for integrating ZenRows Scraping Browser with Puppeteer in Node.js and Pyppeteer in Python for web scraping.

Discover how to scrape data from any website using ZenRows' Scraping Browser with Puppeteer. This comprehensive guide demonstrates how to create your first browser automation request capable of handling JavaScript-heavy sites and bypassing sophisticated anti-bot measures.

ZenRows' Scraping Browser offers cloud-hosted Chrome instances that integrate seamlessly with Puppeteer's automation framework. From scraping dynamic content to performing complex browser interactions, you can build robust scraping solutions in minutes using Puppeteer's intuitive API.

## 1. Set Up Your Project

### Set Up Your Development Environment

Ensure you have the necessary development tools and Puppeteer installed before starting. The Scraping Browser supports both Node.js Puppeteer and Python Pyppeteer implementations.

<Note>We recommend using the latest stable versions to ensure optimal compatibility and access to the newest features.</Note>

<Tabs>
  <Tab title="Node.js">
    Node.js 18+ installed (latest LTS version recommended). Consider 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/webstorm/" target="_blank" rel="noopener noreferrer nofollow">WebStorm</a> for enhanced development 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 Puppeteer Core
        npm install puppeteer-core
    ```

    <Tip>
      Need help with your setup? Check out our comprehensive [Puppeteer web scraping guide](https://www.zenrows.com/blog/puppeteer-web-scraping)
    </Tip>
  </Tab>

  <Tab title="Python">
    Python 3+ installed (latest stable version recommended). IDEs 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 Python extensions provide excellent development support.

    ```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 Pyppeteer
    pip install pyppeteer
     
    ```

    <Tip>
      For detailed setup instructions, refer to our [Pyppeteer scraping tutorial](https://www.zenrows.com/blog/pyppeteer)
    </Tip>
  </Tab>
</Tabs>

### Get Your API Key and Connection URL

[Create a Free Account](https://app.zenrows.com/register?prod=scraping_browser) with ZenRows and retrieve your API key from the [Scraping Browser Dashboard](https://app.zenrows.com/scraping-browser). This key authenticates your WebSocket connection to our cloud browsers.

## 2. Make Your First Request

Begin with a basic request to familiarize yourself with how Puppeteer connects to the Scraping Browser. We'll target the <a href="https://www.scrapingcourse.com/ecommerce/" target="_blank" rel="noopener noreferrer nofollow">E-commerce Challenge</a> page to demonstrate browser connection and title extraction.

<CodeGroup>
  ```javascript Node.js theme={null}
  // npm install puppeteer-core
  const puppeteer = require('puppeteer-core');
  // 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 puppeteer.connect({ browserWSEndpoint: connectionURL });
      const page = await browser.newPage();
      
      await page.goto('https://www.scrapingcourse.com/ecommerce/');
      console.log(await page.title());
      
      await browser.close();
  };

  scraper();
  ```

  ```python Python theme={null}
  # pip install pyppeteer
  import asyncio
  from pyppeteer import connect

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

  async def scraper():
      # connect to the scraping browser
      browser = await connect(browserWSEndpoint=connection_url)
      page = await browser.newPage()
      
      await page.goto('https://www.scrapingcourse.com/ecommerce/')
      print(await page.title())
      
      await page.close()
      await browser.disconnect()

  if __name__ == "__main__":
      asyncio.run(scraper())
  ```
</CodeGroup>

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

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

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

**Expected Output:**

Your script will display the page title:

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

Excellent! You've successfully completed your first web scraping request using ZenRows Scraping Browser with Puppeteer.

## 3. Build a Real-World Scraping Scenario

Now let's advance to a comprehensive scraping example by extracting product data from the e-commerce site. We'll enhance our code to collect product names, prices, and URLs using Puppeteer's robust element selection and data extraction capabilities.

<CodeGroup>
  ```javascript Node.js theme={null}
  // npm install puppeteer-core
  const puppeteer = require('puppeteer-core');

  // scraping browser 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 puppeteer.connect({
          browserWSEndpoint: connectionURL,
      });
      const page = await browser.newPage();
      
      try {
          await page.goto(url, { waitUntil: 'networkidle2' });
          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);
  })();
  ```

  ```python Python theme={null}
  # pip install pyppeteer
  import asyncio
  from pyppeteer import connect

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

  async def scraper(url):
      # connect to the scraping browser
      browser = await connect(browserWSEndpoint=connection_url)
      page = await browser.newPage()
      
      try:
          await page.goto(url, {"waitUntil": "networkidle2"})
          await page.waitForSelector(".product")
          
          # extract the desired data
          product_elements = await page.querySelectorAll(".product")
          products = []
          
          for product in product_elements:
              name_el = await product.querySelector(".product-name")
              name = await page.evaluate("(el) => el.textContent.trim()", name_el) if name_el else ""
              
              price_el = await product.querySelector(".price")
              price = await page.evaluate("(el) => el.textContent.trim()", price_el) if price_el else ""
              
              url_el = await product.querySelector(".woocommerce-LoopProduct-link")
              product_url = await page.evaluate("(el) => el.href", url_el) if url_el else ""
              
              products.append({
                  "name": name,
                  "price": price,
                  "productURL": product_url,
              })
          
          return products
      finally:
          await page.close()
          await browser.disconnect()

  # execute the scraper function
  if __name__ == "__main__":
      url = "https://www.scrapingcourse.com/ecommerce/"
      products = asyncio.run(scraper(url))
      print(products)
  ```
</CodeGroup>

### Run Your Application

Launch your script to verify the scraping functionality:

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

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

**Example Output:**

Your script will collect and display the 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/"
    }
    // ... additional products
]
```

Outstanding! 🎉 You've successfully implemented a production-ready scraping solution using Puppeteer and the ZenRows Scraping Browser.

## 4. Alternative: Using the ZenRows Browser SDK

For enhanced developer experience, consider using the ZenRows Browser SDK rather than manually managing WebSocket URLs. The SDK streamlines connection handling and offers additional development 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

Transitioning from direct WebSocket connections to the SDK requires minimal code changes:

**Before (WebSocket URL):**

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

const browser = await puppeteer.connect({ browserWSEndpoint: connectionURL });
```

**After (SDK):**

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

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

### Complete Example with SDK

```javascript Node.js theme={null}
// npm install @zenrows/browser-sdk puppeteer-core
const puppeteer = require('puppeteer-core');
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 puppeteer.connect({ browserWSEndpoint: 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

* **Streamlined configuration:** Eliminates manual WebSocket URL construction
* **Enhanced error handling:** Provides detailed error messages and debugging capabilities
* **Future-proof architecture:** Automatic updates to connection protocols and endpoints
* **Extended utilities:** Access to helper functions and advanced configuration options

<Tip>The SDK proves especially valuable in production environments where code maintainability and robust error handling are priorities.</Tip>

## How Puppeteer with Scraping Browser Helps

Integrating Puppeteer with ZenRows' Scraping Browser delivers significant advantages for web automation:

### Key Benefits

* **Cloud-hosted browser instances:** Execute Puppeteer scripts on remote Chrome browsers, preserving local system resources for other applications.
* **Drop-in replacement:** Transform existing Puppeteer code to use ZenRows by simply changing the connection method - no architectural changes required.
* **Full automation capabilities:** Leverage Puppeteer's complete feature set including form interactions, file handling, network monitoring, and custom JavaScript execution.
* **Automatic anti-detection:** Benefit from built-in residential proxy rotation and authentic browser fingerprints without additional configuration.
* **Proven reliability:** Cloud infrastructure delivers consistent performance without the complexity of local browser management.
* **Massive scalability:** Execute up to 150 concurrent browser instances depending on your subscription plan.
* **Network optimization:** Reduced latency and improved success rates through globally distributed infrastructure.

## Troubleshooting

Common challenges when integrating Puppeteer with the Scraping Browser and their solutions:

<Steps>
  <Step title="Connection Refused">
    If you encounter Connection Refused errors, verify these potential causes:

    * **API Key Validation:** Confirm you're using the correct API key from your dashboard.
    * **Network Connectivity:** Check your internet connection and firewall configurations.
    * **WebSocket Endpoint:** Ensure the WebSocket URL (`wss://browser.zenrows.com`) is properly formatted.
  </Step>

  <Step title="Timeout and Loading Issues">
    * Use `page.waitForSelector()` to ensure elements are available before interaction

    * Extend timeout values for slow-loading websites

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

    * Validate CSS selectors using browser developer tools

    * Implement `waitUntil: 'networkidle2'` for dynamic content loading
  </Step>

  <Step title="Page Navigation Errors">
    * Handle navigation exceptions with proper try-catch blocks
    * Ensure proper browser and page cleanup to prevent memory leaks
    * Use `page.waitForNavigation()` for multi-step workflows
  </Step>

  <Step title="Geographic Restrictions">
    While ZenRows automatically rotates IP addresses, some websites implement location-based blocking. Consider adjusting regional settings for better access.

    <Info>
      Learn more about geographic targeting in our [Region Documentation](https://docs.zenrows.com/scraping-browser/features/world-region) and [Country Configuration](https://docs.zenrows.com/scraping-browser/features/country).
    </Info>
  </Step>

  <Step title="Get Help From ZenRows Experts">
    If challenges persist after implementing these solutions, our technical support team is ready to assist. Access help through the [Scraping Browser dashboard](https://app.zenrows.com/scraping-browser) or <a href="mailto:success@zenrows.com">contact our support team</a> for expert guidance.
  </Step>
</Steps>

## Next Steps

You've established a strong foundation for Puppeteer-based web scraping with ZenRows. Continue your journey with these resources:

* **[Practical Use Cases](/scraping-browser/help/practical-use-cases)**: <br />Explore common automation patterns including screenshot capture, custom JavaScript execution, and form interactions.
* **[Complete Scraping Browser Documentation](/scraping-browser/introduction)**: <br />Discover all available features and configuration options for the Scraping Browser platform.
* **[Puppeteer Web Scraping Guide](https://www.zenrows.com/blog?q=puppeteer)**: <br />Explore advanced Puppeteer techniques for complex scraping challenges.
* **[Pricing and Plans](/first-steps/pricing)**: <br />Learn about browser usage calculations and select the optimal plan for your requirements.

## Frequently Asked Questions (FAQ)

<Accordion title="Can I use ZenRows Scraping Browser with Playwright?">
  Absolutely! ZenRows Scraping Browser supports both Puppeteer and Playwright automation frameworks. The integration process is similar, requiring only connection method adjustments.

  <Tip>For comprehensive instructions, see our [Playwright Integration guide](/scraping-browser/get-started/playwright).</Tip>
</Accordion>

<Accordion title="Do I need to manage proxies manually with ZenRows Scraping Browser?">
  No manual proxy configuration is required. ZenRows Scraping Browser automatically handles proxy management and IP rotation behind the scenes.
</Accordion>

<Accordion title="Does the Scraping Browser handle CAPTCHA challenges?">
  Currently, ZenRows Scraping Browser doesn't include built-in CAPTCHA solving capabilities. For CAPTCHA handling, consider integrating third-party CAPTCHA solving services.

  <Tip>Explore our [Universal Scraper API](/universal-scraper-api/api-reference) for additional features including CAPTCHA solving and advanced anti-bot bypass mechanisms.</Tip>
</Accordion>

<Accordion title="Can I access all Puppeteer features through the Scraping Browser?">
  Yes! The Scraping Browser provides full access to Puppeteer's API, including page manipulation, screenshot generation, PDF creation, network interception, and all other native features.
</Accordion>

<Accordion title="How do I manage multiple browser tabs or pages?">
  Create additional pages using `await browser.newPage()` within the same browser instance. Each page operates independently while sharing the browser session and resources.
</Accordion>

<Accordion title="Can I use Puppeteer's built-in waiting mechanisms?">
  Certainly! Puppeteer's `waitForSelector()`, `waitForNavigation()`, and other waiting functions work seamlessly with the Scraping Browser, helping ensure reliable data extraction from dynamic content.
</Accordion>

<Accordion title="How do I capture screenshots with Puppeteer and Scraping Browser?">
  Use Puppeteer's standard screenshot functionality:

  ```javascript theme={null}
      await page.screenshot({ path: 'screenshot.png' });
  ```

  Screenshots are captured from the cloud browser and saved to your local environment automatically.
</Accordion>

<Accordion title="Can I monitor network requests with Puppeteer and Scraping Browser?">
  Yes! Puppeteer's network monitoring capabilities, including `page.on('request')` and `page.on('response')` event handlers, function normally with the Scraping Browser.
</Accordion>

<Accordion title="What's the main difference between local Puppeteer and Scraping Browser?">
  The primary distinction is execution location: browsers run in ZenRows' cloud infrastructure rather than locally. This provides superior IP management, fingerprint diversity, and resource efficiency while maintaining identical Puppeteer API functionality.
</Accordion>

<Accordion title="How do I handle file downloads with Puppeteer and Scraping Browser?">
  File downloads work through Puppeteer's standard download handling mechanisms. Files are downloaded to the cloud browser and then transferred to your local environment automatically.
</Accordion>
