Frage

I'm using py2exe to compile a Python 2.7 script that uses Selenium 2.39.0 to open up Firefox windows and carry out some routines. In the past, I've been able to compile the code without any issue. Today though, after updating from Selenium 2.35 to 2.39, I'm running into trouble. When I try to run the .exe generated by the compiled code, I get the following error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "Tkinter.pyo", line 1410, in __call__
  File "literatureonlineapi2.5.5.py", line 321, in startapi
  File "selenium\webdriver\firefox\webdriver.pyo", line 43, in __init__
  File "selenium\webdriver\firefox\firefox_profile.pyo", line 58, in __init__
IOError: [Errno 2] No such file or directory: 'C:\\Text\\Professional\\Digital H
umanities\\Programming Languages\\Python\\Query Literature Online\\LION 1.0\\2.5
\\2.5.5\\dist\\.\\selenium\\webdriver\\firefox\\webdriver_prefs.json'
Here we go!
Exception in Tkinter callback
Traceback (most recent call last):
  File "Tkinter.pyo", line 1410, in __call__
  File "literatureonlineapi2.5.5.py", line 321, in startapi
  File "selenium\webdriver\firefox\webdriver.pyo", line 43, in __init__
  File "selenium\webdriver\firefox\firefox_profile.pyo", line 58, in __init__
IOError: [Errno 2] No such file or directory: 'C:\\Text\\Professional\\Digital H
umanities\\Programming Languages\\Python\\Query Literature Online\\LION 1.0\\2.5
\\2.5.5\\dist\\.\\selenium\\webdriver\\firefox\\webdriver_prefs.json'

(This error does not appear when I run the uncompiled code.)

I came across a google code page that led me to believe newer versions of Selenium have had trouble with this missing webdriver_prefs.json file, but that didn't help me sort out the problem.

Does anyone know how I might manually provide the missing file? I would be grateful for any help others can offer.

War es hilfreich?

Lösung

I found a solution, and thought I would post it in case others have a similar problem. I found the missing webdriver_prefs.json file tucked away in

C:\Python27\Lib\site-packages\selenium-2.39.0-py2.7.egg\selenium\webdriver\firefox\

After I had navigated to that directory, I grabbed the webdriver_prefs.json file and the webdriver.xpi file. I then copied both of those files into

dist\selenium\webdriver\firefox\

created by py2exe, and was able to run the compiled code as expected. God save the queen.

Andere Tipps

I did the following to fix the problem:

  1. Create a sub-folder \selenium\webdriver\firefox\ under dist.
  2. Under command DOS prompt, enter python.exe setup_firefox.py
  3. You could either running the executable under dist or copy all the files under "dist" to your own directory and run the executable from there.

Here is my setup_firefox.py:

from distutils.core import setup
import py2exe,sys,os

sys.argv.append('py2exe')

setup(
    console=[{'script':"test.py"}],
    options={
        "py2exe":{
                "skip_archive": True,
                "unbuffered": True,
                "optimize": 2
        },
    }
)

I had a related issue for which I have found a work round...

My issue

I was trying to run a python script that uses Selenium 2.48.0 and worked fine on the development machine but failed to open Firefox when py2exe'ed with the error message:

[Errno 2] No such file or directory:'C:\test\dist\library.zip\selenium\webdriver\firefox\webdriver_prefs.json'

Cause

I traced the problem to the following file in the selenium package

 C:\Python27\Lib\site-packages\selenium\webdriver\firefox\firefox_profile.py

It was trying to open webdriver_prefs.json and webdriver.xpifrom the same parent directory

This works fine when running on the development machine but when the script is run through py2exe firefox_profile.pyc is added to library.zip but webdriver_prefs.json and webdriver.xpi aren't.

Even if you manual add these files to appropriate location in the zip file you will still get the 'file not found' message.

I think this is because the Selenium file can't cope with opening files from within the zip file.

Work Round

My work round was to get py2exe to copy the two missing files to the dist directory and then modify firefox_profile.py to check the directory string. If it contained .zip modify the string to look in the parent directory

webdriver_prefs.json

class FirefoxProfile(object):
    def __init__(self, profile_directory=None):
        if not FirefoxProfile.DEFAULT_PREFERENCES:
            '''
            The next couple of lines attempt to WEBDRIVER_PREFERENCES json file from the directory
            that this file is located.

            However if the calling script has been converted to an exe using py2exe this file will
            now live within a zip file which will cause the open line to fail with a 'file not found'
            message. I think this is because open can't cope with opening a file from within a zip file.

            As a work round in our application py2exe will copy the preference to the parent directory
            of the zip file and attempt to load it from there

            '''
            if '.zip' in os.path.join(os.path.dirname(__file__)) :
                # find the parent dir that contains the zipfile
                parentDir = __file__.split('.zip')[0]
                configFile = os.path.join(os.path.dirname(parentDir), WEBDRIVER_PREFERENCES)
                print "Running from within a zip file, using [%s]" % configFile 
            else:    
                configFile = os.path.join(os.path.dirname(__file__), WEBDRIVER_PREFERENCES)

            with open(configFile) as default_prefs:
               FirefoxProfile.DEFAULT_PREFERENCES = json.load(default_prefs)

webdriver.xpi

    def _install_extension(self, addon, unpack=True):
        if addon == WEBDRIVER_EXT:
            addon = os.path.join(os.path.dirname(__file__), WEBDRIVER_EXT)

        tmpdir = None
        xpifile = None

        '''
        The next couple of lines attempt to install the webdriver xpi from the directory
        that this file is located.

        However if the calling script has been converted to an exe using py2exe this file will
        now live within a zip file which will cause the script to fail with a 'file not found'
        message. I think this is because it can't cope with opening a file from within a zip file.

        As a work round in our application py2exe will copy the .xpi to the parent directory
        of the zip file and attempt to load it from there
        '''
        if '.zip' in addon :
            # find the parent dir that contains the zipfile
            parentDir = os.path.dirname(addon.split('.zip')[0])
            addon = os.path.join(parentDir, os.path.basename(addon))
            print "Running from within a zip file, using [%s]" % addon

        if addon.endswith('.xpi'):
            tmpdir = tempfile.mkdtemp(suffix='.' + os.path.split(addon)[-1])
            compressed_file = zipfile.ZipFile(addon, 'r')
            for name in compressed_file.namelist():
                if name.endswith('/'):
                    if not os.path.isdir(os.path.join(tmpdir, name)):
                        os.makedirs(os.path.join(tmpdir, name))
                else:
                    if not os.path.isdir(os.path.dirname(os.path.join(tmpdir, name))):
                        os.makedirs(os.path.dirname(os.path.join(tmpdir, name)))
                    data = compressed_file.read(name)
                    with open(os.path.join(tmpdir, name), 'wb') as f:
                        f.write(data)
            xpifile = addon
            addon = tmpdir

I found the sulution, the py2exe can't open zip file. So after copy the webdriver_prefs.json and webdriver.xpi, decompression the library.zip into a folder named "library.zip"

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top