ultrafunkamsterdam / undetected-chromedriver

Custom Selenium Chromedriver | Zero-Config | Passes ALL bot mitigation systems (like Distil / Imperva/ Datadadome / CloudFlare IUAM)
https://github.com/UltrafunkAmsterdam/undetected-chromedriver
GNU General Public License v3.0
9.97k stars 1.16k forks source link

Tkinter + Undetected Chromedriver Stop Button to Kill All Existing Browsers opened by UC #601

Open sunny9495-dev opened 2 years ago

sunny9495-dev commented 2 years ago

Here is my program

import multiprocessing
from multiprocessing import Pool
import time
from tkinter import *
from tkinter import ttk
import undetected_chromedriver as webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import os
from tkinter import messagebox
def next_name(name):
    print("Thread initiated")
    options = webdriver.ChromeOptions()
    options.binary_location = r'drivers/Browser/chrome.exe'
    driver = webdriver.Chrome(options=options)
    driver.get('http://google.com')
    time.sleep(2)
    driver.find_element(By.XPATH, '//input[@name="q"]').send_keys(name)
    time.sleep(2)
    driver.find_element(By.XPATH, '//input[@name="q"]').send_keys(Keys.ENTER)
    time.sleep(3)
    driver.close()
def mycallback(x):
    messagebox.showinfo("Sample Program", "Completed")
def start():
    global pool
    x = ['annah', 'reena', 'jermy', 'sunny', 'chinni']
    pool = Pool(processes=3)
    params = [(a, x.index(a)) for a in x]
    pool.starmap_async(next_name, params, callback=mycallback)
def stop():
    pool.terminate()
    os.system("taskkill /F /IM chromedriver.exe /T")

root = Tk()
startbtn = ttk.Button(root, text="start", command=start)
startbtn.pack()
stopbtn = ttk.Button(root, text="stop", command=stop)
stopbtn.pack()
root.geometry('300x300')
if __name__ == '__main__':
    multiprocessing.freeze_support()
    root.mainloop()

When i click stop, the browser initialized by UC all have to get closed, but it isn't happening. When i selenium library, there is no issue

Any help would be appreciated.

Thanks

sebdelsol commented 2 years ago

It would help if your code was actually working :

I would refrain from using globals, that's a catastrophe waiting to happen.

Anyway I don't understand why you need multiprocesses : you're nesting processes (undected-chromedriver spawns a Chrome process) and that's inefficient.

sunny9495-dev commented 2 years ago

HI @sebdelsol

Iam trying to close all browser instance running by undetected chromedriver, as for example, i have shown it mate.

I tried

os.system("taskkill /F /IM chromedriver.exe /T")

But it suspend only chromedriver.exe, not the browser, where if we tried the same code with selenium, it suspends browser+chromedriver.exe , it works fine without any issue.

sebdelsol commented 2 years ago

A selenium driver spawns the browser and closes it when quitting.

Undetected-chromedriver works differently : it spawns the browser first as a detached process before creating the driver. That's how you get a Chrome browser that has barely any link with it's driver hence hard to detect.

The browser is actually killed when the driver quit() here or killed in this function registered in an atexithook if not.

So if you let the the processes finish everything will be cleanup.

If you want a quick exit you'll have to send a signal to your subprocesses to explicitly quit their drivers. It's the cleanest way otherwise you'll end up with temp directories not cleaned up.

btw you'd better use multithread instead of multiprocess since a driver is IO constrained and sits idle barely doing anything, it's more efficient and it's easier to share states and messages between your main thread and its children (you won't need to have pickeable objects).

sunny9495-dev commented 2 years ago

@sebdelsol let me work on it. Thanks