1

After an exhaustive amount of Googling, I'm at a loss as to how to connect to a CefPython (Chrome Embedded Framework) browser instance using Selenium.

I see two possible ways of going about this:

  1. Use Selenium to launch a CefPython instance directly, or
  2. Launch a CefPython instance independently, then connect to it with Selenium.

I've looked for similar questions but they either have non-working code (older versions?) or seem to be attempting to do other things, and I can't find any with actual working code snippets as answers. So as a starting point, here is working code for launching Chrome with Selenium, but using a standard non-CEF Chrome instance:

Option 1 (working; launch standard Chrome.exe with Selenium)

from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--disable-gpu")

chromedriver_path = r"C:\Users\..\webdrivers\chromedriver_2_40\chromedriver_win32\chromedriver.exe"
chrome_path = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
options.binary_location = chrome_path;

driver = webdriver.Chrome(executable_path=chromedriver_path, options=options)
time.sleep(1)
driver.get("https://www.google.com") # SUCCESS!
time.sleep(4)
driver.quit()

Option 2 (working; launch Chrome.exe then connect to it with Selenium)

In this example, "driver2" is the one connecting remotely to the already-running instance created by "driver."

from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--disable-gpu")

chromedriver_path = r"C:\Users\..\webdrivers\chromedriver_2_40\chromedriver_win32\chromedriver.exe"

chrome_path = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
options.binary_location = chrome_path;

driver = webdriver.Chrome(executable_path=chromedriver_path, options=options)
executor_url = driver.command_executor._url
session_id = driver.session_id
print(executor_url, session_id)

driver2 = webdriver.Remote(command_executor=executor_url, desired_capabilities={})
driver2.close() # close the second session created by driver 2 (cannot pass a session_id to webdriver.Remote())
driver2.session_id = session_id # use the driver1 session instead
time.sleep(1)
driver2.get("https://www.google.com") # SUCCESS!
time.sleep(4)
driver2.quit()

But when I try to make this work with CefPython, I am at a loss for how to do it.

Option 1 (non-working; CefPython instance)

Attempting Option 1 with CefPython just hangs for a while before raising an exception. The only executable in the CefPython package I see that Selenium could possibly use to launch is the subprocess.exe file, but clearly this is NOT just a drop-in replacement for chrome.exe.

This code is identical to the "Option 1" code above, except it swaps the chrome_path for the subprocess.exe binary.

from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--disable-gpu")

chromedriver_path = r"C:\Users\..\webdrivers\chromedriver_2_40\chromedriver_win32\chromedriver.exe"
chrome_path = r"C:\Users\..\project-folder\pybin\Lib\site-packages\cefpython3\subprocess.exe"
options.binary_location = chrome_path;

driver = webdriver.Chrome(executable_path=chromedriver_path, options=options)
print('driver created...') # is never reached :( apparently hangs over socket waiting...
# after a while...
# selenium.common.exceptions.WebDriverException: Message: unknown error: DevToolsActivePort file doesn't exist
time.sleep(1)
driver.get("https://www.google.com") 
time.sleep(4)
driver.quit()

Option 2 (non-working; CefPython instance)

Here I try to launch CEFPython independently, then connecting to it with Selenium. Attempting this leaves me with needing an executor_url and a session Id, however I cannot for the life of me figure out how to get these from a running CefPython instance:

from cefpython3 import cefpython as cef
from selenium import webdriver

settings = {"windowless_rendering_enabled": False}
switches = {"remote-debugging-port": "22222",
            'user-data-dir':r"C:\Users\..\..\mydatadir"}
cef.Initialize(settings, switches)

executor_url = None # how to get this?
session_id = None # how to get this?

driver2 = webdriver.Remote(command_executor=executor_url, desired_capabilities={})
driver2.close() # close the driver 1 session (cannot pass a session_id to webdriver.Remote())
driver2.session_id = session_id
time.sleep(30)
driver2.get("https://www.google.com")
time.sleep(4)
driver2.quit()

I'm using the 2.40 version of ChromeDriver, because the latest version of CefPython uses Chrome version 66, which in turn requires version 2.40 of the chromedriver.

Any assistance is appreciated.

0 Answers0