{"id":7452,"library":"nodriver","title":"Nodriver","description":"Nodriver is a Python library for browser automation and web scraping, acting as the official successor to Undetected-Chromedriver. It communicates directly with browsers using the Chrome DevTools Protocol, eliminating the need for Selenium or WebDriver binaries, which significantly boosts performance and resistance against anti-bot systems. It is fully asynchronous and focuses on usability and quick prototyping. The current version is 0.48.1, and it seems to have a regular update cadence given the recent articles and version number.","status":"active","version":"0.48.1","language":"en","source_language":"en","source_url":"https://github.com/UltrafunkAmsterdam/nodriver","tags":["web scraping","browser automation","headless browser","anti-bot bypass","asyncio","chrome devtools protocol","undetected-chromedriver"],"install":[{"cmd":"pip install nodriver","lang":"bash","label":"Install nodriver"}],"dependencies":[{"reason":"Requires Python 3.9 or higher.","package":"python","optional":false},{"reason":"Requires a local installation of Chrome, Chromium, or Brave for automation.","package":"chrome-based browser","optional":false},{"reason":"Required for the `tab.cf_verify()` method to bypass Cloudflare Captchas.","package":"opencv-python","optional":true}],"imports":[{"note":"The common alias 'uc' (from undetected-chromedriver) is also frequently used: `import nodriver as uc`.","symbol":"nodriver","correct":"import nodriver"},{"note":"Used for handling errors specific to the Chrome DevTools Protocol.","symbol":"ProtocolException","correct":"from nodriver import ProtocolException"},{"note":"For custom browser configurations, such as executable path or user data directory.","symbol":"Config","correct":"from nodriver import Config"},{"note":"For direct interaction with Chrome DevTools Protocol domains and methods.","symbol":"cdp","correct":"from nodriver import cdp"}],"quickstart":{"code":"import nodriver\nimport asyncio\n\nasync def main():\n    browser = await nodriver.start(headless=True)\n    page = await browser.get('https://example.com')\n    print(f\"Page title: {await page.get_title()}\")\n    await page.close()\n    await browser.stop()\n\nif __name__ == '__main__':\n    nodriver.loop().run_until_complete(main())\n","lang":"python","description":"This quickstart demonstrates how to launch a headless browser, navigate to a URL, retrieve the page title, and then close the page and browser instance. Nodriver operations are asynchronous and require `async`/`await`."},"warnings":[{"fix":"Rename your Python script file to something other than `nodriver.py` (e.g., `my_scraper.py`).","message":"Naming your Python script `nodriver.py` can cause an `ImportError` because Python may try to import your local file instead of the installed package.","severity":"gotcha","affected_versions":"All versions"},{"fix":"It is recommended to use `nodriver.loop().run_until_complete(main())` to ensure proper event loop handling and browser lifecycle management.","message":"Using `asyncio.run()` directly to execute your main asynchronous function can sometimes lead to unexpected behavior with `nodriver`'s event loop management.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If encountering issues in headless mode, try running with `headless=False`. Also, consider adjusting browser arguments via `nodriver.Config` to better mimic human browsing patterns if stealth is critical.","message":"Headless mode (`headless=True`) can sometimes trigger anti-bot detection or lead to `ERR_HTTP2_PROTOCOL_ERROR` on certain websites, especially compared to headed mode.","severity":"breaking","affected_versions":"All versions"},{"fix":"Use a dedicated `user_data_dir` for `nodriver` (e.g., `Config(user_data_dir='path/to/nodriver_profile')`), increase the startup timeout for `nodriver.start(timeout=...)`, and ensure no orphaned Chrome processes are running before starting the script.","message":"Nodriver can fail to connect to Chrome (e.g., `ClientConnectorError`) if the Chrome profile is locked by another process or if the debugging port is slow to open, particularly on macOS or when using existing profiles.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure `opencv-python` is installed (`pip install opencv-python`) and avoid setting `expert=True` in `nodriver.start()` if you intend to use `cf_verify()`.","message":"The `tab.cf_verify()` method for Cloudflare bypass only works when the browser is NOT started in 'expert' mode and requires the `opencv-python` package to be installed.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Rename your Python script file to anything other than `nodriver.py` (e.g., `main.py`, `scraper.py`).","cause":"Your Python script file is named `nodriver.py`, causing a conflict with the installed package.","error":"ImportError: cannot import name 'nodriver' from 'nodriver'"},{"fix":"Try killing any lingering Chrome processes, increase the startup timeout for `nodriver.start(timeout=...)`, or configure a dedicated user data directory for `nodriver` to prevent profile locking issues via `nodriver.Config(user_data_dir='path/to/new_profile')`.","cause":"Nodriver failed to establish a connection to the Chrome DevTools Protocol. This often occurs if Chrome is already running and locking its profile, if Chrome takes too long to launch, or if background Chrome processes are interfering.","error":"aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host localhost:<port> [Connect call failed ('127.0.0.1', <port>)]"},{"fix":"Ensure that the element you are trying to interact with exists on the page when the command is called. Use `await page.wait_for_selector('selector')` or appropriate waits before interaction, and double-check your selectors or node IDs.","cause":"A Chrome DevTools Protocol command failed because a specified element (node_id, selector) could not be found or was invalid at the time of the command execution.","error":"nodriver.ProtocolException: No node with given id found"},{"fix":"Verify that Chrome/Chromium is installed and accessible. If you've provided a custom path, ensure it's correct. If not provided, ensure Chrome is installed in a default location `nodriver` can detect.","cause":"Nodriver could not find the Chrome/Chromium executable at the specified `browser_executable_path` in `Config` or in common system locations.","error":"FileNotFoundError: [Errno 2] No such file or directory: '/invalid/path/to/chrome'"},{"fix":"Ensure all `nodriver` calls are correctly `await`ed within `async` functions, and the main entry point is executed using `nodriver.loop().run_until_complete(main())`.","cause":"Nodriver functions that involve browser interaction (like `browser.get()` or `uc.start()`) must be called within an `async` function and executed via an `asyncio` event loop.","error":"RuntimeError: Cannot run Browser.get() outside of async context"}]}