Get PID of Browser launched by selenium

a 夏天 提交于 2019-11-30 06:01:16
hwjp

Using the Python API, it's pretty simple:

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

If you're using Chrome, it's a little more complex, you go via a chromedriver process:

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)

If you're using PhantomJS then you can get the PID from the process Popen object:

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

hwjp's solution isn't working anymore for me, but the solution from ABM is working for other browsers too in case anyone is wondering, so for firefox as of now:

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

can't comment because of reputation, so I'm submitting this as separate answer...

Stefan Matei

In Java, if you use ChromeDriver, you can find the port that the driver will use

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

and then, using the port, you can find the chromedriver process id by running the command

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

or

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

You can go further, to find out the chrome process id, by using the chromedriver process id (parent id of the chrome process)

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

or

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

the code looks like this:

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]);
  }
}

the output will be, on 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

and on windows:

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

You can retrieve the PID of Browser launched by Selenium from the capabilities which returns a using the following solution:

  • Code Block:

    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']))
    
  • Browser Snapshot:

If you are using java and selenium, you can simply first find the PID of the JVM and then through its child processes, you can get the PID of chromedriver and then similarly PID of chrome. Here is an example to find the PID of chromedriver.

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

        }
    }
Mohamed EL AYADI

for the guys comming here to find a solution, here it is, hope it will help you out.

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;
}

I solved it this way:

I am on a Linux OS using Python to detect Firefox memory usage:

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

None that I am aware of. Getting the PID would usually require some modification of Selenium code. You may however obtain the PID from the system instead of from Selenium itself. This topic on webdriver user group may be helpful:

https://groups.google.com/forum/#!topic/webdriver/_-8Slyn6qrI

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!