NoahVerner
NoahVerner

Reputation: 867

WebDriverException: Message: unknown error: Could not remove old devtools port file error updating the Selenium Options() within a function

I have a program that will ask the user for the profile path from Chrome Driver, after providing it and clicking the user_data button and then clicking the open_browser button, it will open Chrome Driver with the user data and profile directory, here:

import tkinter as tk 
from tkinter import ttk #for user inputs
from tkinter import messagebox #for warning messages 
import re
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

root = tk.Tk()
root.geometry('500x400') #resolution
root.title("Bulkdozer") #Name of this program
root.attributes('-topmost', True) #keep the program's window top-most

opt = Options() #the variable that will store the selenium options
def submit_profile_path():
    if len(profile_path.get()) == 0: #check if the user didn't type anything and pressed the button 
        messagebox.showerror(message="You didn't provide any input, try again", title="NULL Input")
    elif len(profile_path.get()) > 0:
        if r'\Google\Chrome\User Data' in profile_path.get(): #check if the path provided by the user is a valid one
            if profile_path.get().split("User Data\\",1)[1] != "": #now check if at the end of that path exist an actual profile folder
                user_data.pack_forget() #hide the user_data button
                data_input.pack_forget() #hide the data_input
                profile_path_label.pack_forget() #hide the profile_path_label
                open_browser.pack() #show the open_browser button
                x = profile_path.get() #get the profile path
                y = x.replace(re.split('\\bUser Data\\b',x)[-1], "") #get the user data path
                z = x.split("User Data\\",1)[1] #get the profile directory 
                global opt
                opt.add_argument(fr'--user-data-dir="{y}"') #Add the user data path as an argument in selenium Options
                print(y)
                opt.add_argument(f'--profile-directory={z}') #Add the profile directory as an argument in selenium Options
                print(z)
                print(type(opt))
                print(opt)
                return opt
                
            else: #inform the user that he must provide the profile path containing the corresponding profile folder
                messagebox.showwarning(message="You forgot to add the PROFILE FOLDER in the profile path, try again", title="Profile Folder Missing")
                data_input.delete(0, tk.END)        
                
        else: #inform the user that he must provide a valid profile path
            messagebox.showwarning(message="The path provided does not seem to be the right one, try again", title="Invalid Profile PATH")
            data_input.delete(0, tk.END)
            
# BUTTON FOR PROVIDING THE PROFILE PATH OF CHROME BROWSER #
profile_path = tk.StringVar() #This variable will be used for storing the profile path string passed by the user
signin = ttk.Frame(root) #create a container for the profile_path variable
signin.pack(padx=55, pady=20, fill='x', expand=True) #define the dimensional measurement and location for this container
profile_path_label = ttk.Label(signin, text="Introduce YOUR profile path:") #create a label for the profile_path variable
profile_path_label.pack(fill='x', expand=True) #add the label
data_input = ttk.Entry(signin, textvariable=profile_path) #create an entry for the profile_path variable
data_input.pack(fill='x', expand=True)
data_input.focus()
user_data = tk.Button(root, width=20,  text="Submit User Data", command=submit_profile_path) #executes the function when clicked
user_data.place(x=60, y=40, width=100, height=30) #define the dimensional measurement and location for this button
user_data.pack() #Apply The Pack geometry manager to this button for using its functions later on

#opt.add_argument('--user-data-dir='+r'C:\Users\ResetStoreX\AppData\Local\Google\Chrome\User Data') #PATH profile
#opt.add_argument('--profile-directory=Default')

s = Service('C:/Users/ResetStoreX/AppData/Local/Programs/Python/Python39/Scripts/chromedriver.exe')

########################     BUTTON ZONE     #############################

def open_chrome_profile():
    driver = webdriver.Chrome(service=s, options=opt) 
    driver.get('https://opensea.io/login?referrer=%2Faccount')

# BUTTON FOR OPENING A CHROME DRIVER WITH THE OPTIONS PASSED #

open_browser = tk.Button(root, width=20,  text="Open OpenSea Tab", command=open_chrome_profile) #executes the function when clicked
open_browser.place(width=100, height=30) #define the dimensional measurement and location for this button
open_browser.pack() #Apply The Pack geometry manager to this button for using its functions later on
open_browser.pack_forget() #initialize this button hidden

######################     BUTTON ZONE END     ###########################
root.mainloop()

I was testing my program with the following profile path:

C:\Users\ResetStoreX\AppData\Local\Google\Chrome\User Data\Default

And after clicking the user_data button and then clicking the open_browser button I got the following error:

selenium.common.exceptions.WebDriverException: Message: unknown error: Could not remove old devtools port file. Perhaps the given user-data-dir at "C:\Users\ResetStoreX\AppData\Local\Google\Chrome\User Data" is still attached to a running Chrome or Chromium process

Which is very unexpected because I didn't have any Chrome Browser opened at the moment of testing this program, and if set the following lines (instead of the ones I currently have) right below global opt in submit_profile_path() :

opt.add_argument('--user-data-dir='+r'C:\Users\ResetStoreX\AppData\Local\Google\Chrome\User Data')
opt.add_argument('--profile-directory=Default')

The program will compile with no errors, and Chrome Driver will use the user data and profile directory as expected.

The problem seems to be related with the current way of adding x and z variables as arguments to opt variable in submit_profile_path() function, that is:

opt.add_argument(fr'--user-data-dir="{y}"')
opt.add_argument(f'--profile-directory={z}')

So, I would appreciate a lot if someone could explain why is it wrong? and what could be a better way of doing so?

Upvotes: 0

Views: 1618

Answers (1)

undetected Selenium
undetected Selenium

Reputation: 193108

This error message...

selenium.common.exceptions.WebDriverException: Message: unknown error: Could not remove old devtools port file. Perhaps the given user-data-dir at "C:\Users\ResetStoreX\AppData\Local\Google\Chrome\User Data" is still attached to a running Chrome or Chromium process

...implies that the ChromeDriver was unable to initiate/spawn a new Browsing Context i.e. Chrome Browser session for either of the following reasons:

  • There are previous instance of ChromeDriver process attached to the system memory.
  • You have a manually opened session already running.

Because as per RemoveOldDevToolsActivePortFile():

Status RemoveOldDevToolsActivePortFile(const base::FilePath& user_data_dir) {
  base::FilePath port_filepath = user_data_dir.Append(kDevToolsActivePort);
  // Note that calling DeleteFile on a path that doesn't exist returns True.
  if (base::DeleteFile(port_filepath)) {
    return Status(kOk);
  }
  return Status(
      kUnknownError,
      base::StringPrintf(
          "Could not remove old devtools port file. Perhaps the given "
          "user-data-dir at %s is still attached to a running %s or "
          "Chromium process",
          user_data_dir.AsUTF8Unsafe().c_str(), kBrowserShortName));
}

References

You can find a couple of relevant detailed discussions in:

Upvotes: 1

Related Questions