Skip to main content

Prerequisites

Before you begin, ensure you have:
  • Python 3.10 or higher
  • Chrome or Chromium browser installed on your system
  • Basic understanding of Python async/await syntax
Zendriver will automatically detect your Chrome installation. If you have Chrome installed in a non-standard location, you can specify the path when starting the browser.

Your first script

Let’s create a simple script that visits a website and captures a screenshot.

Step 1: Install Zendriver

If you haven’t already, install Zendriver:
pip install zendriver
See the installation guide for more options.

Step 2: Create a Python file

Create a new file called example.py:
import asyncio
import zendriver as zd

async def main():
    # Start the browser
    browser = await zd.start()
    
    # Navigate to a webpage
    page = await browser.get("https://www.browserscan.net/bot-detection")
    
    # Save a screenshot
    await page.save_screenshot("browserscan.png")
    
    # Clean up
    await browser.stop()

if __name__ == "__main__":
    asyncio.run(main())

Step 3: Run the script

python example.py
You should see Chrome open, navigate to the website, and then close. A screenshot will be saved as browserscan.png in your current directory.
Congratulations! You’ve successfully automated a browser with Zendriver.

Understanding the code

Let’s break down what each part does:
1

Import the library

import asyncio
import zendriver as zd
Import asyncio for async/await support and zendriver for browser automation.
2

Start the browser

browser = await zd.start()
The start() function launches Chrome with sensible defaults. It returns a Browser object that you’ll use to control the browser.
3

Navigate to a page

page = await browser.get("https://www.browserscan.net/bot-detection")
The get() method navigates to a URL and returns a Tab object representing the page.
4

Interact with the page

await page.save_screenshot("browserscan.png")
Use the Tab object to interact with the page—in this case, saving a screenshot.
5

Clean up

await browser.stop()
Always stop the browser when you’re done to clean up resources.

Common patterns

Finding and clicking elements

Zendriver makes it easy to find elements by selector or text:
import asyncio
import zendriver as zd

async def main():
    browser = await zd.start()
    page = await browser.get("https://example.com")
    
    # Find element by CSS selector
    button = await page.find("button.submit")
    await button.click()
    
    # Find element by text content
    link = await page.find("Click here")
    await link.click()
    
    await browser.stop()

if __name__ == "__main__":
    asyncio.run(main())
The find() method automatically waits and retries until the element appears or times out, making your scripts more reliable.

Typing into input fields

Send keyboard input to form fields:
import asyncio
import zendriver as zd

async def main():
    browser = await zd.start()
    page = await browser.get("https://example.com/login")
    
    # Find and fill in a text input
    username_field = await page.find("input[name='username']")
    await username_field.send_keys("myusername")
    
    password_field = await page.find("input[name='password']")
    await password_field.send_keys("mypassword")
    
    # Submit the form
    submit_button = await page.find("button[type='submit']")
    await submit_button.click()
    
    await browser.stop()

if __name__ == "__main__":
    asyncio.run(main())

Working with multiple elements

Find all matching elements:
import asyncio
import zendriver as zd

async def main():
    browser = await zd.start()
    page = await browser.get("https://example.com")
    
    # Find all links on the page
    links = await page.select_all("a")
    
    print(f"Found {len(links)} links")
    
    for link in links:
        text = await link.text
        print(f"Link text: {text}")
    
    await browser.stop()

if __name__ == "__main__":
    asyncio.run(main())

Browser configuration

Customize browser behavior with configuration options:
import asyncio
import zendriver as zd

async def main():
    # Start browser with custom options
    browser = await zd.start(
        headless=False,  # Show browser window (default)
        user_agent="Custom User Agent String",
        lang="en-US",
        browser_args=["--window-size=1920,1080"]
    )
    
    page = await browser.get("https://example.com")
    await page.save_screenshot("example.png")
    await browser.stop()

if __name__ == "__main__":
    asyncio.run(main())
By default, Zendriver runs in non-headless mode (showing the browser window). This helps avoid detection by anti-bot systems.

Next steps

Now that you understand the basics, explore these topics:

Browser configuration

Learn about all available configuration options

Working with elements

Master element selection, interaction, and manipulation

Cookie management

Save and restore cookies for persistent sessions

API reference

Explore the complete API documentation

Troubleshooting

If Zendriver can’t find your Chrome installation, specify the path explicitly:
browser = await zd.start(
    browser_executable_path="/path/to/chrome"
)
If find() times out, the element might not exist or might load slowly:
  • Verify the selector is correct
  • Increase the timeout: await page.find("selector", timeout=30)
  • Check if the element is inside an iframe
Always call await browser.stop() to clean up properly. Consider using a try/finally block:
browser = await zd.start()
try:
    # Your automation code here
    pass
finally:
    await browser.stop()

Build docs developers (and LLMs) love