scinstore上的Pyinstaller错误?

coo*_*ler 2 python pyinstaller scrapy

我正在使用scrapy导入它.我使用pyinstaller构建了python文件.构建它之后,我运行了./new.py文件.但错误弹出:

 FileNotFoundError: [Errno 2] No such file or directory: '/tmp/_MEIbxALM3/scrapy/VERSION'
[23450] Failed to execute script new
Run Code Online (Sandbox Code Playgroud)

col*_*ins 7

在构建独立程序时,没有正确使用Pyinstaller.下面是一个简短的外行人对Pyinstaller如何工作的描述:Pyinstaller将Python解释器,必要的DLL(用于Windows),项目的源代码以及它可以找到的所有模块捆绑到一个文件夹或自解压可执行文件中.Pyinstaller不包含在运行Pyinstaller时导致的最终.exe(Windows),. app(macOS),文件夹等中找不到的模块或文件.

那么,这是发生了什么:

 FileNotFoundError: [Errno 2] No such file or directory: '/tmp/_MEIbxALM3/scrapy/VERSION'
Run Code Online (Sandbox Code Playgroud)

您运行了冻结/独立程序.一旦执行此操作,您的程序就会"解压缩"到计算机上的新临时文件夹中/temp/_MEIbxALM3/.该文件夹包含Python解释器,程序的源代码以及Pyinstaller设法找到的模块(以及其他一些必要的文件).

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

Scrapy框架尤其与Pyinstaller不相处,因为它使用许多方法来导入Pyinstaller无法"看到"的模块.此外,Pyinstaller基本上不会尝试在最终版本中包含不是.py文件的文件,除非你告诉它.

真的发生了什么?

计算机上"正常"scrapy模块中存在的文本文件"VERSION"(您使用pip或pipenv安装)未包含在程序构建中的模块scrapy模块中.Scrapy需要这个文件; Python正在给你,FileNotFoundError因为它从未包含在内.因此,您必须使用Pyinstaller将该文件包含在程序的构建中.

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

这个人说只需将丢失的文件从计算机上安装到你的构建文件夹中,然后从Pyinstaller中吐出.这确实有效.但是,有一种更好的方法,Pyinstaller可以为你做更多的工作(防止你可能获得进一步的ImportErrors和FileNotFoundErrors).见下文:

build.spec 档案是你的朋友

spec文件只是Pyinstaller使用的Python文件,就像配置文件一样,告诉它如何构建程序.在这里阅读更多相关信息.下面是build.spec我最近用于构建带有GUI for Windows的Scrapy程序的真实文件示例(我的项目名称是BOT 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'))
Run Code Online (Sandbox Code Playgroud)

如果要构建文件夹而不是独立文件夹,请取消注释最后一个区域.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
Run Code Online (Sandbox Code Playgroud)

要特别注意hooks/目录.使用挂钩可以避免您在路上遇到很多麻烦.在这里阅读有关Pyinstaller的钩子功能的更多信息.在hooks/目录中有一个Scrapy的钩子文件.这将告诉Pyinstaller包含许多模块和文件,如果你不使用文件,它将会丢失.spec.到目前为止,这是我在这里写的最重要的事情.如果您不执行此步骤,则ImportError每次尝试运行使用Pyinstaller构建的Scrapy程序时都会继续执行此操作.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')
Run Code Online (Sandbox Code Playgroud)

编写完正确的build.spec文件后,您需要做的就是在shell提示符下运行Pyinstaller:

pyinstaller build.spec
Run Code Online (Sandbox Code Playgroud)

然后Pyinstaller应该吐出适当的程序版本,该程序应该有效.问题解决了.

那些谷歌正在回答这个问题,或者与Pyinstaller或Scrapy有任何问题,祈祷你找到答案.