使用pyinstaller和scrapy时没有此类文件或目录错误

06odsfpq  于 2022-11-09  发布在  其他
关注(0)|答案(2)|浏览(192)

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

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

我试过重新安装Scrapy,但没有帮助。我使用的是带有Python3的Windows 10

m4pnthwp

m4pnthwp1#

完全披露:这是我对一个重复的、类似的问题的回答的转贴。我把它放在这里只是为了看一看。这真实地回答了所问的问题;因此它是相关的。

当你编译独立程序时,你没有正确使用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文件 *,除非您告诉它 *。
"到底发生了什么事"
文本文件'VERSION'存在于您的计算机上的'normal' scrapy模块中(您已经用pip或pipenv安装了它),但它没有包含在您的程序版本中的copycat scrapy模块中。Scrapy需要这个文件; Python之所以给你FileNotFoundError,是因为它根本就没有被包含进去,所以你必须用Pyinstaller把这个文件包含在你的程序中。

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

This guy说只要把丢失的文件从你的电脑上安装的地方复制到你的build文件夹中就行了。这确实有效。但是,有一个更好的方法,Pyinstaller可以为你做更多的工作(防止你可能得到更多的ImportErrorFileNotFoundError)。见下面:

build.spec文件是您的好朋友

spec文件只是Python文件,Pyinstaller像配置文件一样使用它来告诉它如何构建你的程序。阅读更多关于它们的信息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/目录。使用hooks将为您省去很多麻烦。阅读更多关于Pyinstaller的hooks特性here的信息。在hooks/目录中有一个Scrapy的hooks文件。这将告诉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应该会吐出一个正确的构建程序,应该可以工作。问题解决了。

kxxlusnw

kxxlusnw2#

您可以在scrapy包中找到该文件。转到此路径:Python/Lib/site-packages/scrapy,你就会找到那个文件。下面是你接下来要做的步骤:
1.转到exe文件所在的目录,创建一个名为scrappy的文件夹。
1.从上面的路径中复制VERSIONmime.types。(如果不复制mime.types,则会出现另一个没有此类文件的错误。我只是在节省您的时间)
1.将这两个文件粘贴到您在步骤1中创建的scrapy文件夹中。
1.现在打开你的exe文件。如果出现No Module Error,你只需要导入你想使用Pyinstaller的文件中的相应模块。
祝你好运。

相关问题