Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run Selenium Webdriver with pythonw?

I'm trying to open Firefox browser in a Selenium script via a GUI application in Windows. It worked just fine while running with python.exe runw.py, but when I run it with pythonw.exe runw.py, the browser can't start. Instead, it throws me this exception:

Traceback (most recent call last):
  File "bin\runw.py", line 215, in process_instance
    instance.setup()
  File "bin\mixin.py", line 181, in setup
    self.browser = self.get_firefox_browser()
  File "bin\mixin.py", line 166, in get_firefox_browser
    firefox_binary=binary, firefox_profile=profile)
  File "C:\myvirtualenv\lib\site-packages\selenium\webdriver\firefox\webdriver.py", line 59, in __init__
    self.binary, timeout),
  File "C:\myvirtualenv\lib\site-packages\selenium\webdriver\firefox\extension_connection.py", line 47, in __init__
    self.binary.launch_browser(self.profile)
  File "C:\myvirtualenv\lib\site-packages\selenium\webdriver\firefox\firefox_binary.py", line 60, in launch_browser
    self._start_from_profile_path(self.profile.path)
  File "C:\myvirtualenv\lib\site-packages\selenium\webdriver\firefox\firefox_binary.py", line 83, in _start_from_profile_path
    env=self._firefox_env).communicate()
  File "C:\Python27\Lib\subprocess.py", line 702, in __init__
    errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
  File "C:\Python27\Lib\subprocess.py", line 833, in _get_handles
    p2cread = self._make_inheritable(p2cread)
  File "C:\Python27\Lib\subprocess.py", line 884, in _make_inheritable
    _subprocess.DUPLICATE_SAME_ACCESS)
WindowsError: [Error 6] The handle is invalid

The problem certainly lies on having no stdin or stdout (I'm not sure), because it fails in this line (firefox_binary.py):

def _start_from_profile_path(self, path):
    ...
    Popen(command, stdout=self._log_file, stderr=STDOUT,
          env=self._firefox_env).communicate()
    command[1] = '-foreground'
    self.process = Popen(
        command, stdout=self._log_file, stderr=STDOUT,
        env=self._firefox_env)

I've tried overriding syd.stdout with an output file before running the browser, but it didn't work:

sys.stdout = sys.stderr = open('log.txt', 'a+')

I'm running Python2.7 and Selenium 2.40. How can Selenium run with pythonw?

like image 834
augustomen Avatar asked May 26 '26 17:05

augustomen


1 Answers

Like @falsetru said, subprocess is trying to user file descriptor 0. The subprocess call will only work if all handles are valid (or if they are all None), and as pythonw is a Windows process and doesn't have any, I was forced to subclass FirefoxBinary to use nul handles:

class WindowsFirefoxBinary(FirefoxBinary):

    def _start_from_profile_path(self, path):
        self._firefox_env["XRE_PROFILE_PATH"] = path

        if platform.system().lower() == 'linux':
            self._modify_link_library_path()
        command = [self._start_cmd, "-silent"]
        if self.command_line is not None:
            for cli in self.command_line:
                command.append(cli)

        # Added stdin argument:
        nul = open(os.devnull, 'w+')
        Popen(command, stdin=nul, stdout=self._log_file or nul, stderr=STDOUT,
              env=self._firefox_env).communicate()
        command[1] = '-foreground'
        self.process = Popen(
            command, stdin=nul, stdout=self._log_file or nul, stderr=STDOUT,
            env=self._firefox_env)

This way I can use my own binary when creating the WebDriver instance:

binary = WindowsFirefoxBinary()
browser = webdriver.Firefox(firefox_binary=binary)

This may be a bug or simply incompatibility in Selenium with Python for Windows.

like image 150
augustomen Avatar answered May 28 '26 07:05

augustomen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!