When running multiple Chrome instances in parallel using multiprocessing or multithreading, you must follow a specific setup pattern to prevent binary conflicts. Multiple processes attempting to download and patch the same ChromeDriver binary simultaneously will cause failures.
Without proper setup, multiprocessing will fail with the error:
No undetected chromedriver binary were found.Call `Patcher.patch()` outside of multiprocessing/threading implementation.
import undetected as ucfrom undetected.patcher import Patcherimport multiprocessing as mpdef worker(idx: int): driver = uc.Chrome(user_multi_procs=True) driver.get("https://example.com") print(f"Process {idx}: {driver.title}") driver.quit()if __name__ == "__main__": Patcher.patch() # Patch a unique undetected chromedriver ONCE processes = [mp.Process(target=worker, args=(i,)) for i in range(4)] for p in processes: p.start() for p in processes: p.join()
Here’s a more complete example with error handling and result collection:
import undetected as ucfrom undetected.patcher import Patcherimport multiprocessing as mpdef worker(idx: int, result_queue): """Worker function that scrapes a page and returns results.""" try: options = uc.ChromeOptions() options.add_argument("--headless=new") driver = uc.Chrome( options=options, user_multi_procs=True ) driver.get("https://example.com") title = driver.title driver.quit() result_queue.put((idx, True, title)) except Exception as e: result_queue.put((idx, False, str(e)))if __name__ == "__main__": # Step 1: Patch the binary once Patcher.patch() # Step 2: Set up multiprocessing process_count = 4 ctx = mp.get_context("spawn") result_queue = ctx.Queue() # Step 3: Create and start processes processes = [ ctx.Process(target=worker, args=(i, result_queue)) for i in range(process_count) ] for p in processes: p.start() # Step 4: Wait for completion for p in processes: p.join(timeout=60) # Step 5: Collect results results = [result_queue.get(timeout=5) for _ in range(process_count)] # Step 6: Process results for idx, success, data in results: if success: print(f"Process {idx}: {data}") else: print(f"Process {idx} failed: {data}")
Always use the spawn context for maximum compatibility:
import multiprocessing as mpif __name__ == "__main__": ctx = mp.get_context("spawn") # Use ctx.Process() instead of mp.Process() p = ctx.Process(target=worker)
This ensures clean process creation on all platforms (Windows, Linux, macOS).
Error:No undetected chromedriver binary were foundSolution: Make sure Patcher.patch() is called before spawning processes:
if __name__ == "__main__": Patcher.patch() # Must be here # Then spawn processes
Permission errors on binary
Error:PermissionError: [Errno 13] Permission deniedSolution: This happens when processes try to modify the same binary. Ensure user_multi_procs=True is set:
driver = uc.Chrome(user_multi_procs=True)
Processes hang or timeout
Problem: Processes don’t completeSolutions:
Use headless mode to reduce resource usage
Limit the number of concurrent processes
Add timeouts to join() calls
Ensure driver.quit() is always called (use try/finally)