简体   繁体   中英

Py2exe and selenium - IOError: [Errno 2] No such file or directory: '\\dist\\main.exe\\selenium\\webdriver\\firefox\\webdriver_prefs.json'

I wrote a simple application which uses selenium to nagivate through pages and download their source code. Now I would like to make my application Windows-executable.

My setup.py file:

from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')

setup(
    options = {'py2exe': {'bundle_files': 1,
                          "dll_excludes": ['w9xpopen.exe', 'MSVCP90.dll', 'mswsock.dll', 'powrprof.dll', 'MPR.dll', 'MSVCR100.dll', 'mfc90.dll'],
                          'compressed': True,"includes":["selenium"],
                          }
              },
    windows = [{'script': "main.py", "icon_resources": [(1, "hacker.ico")]}],
    zipfile = None
)

My program ( main.py ) (with setup.py file) is located in C:\\Documents and Settings\\student\\Desktop . Py2exe builds my exe in C:\\Documents and Settings\\student\\Desktop\\dist .

I copied both webdriver.xpi and webdriver_prefs.json files to C:\\Documents and Settings\\student\\Desktop\\dist\\selenium\\webdriver\\firefox\\ , but I'm getting the error when trying to launch my application:

Traceback (most recent call last):
  File "main.py", line 73, in <module>
  File "main.py", line 58, in check_file
  File "main.py", line 25, in try_to_log_in
  File "selenium\webdriver\firefox\webdriver.pyo", line 47, in __init__
  File "selenium\webdriver\firefox\firefox_profile.pyo", line 63, in __init__
IOError: [Errno 2] No such file or directory: 'C:\\Documents and Settings\\student\\Desktop\\dist\\main.exe\\selenium\\webdriver\\firefox\\webdriver_prefs.json'

How to solve this?

Actually, it worked with such setup.py file:

from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')

wd_path = 'C:\\Python27\\Lib\\site-packages\\selenium\\webdriver'
required_data_files = [('selenium/webdriver/firefox',
                        ['{}\\firefox\\webdriver.xpi'.format(wd_path), '{}\\firefox\\webdriver_prefs.json'.format(wd_path)])]

setup(
    windows = [{'script': "main.py", "icon_resources": [(1, "hacker.ico")]}],
    data_files = required_data_files,
    options = {
               "py2exe":{
                         "skip_archive": True,
                        }
               }
)

But the problem is I need to build SINGLE executable.

Have you tried to have a look at this answer for the "bundle_files = 1" problems? It helped me solving that specific problem.

TL;DR --Please check out this tool I built: https://github.com/douglasmccormickjr/PyInstaller-Assistance-Tools--PAT

Might I suggest using PyInstaller instead of py2exe or anything else for that matter since PyInstaller does a far better job in terms of bundling a single executable. I'm on Windows about 90% of the time (no complaints here) with my python coding-- PyInstaller is a way better option than py2exe (for me at least -- I've used/test a great deal of Windows compilers in the past with varied success). Maybe other people suffering from compiling issues could benefit from this method as well.

PyInstaller Prerequisites:

  1. Install PyInstaller from: http://www.pyinstaller.org/
  2. After PyInstaller installation-- confirm both "pyi-makespec.exe" and "pyi-build.exe" are in the "C:\\Python##\\Scripts" directory on your machine
  3. Download my PyInstaller-Assitance-Tools--PAT (it's just 2 batch files and 1 executable with the executable's source python file too -- for the paranoid)...The file are listed above:

    • Create_Single_Executable_with_NO_CONSOLE.bat
    • Create_Single_Executable_with_CONSOLE.bat
    • pyi-fixspec.exe
    • pyi-fixpec.py (optional -- this is the source file for the executable -- not needed)
  4. Place the exectuable file called "pyi-fixspec.exe" inside the previous "Scripts" folder I mentioned above ...this makes compiling much easier in the long run!

let's get it working now...some slight code changes to your python application

  1. I use a standard function that references the location of applications/scripts that my python application needs to utilize to work while being executed/operated. This function operates both when the app is a standalone python script or when it's fully compiled via pyinstaller.

    Here's the piece of code I use...

     def resource_path(relative_path): """ Get absolute path to resource, works for dev and for PyInstaller """ if hasattr(sys, '_MEIPASS'): return os.path.join(sys._MEIPASS, relative_path) return os.path.join(os.path.abspath("."), relative_path) 

    and here's my app using it....

     source = resource_path("data\\my_archive_file.zip") 

    that means the app/files look something like this in terms of directory structure:

     C:\\Path\\To\\Application\\myscript_001.py <--- main application/script intended to be compiled ... C:\\Path\\To\\Application\\data\\my_archive_file.zip <---| C:\\Path\\To\\Application\\data\\images\\my_picture.jpg <---| supporting files in the bundled app C:\\Path\\To\\Application\\info\\other_stuff.json <---| ... 

    Please note that the data/files/folders I'm bundling for my app are below the main executable/script that I'll be compiling...the "_MEIPASS" part in the function lets pyinstaller know that it's working as a compiled application... VERY IMPORTANT NOTE: Please use the function "resource_path" since the "pyi-fixspec.exe" application will be looking for that phrase/function while parsing/correcting the python application pathing

  2. Goto the directory containing the 2 batch files mentioned above and type in either:

    Option #1
     C:\\MyComputer\\Downloads\\PAT> Create_Single_Executable_with_NO_CONSOLE.bat C:\\Path\\to\\the\\python\\file.py 

    The output executable file results in a GUI app when double clicked

    Option #2
     C:\\MyComputer\\Downloads\\PAT> Create_Single_Executable_with_CONSOLE.bat C:\\Path\\to\\the\\python\\file.py 

    The output executable file results in a WINDOWS CONSOLE app when double clicked -- expects commandline activity ONLY

  3. Your new single-file-executable is done! Check for it in this location

     C:\\Original\\Directory\\ApplicationDistribution64bit\\NameOfPythonFile\\dist 

    If you do edit/change the original python file that has just been previously compiled, please delete the folder/contents of **\\NameOfPythonFile** prior to next compile kickoff (you'll want to delete the historical/artifact files)

  4. Coffee break -- or if you wany to edit/add ICONS to the executable (and other items too), please look at the generated ".spec" file and PyInstaller documentation for configuration details. You'll just need to kick off this again in the windows console:

     pyi-build.exe C:\\path\\to\\the\\pythonfile.spec 

You can build a single executable, which will run natively, by using Nuitka. It converts the Python code into C++ and then compiles it.

http://nuitka.net/

It does, however, require that you have a compiler installed. The appropriate versions of either Microsoft Visual C++ or GCC. Microsoft released "Microsoft Visual C++ Compiler for Python 2.7", which can be obtained here at https://www.microsoft.com/en-us/download/details.aspx?id=44266 .

A nice installer of MinGW GCC for windows can be found at https://github.com/develersrl/gccwinbinaries with detailed instructions, including which MSVCRTXX.dll version to link with for which version of Python.

Things you will gain from this method of executable generation:

The problem you have is that selenium is trying to open a file in a way that is not directly compatible with py2exe.

As you can see at line 63 here , selenium must open a preferences file that is usually shipped with the package. It uses the __file__ variable to find it, which doesn't play well with py2exe . As you have found, it is possible to work around that by also packaging up the prefs file in your distribution . However, that is now more than one file.

The py2exe wiki then has a recipe to use NSIS that will build a self-extracting executable of your complete distribution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM