I would like to get the PID of the browser launched by selenium. Is there any way to get it done?
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]])
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
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...
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) {
}
}
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.