Py2exe isn't copying webdriver_prefs.json into builds

前端 未结 4 586
小蘑菇
小蘑菇 2020-12-21 10:54

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 th

4条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-21 11:07

    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
    

提交回复
热议问题