Skip to main content
 首页 » 编程设计

python之使用pyinstaller和scrapy没有这样的文件或目录错误

2025年05月04日17wuhuacong

我有一个使用scrapy的python脚本,我想使用pyinstaller将其制作成exe文件。生成的exe文件没有任何错误,但是当我打开它时发生错误。

FileNotFoundError: [Errno 2] No such file or directory: '...\\scrapy\\VERSION' 


我尝试重新安装scrapy,但这没有帮助。我正在将Windows 10与python3一起使用

请您参考如下方法:

完全公开:这是我对重复的类似问题的回答的转贴。我只是为了可见而将其放在这里。这真正地回答了所提出的问题;因此很重要。

构建独立程序时,没有正确使用Pyinstaller。以下是对Pyinstaller的工作方式的简短介绍:Pyinstaller将Python解释器,必需的DLL(对于Windows),项目的源代码以及它可以找到的所有模块捆绑到文件夹或自解压的可执行文件中。 Pyinstaller不包含在运行Pyinstaller时产生的最终.exe(Windows)、. app(macOS),文件夹等中找不到的模块或文件。

所以,这是发生了什么:

 FileNotFoundError: [Errno 2] No such file or directory: '/tmp/_MEIbxALM3/scrapy/VERSION' 


您运行了冻结/独立程序。完成此操作后,程序便被“提取”到计算机 /temp/_MEIbxALM3/上的新临时文件夹中。该文件夹包含Python解释器,程序的源代码以及Pyinstaller设法找到的模块(以及其他一些必要的文件)。

Scrapy模块不仅仅是一个模块。这是一个完整的框架。它使用自己的纯文本文件(Python文件除外)。并且,它本身会导入很多模块。

Scrapy框架尤其不能与Pyinstaller配合使用,因为它使用许多方法来导入Pyinstaller无法“看到”的模块。另外,除非您告知Pyinstaller,否则基本上不会尝试在最终版本中包括不是.py文件的文件。

那么,到底发生了什么?

您计算机上的“普通”刮板模块中已存在的文本文件“版本”(已通过pip或pipenv安装)未包含在程序构建的copycat刮板模块中。 Scrapy需要此文件。 Python为您提供了 FileNotFoundError,因为它从未包含在内。因此,您必须使用Pyinstaller将文件包含在程序的构建中。

您如何告诉Pyinstaller在哪里找到模块和文件?

This guy表示只需将丢失的文件从计算机上的安装位置复制到从Pyinstaller吐出的build文件夹中。这确实有效。但是,有一种更好的方法,Pyinstaller可以为您完成更多工作(防止您得到更多的 ImportError和 FileNotFoundError)。见下文:

build.spec文件是您的朋友

spec文件只是Pyinstaller使用的Python文件(例如配置文件)来告诉它如何构建程序。阅读有关它们的更多信息 here。下面是一个真实的 build.spec文件的示例,我最近使用它来构建带有Windows的GUI的Scrapy程序(我的项目名为B.O.T. Bot):

import gooey 
gooey_root = os.path.dirname(gooey.__file__) 
gooey_languages = Tree(os.path.join(gooey_root, 'languages'), prefix = 'gooey/languages') 
gooey_images = Tree(os.path.join(gooey_root, 'images'), prefix = 'gooey/images') 
a = Analysis(['botbotgui.py'], 
             pathex=['C:\\Users\\Colton\\.virtualenvs\\bot-bot-JBkeVQQB\\Scripts', 'C:\\Program Files (x86)\\Windows Kits\\10\\Redist\\ucrt\\DLLs\\x86'], 
             hiddenimports=['botbot.spiders.spider'], 
             hookspath=['.\\hooks\\'], 
             runtime_hooks=None, 
             datas=[('.\\spiders\\','.\\spiders\\'), ('.\\settings.py','.'), 
                    ('.\\scrapy.cfg','.'), ('.\\items.py','.'), ('.\\itemloaders.py','.'), 
                    ('.\\middlewares.py','.'), ('.\\pipelines.py','.') 
                   ] 
             ) 
pyz = PYZ(a.pure) 
 
options = [('u', None, 'OPTION'), ('u', None, 'OPTION'), ('u', None, 'OPTION')] 
 
exe = EXE(pyz, 
          a.scripts, 
          a.binaries, 
          a.zipfiles, 
          a.datas, 
          options, 
          gooey_languages, # Add them in to collected files 
          gooey_images, # Same here. 
          name='BOT_Bot_GUI', 
          debug=False, 
          strip=None, 
          upx=True, 
          console=False, 
          windowed=True, 
          icon=os.path.join(gooey_root, 'images', 'program_icon.ico')) 
 
#coll = COLLECT(exe, 
    #a.binaries, 
    #a.zipfiles, 
    #a.datas, 
    #options, 
    #gooey_languages, # Add them in to collected files 
    #gooey_images, # Same here. 
    #name='BOT_Bot_GUI', 
    #debug=False, 
    #strip=False, 
    #upx=True, 
    #console=False, 
    #windowed=True, 
    #icon=os.path.join(gooey_root, 'images', 'program_icon.ico')) 


如果要构建文件夹而不是独立的 .exe,请取消注释最后一个区域。这是特定于我的计算机和项目结构的配置文件。因此,您必须在文件中进行一些更改(例如, pathex告诉Pyinstaller在Windows 10上可以找到DLL的位置。但是前提是相同的。

我的项目目录如下所示:

botbotgui.py  botbot.py  hooks  images  __init__.py  itemloaders.py  items.py  middlewares.py  pipelines.py  __pycache__  scrapy.cfg  settings.py  spiders 


特别注意 hooks/目录。使用钩子可以使您免于日后的头痛。阅读有关Pyinstaller的钩子功能 here的更多信息。在 hooks/目录中,有一个Scrapy的挂钩文件。这将告诉Pyinstaller包含许多模块和文件,如果您不使用 .spec文件,这些模块和文件将会丢失。到目前为止,这是我在这里写的最重要的内容。如果不执行此步骤,则每次尝试运行使用Pyinstaller构建的Scrapy程序时,您都会一直得到 ImportError。 Scrapy导入了许多Pyinstaller错过的模块。

hook-scrapy.py(注意:您的钩子文件必须这样命名。):

from PyInstaller.utils.hooks import collect_submodules, collect_data_files 
 
# This collects all dynamically imported scrapy modules and data files. 
hiddenimports = (collect_submodules('scrapy') + 
                 collect_submodules('scrapy.pipelines') + 
                 collect_submodules('scrapy.extensions') + 
                 collect_submodules('scrapy.utils') 
) 
datas = collect_data_files('scrapy') 


完成编写正确的 build.spec文件后,只需在shell提示符下运行Pyinstaller,如下所示:

pyinstaller build.spec 


然后,Pyinstaller应该吐出应该可以正常运行的程序。问题解决了。

那些Google希望为该问题或Pyinstaller或Scrapy的任何问题提供答案,请祈祷您找到我的答案。