Get PID of Browser launched by selenium
Asked Answered
T

11

38

I would like to get the PID of the browser launched by selenium. Is there any way to get it done?

Thrice answered 25/5, 2012 at 10:11 Comment(1)
None of the answers appear to tell how to accomplish this using nodejsAloud
F
34

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)
Faulkner answered 30/11, 2012 at 17:27 Comment(9)
Don't you know how to get it using nodejs?Ardennes
I do not. I found it by digging around through the source, in a module called selenium.webdriver.firefox. Maybe dig around through the js source? Somewhere like here? code.google.com/p/selenium/source/browse/javascript/…Faulkner
This doesn't work if you're using PhantomJS. The driver has no binary attribute.Keithakeithley
with chrome it is p.children now instead p.get_childrenRollet
For some reason, this did not work when I am using firefox using geckodriver. In that case, the answer suggested by @Keithakeithley worked fineTague
From the psutil documentation: get_children is now children: pythonhosted.org/psutil/#psutil.Process.childrenMap
What about getting PID of RemoteBrowser? Please update if someone knows..Genovese
hello, @nmfzone, try to get remote browser's service instance.Traceytrachea
it return driver's pid, not browser's pid.Freightage
V
28

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...

Vacuous answered 21/12, 2018 at 15:56 Comment(3)
This is an answer, you don't need to apologize that it wasn't a comment. As far as rep, here is some so you will be able to comment. :)Pernickety
What about getting PID of RemoteBrowser? Please update if someone knows..Genovese
@Genovese See the answer below. (note that this answer returns the PID of the driver, at least for Firefox)Wetzell
K
12

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  
Keithakeithley answered 30/3, 2016 at 16:40 Comment(0)
N
9

You can retrieve the PID of Browser Process launched by Selenium using client in different ways as follows:


Firefox

Accessing the capabilities object 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']))
    
  • Console Output:

    PID of the browser process is: 14240
    
  • Browser Snapshot:

FirefoxPID


Chrome

Iterating through the processes using psutil.process_iter() where process.cmdline() contains --test-type=webdriver as follows:

  • Code Block:

    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)
    
  • Console Output:

    1164
    1724
    4380
    5748        
    
  • Browser Snapshot:

Chrome_Process

Nabokov answered 4/9, 2019 at 22:31 Comment(0)
O
8

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
Osbert answered 23/5, 2018 at 10:49 Comment(1)
Is this still the "simplest" way in Java?Jasminejason
C
2

This is an example you can use for C# and Selenium. There would be the same implementation for other languages (like Java) but I am only working in C#.

Chrome allows you to supply your own user-defined command-line arguments. So you can add an argument named "scriptpid-" with the PID (Windows Process ID) of your currently running program. ChromeDriver passes your argument to Chrome in the command-line. Then using Windows WMI calls retrieve this PID from the command-line of the running Chrome ...

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 should contain the HWND of your Chrome window.

CurrentBrowserPID should contain the Process ID of your Chrome window.

Christiechristin answered 11/7, 2020 at 11:29 Comment(0)
Y
1

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;
}
Yarrow answered 2/11, 2016 at 11:27 Comment(2)
Is this still the "simplest" way in Java? How do you adapt it for Chrome?Jasminejason
I don't know tbh, I wrote this answer 4 years ago, it has been a while since I used Selenium.Yarrow
F
1

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]])
Frunze answered 1/5, 2019 at 6:6 Comment(0)
H
1

I get this fast way to solved. On centos use java to fix chromedriver's quit(),close() doesn't work

WebDriver driver = new ChromeDriver(service,desiredCapabilities);
Integer port = service.getUrl().getPort();

List<Integer> pids = GetChromePidFromPort(port);
private static List<Integer> GetChromePidFromPort(Integer port) throws IOException {
        List<Integer> pidList = new ArrayList<>();
        Process process = Runtime.getRuntime().exec("lsof -i:" + port);
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.contains("chrome")) {
                int pid = Integer.parseInt(line.split("\\s+")[1]);
                System.out.println("PID: " + pid);
                pidList.add(pid);
                break;
            }
        }
        return pidList;
    }
Humbug answered 28/2, 2023 at 10:4 Comment(0)
B
0

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

        }
    }
Brunhilda answered 17/2, 2017 at 8:19 Comment(1)
Is this still the "simplest" way in Java?Jasminejason
P
0

@Sean Griffin's answer is great. One thing - better to filter the list of chrome processes by the ones that started in the last 5 (or so ) minutes, like this:

System.Diagnostics.Process[] processesInLast5Min =  processes.Where(p => DateTime.Now.Subtract(p.StartTime) <= TimeSpan.FromMinutes(5) ).ToArray();
Palikar answered 11/5, 2022 at 19:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.