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

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

我有一个程序会向用户询问来自 Chrome 驱动程序的 profile path,在提供它并单击 user_data 按钮然后单击 open_browser 之后按钮,它将打开 Chrome 带有用户数据和配置文件目录的驱动程序,此处:

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()

我正在使用以下配置文件路径测试我的程序:

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

单击 user_data 按钮,然后单击 open_browser 按钮后,出现以下错误:

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

这是非常出乎意料的,因为在测试此程序时我没有打开任何 Chrome 浏览器,如果设置以下行 ( 而不是我目前拥有的 ) 就在 submit_profile_path() 中的 global opt 下方 :

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

程序将编译无误,Chrome驱动程序将按预期使用用户数据和配置文件目录。

问题似乎与当前在 submit_profile_path() 函数中将 xz 变量作为参数添加到 opt 变量的方式有关,即:

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

所以,如果有人能解释为什么错了,我将不胜感激?还有什么更好的方法呢?

这个错误信息...

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

...意味着 无法 initiate/spawn 新的 浏览上下文 Chrome 浏览器 会话出于以下任一原因:

  • 系统内存中附加了 个进程的先前实例。
  • 您已经有一个手动打开的 会话 运行。

因为根据 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));
}

参考资料

您可以在以下位置找到一些相关的详细讨论: