How to Pass Custom Arguments to the Browser Executable in Zendriver
You can pass custom arguments to the Chromium browser executable in zendriver using the browser_args parameter in Browser.create(), setting the browser_args attribute on a Config instance, or calling the add_argument() method for incremental additions.
The zendriver library automates Chromium-based browsers by constructing command-line flags through a centralized configuration system. When you need to enable specific Chrome features, disable security restrictions, or tune performance settings, you must inject custom flags into the browser launch sequence.
Understanding the Config Class Architecture
The Config class in zendriver/core/config.py serves as the command-line builder for the browser process. When Browser.start() launches the executable, it invokes the Config instance as a callable (Config.__call__), which returns a list of strings representing the final command-line arguments.
The __call__ method (lines 190–235) constructs the argument list by:
- Copying default browser arguments
- Appending managed flags (user data directory, headless mode, user agent, etc.)
- Extending with custom arguments from
self._browser_argswhile filtering duplicates
Three Methods to Pass Custom Browser Arguments
Using the browser_args Parameter in Browser.create
The simplest approach passes a list of strings directly to the factory method. In zendriver/core/browser.py, the Browser.create() method accepts a browser_args parameter that gets forwarded to the Config constructor.
import zendriver
# Enable remote debugging and disable GPU acceleration
custom_flags = ["--remote-debugging-port=9222", "--disable-gpu"]
browser = await zendriver.Browser.create(
headless=False,
browser_args=custom_flags
)
Setting Config.browser_args Directly
For advanced scenarios requiring explicit Config manipulation, instantiate Config separately and populate its browser_args attribute before passing it to Browser.create.
from zendriver.core.config import Config
import zendriver
cfg = Config()
cfg.browser_args = ["--disable-features=AudioServiceOutOfProcess", "--disable-extensions"]
browser = await zendriver.Browser.create(config=cfg)
Adding Arguments Incrementally with Config.add_argument
The Config.add_argument() method in zendriver/core/config.py allows appending single flags while enforcing validation rules. This method rejects arguments that conflict with dedicated Config attributes.
from zendriver.core.config import Config
cfg = Config()
cfg.add_argument("--disable-background-networking")
cfg.add_argument("--disable-popup-blocking")
# These would raise ValueError because they have dedicated Config fields:
# cfg.add_argument("--headless") # Use cfg.headless = True instead
# cfg.add_argument("--user-data-dir=/tmp") # Use cfg.user_data_dir instead
How Custom Arguments Are Merged with Defaults
When Browser.start() invokes the Config callable, the following merge logic executes:
# From zendriver/core/config.py
def __call__(self) -> list[str]:
args = self._default_browser_args.copy()
args += ["--user-data-dir=%s" % self.user_data_dir]
# ... other managed flags ...
if self._browser_args:
# Custom args extend the list, duplicates filtered
args.extend([arg for arg in self._browser_args if arg not in args])
return args
Custom arguments always appear after the default set in the final command list. The implementation filters exact duplicates to prevent conflicting flags, but note that flags with different values (e.g., --window-size=800,600 vs --window-size=1200,800) are treated as distinct strings and both would be included.
Important Restrictions on Custom Arguments
The add_argument() method specifically blocks flags that have dedicated Config attributes to prevent configuration conflicts. According to the source in zendriver/core/config.py, you cannot use add_argument() for:
--headless(usecfg.headless)--user-data-dir(usecfg.user_data_dir)--no-sandbox(usecfg.no_sandbox)--lang(usecfg.lang)--user-agent(usecfg.user_agent)--window-size(usecfg.window_size)--proxy-server(usecfg.proxy)
Attempting to add these via add_argument() raises a ValueError with instructions to use the corresponding attribute instead.
Complete Code Examples
Passing a List of Custom Flags
import zendriver
import asyncio
async def main():
# Configure performance and security flags
browser_args = [
"--disable-gpu",
"--disable-dev-shm-usage",
"--disable-setuid-sandbox",
"--remote-debugging-port=9222"
]
browser = await zendriver.Browser.create(
headless=True,
browser_args=browser_args
)
page = await browser.get("https://example.com")
await browser.stop()
asyncio.run(main())
Adding Arguments After Config Initialization
from zendriver.core.config import Config
import zendriver
import asyncio
async def main():
cfg = Config()
cfg.headless = False
cfg.window_size = (1920, 1080)
# Incrementally add experimental flags
cfg.add_argument("--enable-experimental-web-platform-features")
cfg.add_argument("--disable-background-timer-throttling")
browser = await zendriver.Browser.create(config=cfg)
page = await browser.get("https://example.com")
await browser.stop()
asyncio.run(main())
Combining Both Approaches
from zendriver.core.config import Config
import zendriver
import asyncio
async def main():
# Base configuration with specific overrides
cfg = Config()
cfg.add_argument("--disable-extensions")
cfg.add_argument("--disable-background-networking")
# Additional runtime flags passed via browser_args
extra_args = ["--disable-popup-blocking", "--disable-translate"]
browser = await zendriver.Browser.create(
config=cfg,
browser_args=extra_args
)
page = await browser.get("https://example.com")
await browser.stop()
asyncio.run(main())
Summary
- Primary mechanism: Pass a list of strings to the
browser_argsparameter inBrowser.create()(defined inzendriver/core/browser.py). - Advanced configuration: Instantiate
Configfromzendriver/core/config.pyand setcfg.browser_argsdirectly or usecfg.add_argument()for incremental additions. - Merge behavior: Custom arguments are appended after default flags in
Config.__call__(), with exact duplicates filtered to prevent conflicts. - Validation:
add_argument()blocks flags that have dedicatedConfigattributes (e.g.,--headless,--user-data-dir) to ensure consistent configuration management.
Frequently Asked Questions
Can I override default browser arguments like --headless using browser_args?
No, you should use the dedicated Config attributes instead. According to the source code in zendriver/core/config.py, flags like --headless, --user-data-dir, --no-sandbox, and --window-size are managed through specific properties (cfg.headless, cfg.user_data_dir, etc.). The add_argument() method explicitly rejects these flags with a ValueError to prevent configuration conflicts.
What happens if I pass duplicate arguments in browser_args?
The Config.__call__ method filters out exact duplicates when building the final command line. In zendriver/core/config.py, the implementation extends the argument list with [arg for arg in self._browser_args if arg not in args], ensuring that if a flag already exists in the default set, your custom version is ignored. However, flags with different values (like different window sizes) are treated as distinct strings and both would appear in the final command.
Can I modify browser arguments after creating the Config object but before launching the browser?
Yes, you can incrementally add arguments using the add_argument() method or by modifying the browser_args list directly. As shown in zendriver/core/config.py, the add_argument() method appends to self._browser_args, and since Config is not frozen, you can modify this list until you pass the config to Browser.create(). This is useful for conditionally adding flags based on runtime logic before launching the browser process.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →