seleniumbase / SeleniumBase

📊 Python's all-in-one framework for web crawling, scraping, testing, and reporting. Supports pytest. UC Mode provides stealth. Includes many tools.
https://seleniumbase.io
MIT License
4.45k stars 908 forks source link

SB/Driver does not work with ProcessPoolExecutor/ThreadPoolExecutor #2828

Closed iamumairayub closed 4 weeks ago

iamumairayub commented 4 weeks ago

I have code in my Windows

def send_request(rows, profile):

    with SB(
        uc=True,
        ) as sb:

        print(f"Opening {row['source']} in thread {profile}")
        sb.driver.uc_open_with_reconnect(row['source'], 10)

if __name__ == '__main__':

    sessions = 2
    with futures.ProcessPoolExecutor(max_workers=sessions) as executor:

        cursor.execute("SELECT id, source FROM Sale WHERE updated IS NULL LIMIT 2")
        all_jobs=[]

        for idx, rows in enumerate(split(cursor.fetchall(), sessions)):

            job = executor.submit(
                send_request, 
                rows,
                idx
            )
            all_jobs.append(job)

In logs I can see


Will process 1 rows
Will process 1 rows
Opening https://website.com/url2 in 1
Opening https://website.com/url1 in 0

The URL is opened fine in one of thread/process

I can clearly see browser window

But on the 2nd window its always like this

image

Logs also show

Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\common\service.py", line 170, in _terminate_process
    self.process.terminate()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1573, in terminate
    _winapi.TerminateProcess(self._handle, 1)
OSError: [WinError 6] The handle is invalid
Error terminating service process.
Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\common\service.py", line 170, in _terminate_process
    self.process.terminate()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1573, in terminate
    _winapi.TerminateProcess(self._handle, 1)
OSError: [WinError 6] The handle is invalid

I have tried both ProcessPoolExecutor/ThreadPoolExecutor I have tried both SB/Driver

mdmintz commented 4 weeks ago

See the example that uses ThreadPoolExecutor with UC Mode: https://github.com/seleniumbase/SeleniumBase/issues/2478#issuecomment-1981699298

import sys
from concurrent.futures import ThreadPoolExecutor
from seleniumbase import Driver
sys.argv.append("-n")  # Tell SeleniumBase to do thread-locking as needed

def launch_driver(url):
    driver = Driver(uc=True)
    try:
        driver.get(url=url)
        driver.sleep(2)
    finally:
        driver.quit()

urls = ['https://seleniumbase.io/demo_page' for i in range(3)]
with ThreadPoolExecutor(max_workers=len(urls)) as executor:
    for url in urls:
        executor.submit(launch_driver, url)