【问题标题】:Get PID of Browser launched by selenium获取 selenium 启动的浏览器的 PID
【发布时间】:2012-05-31 22:10:19
【问题描述】:

我想获取 selenium 启动的浏览器的 PID。有什么办法可以完成吗?

【问题讨论】:

    标签: selenium selenium-webdriver webdriver selenium-rc


    【解决方案1】:

    使用 Python API,非常简单:

    from selenium import webdriver
    browser = webdriver.Firefox()
    print browser.binary.process.pid
    # browser.binary.process is a Popen object...
    

    如果您使用的是 Chrome,它会稍微复杂一些,您需要通过 chromedriver 进程:

    c = webdriver.Chrome()
    c.service.process # is a Popen instance for the chromedriver process
    import psutil
    p = psutil.Process(c.service.process.pid)
    print p.get_children(recursive=True)
    

    【讨论】:

    • 你不知道如何使用nodejs获取它吗?
    • 我没有。我通过在一个名为 selenium.webdriver.firefox 的模块中挖掘源代码找到了它。也许通过js源挖掘?像这里这样的地方? code.google.com/p/selenium/source/browse/javascript/…
    • chrome 现在是 p.children 而不是 p.get_children
    • 由于某种原因,当我使用 geckodriver 使用 firefox 时,这不起作用。在这种情况下,@ABM 建议的答案效果很好
    • 来自 psutil 文档:get_children 现在是 childrenpythonhosted.org/psutil/#psutil.Process.children
    【解决方案2】:

    hwjp 的解决方案不再适用于我,但 ABM 的解决方案也适用于其他浏览器,以防有人想知道,所以对于 firefox 来说:

    from selenium import webdriver
    driver = webdriver.Firefox()
    print(driver.service.process.pid)
    

    由于声誉问题无法发表评论,因此我将其作为单独的答案提交...

    【讨论】:

    • 这是一个答案,您无需为这不是评论而道歉。至于代表,这里有一些,所以你可以发表评论。 :)
    • 如何获取 RemoteBrowser 的 PID?如果有人知道,请更新..
    • @nmfzone 请参阅answer below。 (请注意,此答案返回驱动程序的 PID,至少对于 Firefox)
    【解决方案3】:

    如果您使用的是 PhantomJS,那么您可以从进程 Popen 对象中获取 PID:

    from selenium import webdriver
    browser = webdriver.PhantomJS()
    print browser.service.process.pid  
    

    【讨论】:

      【解决方案4】:

      在 Java 中,如果您使用 ChromeDriver,您可以找到驱动程序将使用的端口

      port = chromeDriverService.getUrl().getPort();
      

      然后,使用端口,您可以通过运行命令找到 chromedriver 进程 id

      netstat -anp | grep LISTEN | grep [port] (on linux)
      

      netstat -aon | findstr LISTENING | findstr [port] (on windows)
      

      您可以更进一步,通过使用 chromedriver 进程 id(chrome 进程的父 id)找出 chrome 进程 id

      ps -efj | grep google-chrome | grep [chromedriverprocessid] (on linux)
      

      wmic process get processid,parentprocessid,executablepath | find \"chrome.exe\" |find \"chromeDriverProcessID\"
      

      代码如下所示:

      import java.io.BufferedReader;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.util.ArrayList;
      import java.util.List;
      import java.util.logging.Level;
      
      import org.apache.commons.lang.SystemUtils;
      import org.openqa.selenium.WebDriverException;
      import org.openqa.selenium.chrome.ChromeDriver;
      import org.openqa.selenium.chrome.ChromeDriverService;
      import org.openqa.selenium.chrome.ChromeOptions;
      import org.openqa.selenium.logging.LogType;
      import org.openqa.selenium.logging.LoggingPreferences;
      import org.openqa.selenium.remote.CapabilityType;
      import org.openqa.selenium.remote.DesiredCapabilities;
      
      public class WebdriverProcessID
      {
        public static void main(String[] args) throws IOException, InterruptedException
        {
          ChromeDriver driver = null;
      
          ChromeOptions options = new ChromeOptions();
          List<String> listArguments = new ArrayList<String>();
      
          DesiredCapabilities cap = DesiredCapabilities.chrome();
          cap.setCapability(ChromeOptions.CAPABILITY, options);
      
          LoggingPreferences logPrefs = new LoggingPreferences();
          logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
          cap.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
      
          ChromeDriverService chromeDriverService = ChromeDriverService.createDefaultService();
          int port = chromeDriverService.getUrl().getPort();
      
          driver = new ChromeDriver(chromeDriverService, cap);
      
          System.out.println("starting chromedriver on port " + port);
          int chromeDriverProcessID = GetChromeDriverProcessID(port);
          System.out.println("detected chromedriver process id " + chromeDriverProcessID);
          System.out.println("detected chrome process id " + GetChromeProcesID(chromeDriverProcessID));
      
          driver.navigate().to("https://www.test.com/");
      
          try
          {
            Thread.sleep(100000);
          }
          catch (InterruptedException e)
          {
          }
      
          try
          {
            driver.close();
          }
          catch (WebDriverException ex)
          {
            ex.printStackTrace();
          }
      
          try
          {
            driver.quit();
          }
          catch (WebDriverException ex)
          {
            ex.printStackTrace();
          }
        }
      
        private static int GetChromeDriverProcessID(int aPort) throws IOException, InterruptedException
        {
          String[] commandArray = new String[3];
      
          if (SystemUtils.IS_OS_LINUX)
          {
            commandArray[0] = "/bin/sh";
            commandArray[1] = "-c";
            commandArray[2] = "netstat -anp | grep LISTEN | grep " + aPort;
          }
          else if (SystemUtils.IS_OS_WINDOWS)
          {
            commandArray[0] = "cmd";
            commandArray[1] = "/c";
            commandArray[2] = "netstat -aon | findstr LISTENING | findstr " + aPort;
          }
          else
          {
            System.out.println("platform not supported");
            System.exit(-1);
          }
      
          System.out.println("running command " + commandArray[2]);
      
          Process p = Runtime.getRuntime().exec(commandArray);
          p.waitFor();
      
          BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
      
          StringBuilder sb = new StringBuilder();
          String line = "";
          while ((line = reader.readLine()) != null)
          {
            sb.append(line + "\n");
          }
      
          String result = sb.toString().trim();
      
          System.out.println("parse command response line:");
          System.out.println(result);
      
          return SystemUtils.IS_OS_LINUX ? ParseChromeDriverLinux(result) : ParseChromeDriverWindows(result);
        }
      
        private static int GetChromeProcesID(int chromeDriverProcessID) throws IOException, InterruptedException
        {
          String[] commandArray = new String[3];
      
          if (SystemUtils.IS_OS_LINUX)
          {
            commandArray[0] = "/bin/sh";
            commandArray[1] = "-c";
            commandArray[2] = "ps -efj | grep google-chrome | grep " + chromeDriverProcessID;
          }
          else if (SystemUtils.IS_OS_WINDOWS)
          {
            commandArray[0] = "cmd";
            commandArray[1] = "/c";
            commandArray[2] = "wmic process get processid,parentprocessid,executablepath | find \"chrome.exe\" |find \"" + chromeDriverProcessID + "\"";
          }
          else
          {
            System.out.println("platform not supported");
            System.exit(-1);
          }
      
          System.out.println("running command " + commandArray[2]);
      
          Process p = Runtime.getRuntime().exec(commandArray);
          p.waitFor();
      
          BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
      
          StringBuilder sb = new StringBuilder();
          String line = "";
          while ((line = reader.readLine()) != null)
          {
            if (SystemUtils.IS_OS_LINUX && line.contains("/bin/sh"))
            {
              continue;
            }
      
            sb.append(line + "\n");
          }
      
          String result = sb.toString().trim();
      
          System.out.println("parse command response line:");
          System.out.println(result);
      
          return SystemUtils.IS_OS_LINUX ? ParseChromeLinux(result) : ParseChromeWindows(result);
        }
      
        private static int ParseChromeLinux(String result)
        {
          String[] pieces = result.split("\\s+");
          // root 20780 20772 20759 15980  9 11:04 pts/1    00:00:00 /opt/google/chrome/google-chrome.........
          // the second one is the chrome process id
          return Integer.parseInt(pieces[1]);
        }
      
        private static int ParseChromeWindows(String result)
        {
          String[] pieces = result.split("\\s+");
          // C:\Program Files (x86)\Google\Chrome\Application\chrome.exe 14304 19960
          return Integer.parseInt(pieces[pieces.length - 1]);
        }
      
        private static int ParseChromeDriverLinux(String netstatResult)
        {
          String[] pieces = netstatResult.split("\\s+");
          String last = pieces[pieces.length - 1];
          // tcp 0 0 127.0.0.1:2391 0.0.0.0:* LISTEN 3333/chromedriver
          return Integer.parseInt(last.substring(0, last.indexOf('/')));
        }
      
        private static int ParseChromeDriverWindows(String netstatResult)
        {
          String[] pieces = netstatResult.split("\\s+");
          // TCP 127.0.0.1:26599 0.0.0.0:0 LISTENING 22828
          return Integer.parseInt(pieces[pieces.length - 1]);
        }
      }
      

      输出将是,在 linux 上:

      starting chromedriver on port 17132
      running command netstat -anp | grep LISTEN | grep 17132
      parse command response line:
      tcp        0      0 127.0.0.1:17132         0.0.0.0:*               LISTEN      22197/chromedriver
      detected chromedriver process id 22197
      running command ps -efj | grep google-chrome | grep 22197
      parse command response line:
      root     22204 22197 22183 15980 26 11:17 pts/1    00:00:00 /opt/google/chrome/google-chrome ...
      detected chrome process id 22204
      

      在窗户上:

      starting chromedriver on port 34231
      running command netstat -aon | findstr LISTENING | findstr 34231
      parse command response line:
      TCP    127.0.0.1:34231        0.0.0.0:0              LISTENING       10692
      detected chromedriver process id 10692
      running command wmic process get "processid,parentprocessid,executablepath" | findstr "chrome.exe" | findstr "10692"
      parse command response line:
      C:\Program Files (x86)\Google\Chrome\Application\chrome.exe  10692 12264
      detected chrome process id 12264
      

      【讨论】:

      • 这仍然是 Java 中“最简单”的方式吗?
      【解决方案5】:

      您可以通过以下不同方式使用客户端检索Selenium启动的浏览器进程的PID:


      火狐

      使用以下解决方案访问返回capabilities 对象:

      • 代码块:

        from selenium import webdriver
        from selenium.webdriver.firefox.options import Options
        
        options = Options()
        options.binary_location = r'C:\Program Files\Firefox Nightly\firefox.exe'
        driver = webdriver.Firefox(firefox_options=options, executable_path=r'C:\WebDrivers\geckodriver.exe')
        my_dict = driver.capabilities
        print("PID of the browser process is: " + str(my_dict['moz:processID']))
        
      • 控制台输出:

        PID of the browser process is: 14240
        
      • 浏览器快照:


      使用psutil.process_iter() 遍历进程,其中process.cmdline() 包含--test-type=webdriver,如下所示:

      • 代码块:

        from selenium import webdriver
        from contextlib import suppress
        import psutil
        
        driver = webdriver.Chrome(executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
        driver.get('https://www.google.com/')
        for process in psutil.process_iter():
            if process.name() == 'chrome.exe' and '--test-type=webdriver' in process.cmdline():
            with suppress(psutil.NoSuchProcess):
                print(process.pid)
        
      • 控制台输出:

        1164
        1724
        4380
        5748        
        
      • 浏览器快照:

      【讨论】:

        【解决方案6】:

        如果你使用java和selenium,你可以简单地先找到JVM的PID,然后通过它的子进程,你可以得到chromedriver的PID,然后类似地得到chrome的PID。下面是一个查找chromedriver PID的例子。

            final String jvmName = ManagementFactory.getRuntimeMXBean().getName();
            final int index = jvmName.indexOf('@');
            if(index > 1) {
                try {
                    String processId = Long.toString(Long.parseLong(jvmName.substring(0, index)));
                    Scanner scan = new Scanner(Runtime.getRuntime().exec("wmic process where (ParentProcessId="+ processId +") get Caption,ProcessId").getInputStream());
                    scan.useDelimiter("\\A");
                    String childProcessIds =  scan.hasNext() ? scan.next() : "";
                    List<String> chromeDrivers = new ArrayList<String>();
                    String[] splited = childProcessIds.split("\\s+");
                    for(int i =0 ; i<splited.length; i = i+2){
                        if("chromedriver.exe".equalsIgnoreCase(splited[i])){
                            chromeDrivers.add(splited[i+1]);
                        }
                    }
                    /*              
                    *
                    *Do whatever you want to do with the chromedriver's PID here    
                    *
                    * */        
                    scan.close();
                } catch (Exception e) {
        
                }
            }
        

        【讨论】:

        • 这仍然是 Java 中“最简单”的方式吗?
        【解决方案7】:

        我是这样解决的:

        我在 Linux 操作系统 上使用 Python 检测 Firefox 内存使用情况:

        import psutil
        
        # Get pid of geckodriver
        webdriver_pid = driver.service.process.pid
        
        # Get the process of geckodriver
        process = psutil.Process(webdriver_pid)
        
        # Get memory of geckodriver + firefox
        # Since memory is in bytes divide by 1024*1024 to obtain result in MB
        total_memory = sum([x.memory_info().rss/1048576 for x in process.children() + [process]])
        

        【讨论】:

          【解决方案8】:

          这是一个可用于 C# 和 Selenium 的示例。其他语言(如 Java)也会有相同的实现,但我只使用 C#。

          Chrome 允许您提供自己的用户定义的命令行参数。因此,您可以使用当前正在运行的程序的 PID(Windows 进程 ID)添加一个名为“scriptpid-”的参数。 ChromeDriver 在命令行中将您的参数传递给 Chrome。然后使用 Windows WMI 调用从正在运行的 Chrome 的命令行检索此 PID ...

          public static IntPtr CurrentBrowserHwnd = IntPtr.Zero;
          public static int CurrentBrowserPID = -1;
                  
          ChromeOptions options = new ChromeOptions();
          options.AddArgument("scriptpid-" + System.Diagnostics.Process.GetCurrentProcess().Id);
          IWebDriver driver = new ChromeDriver(options);
          
          // Get the PID and HWND details for a chrome browser
          
          System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("chrome");
          for (int p = 0; p < processes.Length; p++)
          {
              ManagementObjectSearcher commandLineSearcher = new ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + processes[p].Id);
              String commandLine = "";
              foreach (ManagementObject commandLineObject in commandLineSearcher.Get())
              {
                  commandLine += (String)commandLineObject["CommandLine"];
              }
          
              String script_pid_str = (new Regex("--scriptpid-(.+?) ")).Match(commandLine).Groups[1].Value;
          
              if (!script_pid_str.Equals("") && Convert.ToInt32(script_pid_str).Equals(System.Diagnostics.Process.GetCurrentProcess().Id))
              {
                  CurrentBrowserPID = processes[p].Id;
                  CurrentBrowserHwnd = processes[p].MainWindowHandle;
                  break;
              }
          }
          

          CurrentBrowserHwnd 应包含 Chrome 窗口的 HWND。

          CurrentBrowserPID 应包含您的 Chrome 窗口的进程 ID。

          【讨论】:

            【解决方案9】:

            对于来这里寻找解决方案的人来说,这里就是,希望它能帮助你。

            protected Integer getFirefoxPid(FirefoxBinary binary){
                try {
                    final Field fieldCmdProcess = FirefoxBinary.class.getDeclaredField("process");
                    fieldCmdProcess.setAccessible(true);
                    final Object ObjCmdProcess = fieldCmdProcess.get(binary);
            
                    final Field fieldInnerProcess = ObjCmdProcess.getClass().getDeclaredField("process");
                    fieldInnerProcess.setAccessible(true);
                    final Object objInnerProcess = fieldInnerProcess.get(ObjCmdProcess);
            
                    final Field fieldWatchDog = objInnerProcess.getClass().getDeclaredField("executeWatchdog");
                    fieldWatchDog.setAccessible(true);
                    final Object objWatchDog = fieldWatchDog.get(objInnerProcess);
            
                    final Field fieldReelProcess = objWatchDog.getClass().getDeclaredField("process");
                    fieldReelProcess.setAccessible(true);
                    final Process process = (Process) fieldReelProcess.get(objWatchDog);
            
                    final Integer pid;
            
                    if (Platform.getCurrent().is(WINDOWS)) {
                        final Field f = process.getClass().getDeclaredField("handle");
                        f.setAccessible(true);
                        long hndl = f.getLong(process);
            
                        final Kernel32 kernel = Kernel32.INSTANCE;
                        final WinNT.HANDLE handle = new WinNT.HANDLE();
                        handle.setPointer(Pointer.createConstant(hndl));
                        pid = kernel.GetProcessId(handle);
            
                    } else {
                        final Field f = process.getClass().getDeclaredField("pid");
                        f.setAccessible(true);
                        pid = (Integer) f.get(process);
                    }
                    logger.info("firefox process id : " + pid + " on plateform : " + Platform.getCurrent());
                    return pid;
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("Cannot get firefox process id, exception is : {}", e);
                }
                return null;
            }
            

            【讨论】:

            • 这仍然是 Java 中“最简单”的方式吗?您如何使其适应 Chrome?
            • 我不知道,我在 4 年前写了这个答案,自从我使用 Selenium 已经有一段时间了。
            猜你喜欢
            • 1970-01-01
            • 2020-10-04
            • 2013-09-12
            • 1970-01-01
            • 2020-04-16
            • 1970-01-01
            • 2010-11-27
            • 2011-01-07
            • 1970-01-01
            相关资源
            最近更新 更多