我有一个使用scrapy的python脚本,我想使用pyinstaller将其生成一个exe文件。exe文件生成时没有任何错误,但当我打开它时出现错误。
FileNotFoundError: [Errno 2] No such file or directory: '...\\scrapy\\VERSION'
我试过重新安装Scrapy,但没有帮助。我使用的是带有Python3的Windows 10
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把这个文件包含在你的程序中。
/temp/_MEIbxALM3/
FileNotFoundError
如何告诉Pyinstaller在哪里可以找到模块和文件?
This guy说只要把丢失的文件从你的电脑上安装的地方复制到你的build文件夹中就行了。这确实有效。但是,有一个更好的方法,Pyinstaller可以为你做更多的工作(防止你可能得到更多的ImportError和FileNotFoundError)。见下面:
ImportError
build.spec文件是您的好朋友
build.spec
spec文件只是Python文件,Pyinstaller像配置文件一样使用它来告诉它如何构建你的程序。阅读更多关于它们的信息here。下面是一个真实的build.spec文件的例子,我最近用它来构建一个带有Windows GUI的Scrapy程序(我的项目的名称是B. O.T. Bot):
spec
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。但是,前提是相同的。我的项目目录如下所示:
.exe
pathex
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遗漏的许多模块。
hooks/
.spec
hook-scrapy.py(注:挂钩文件的名称必须与此相同。):
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应该会吐出一个正确的构建程序,应该可以工作。问题解决了。
kxxlusnw2#
您可以在scrapy包中找到该文件。转到此路径:Python/Lib/site-packages/scrapy,你就会找到那个文件。下面是你接下来要做的步骤:1.转到exe文件所在的目录,创建一个名为scrappy的文件夹。1.从上面的路径中复制VERSION和mime.types。(如果不复制mime.types,则会出现另一个没有此类文件的错误。我只是在节省您的时间)1.将这两个文件粘贴到您在步骤1中创建的scrapy文件夹中。1.现在打开你的exe文件。如果出现No Module Error,你只需要导入你想使用Pyinstaller的文件中的相应模块。祝你好运。
2条答案
按热度按时间m4pnthwp1#
完全披露:这是我对一个重复的、类似的问题的回答的转贴。我把它放在这里只是为了看一看。这真实地回答了所问的问题;因此它是相关的。
当你编译独立程序时,你没有正确使用Pyinstaller。下面是一个简短的、外行的Pyinstaller工作原理的描述:Pyinstaller将Python解释器、必要的DLL(Windows)、项目的源代码和***所有它能找到的模块***捆绑到一个文件夹或自解压可执行文件中。Pyinstaller不包括在运行Pyinstaller时最终的.exe(Windows)、.app(macOS)、文件夹等中找不到的模块或文件。
所以,事情是这样的:
你运行了你的冻结/独立程序。一旦你这样做了,你的程序就被“解压缩”到你的计算机
/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可以为你做更多的工作(防止你可能得到更多的
ImportError
和FileNotFoundError
)。见下面:build.spec
文件是您的好朋友spec
文件只是Python文件,Pyinstaller像配置文件一样使用它来告诉它如何构建你的程序。阅读更多关于它们的信息here。下面是一个真实的build.spec
文件的例子,我最近用它来构建一个带有Windows GUI的Scrapy程序(我的项目的名称是B. O.T. Bot):如果你想构建一个文件夹,而不是一个独立的
.exe
,取消注解最后一个区域。这是一个特定于我的计算机和项目结构的配置文件。所以在你的文件中,你必须更改一些东西(例如pathex
,以告诉Pyinstaller在Windows 10上哪里可以找到DLL。但是,前提是相同的。我的项目目录如下所示:
要特别注意
hooks/
目录。使用hooks将为您省去很多麻烦。阅读更多关于Pyinstaller的hooks特性here的信息。在hooks/
目录中有一个Scrapy的hooks文件。这将告诉Pyinstaller包含许多模块和文件 * 如果您没有使用.spec
文件,* 它可能会遗漏 *。****如果你不做这一步,每次你试图运行一个用Pyinstaller构建的Scrapy程序时,你都会得到ImportError
。Scrapy导入了Pyinstaller遗漏的许多模块。hook-scrapy.py
(注:挂钩文件的名称必须与此相同。):编写完一个合适的
build.spec
文件后,只需在shell提示符下运行Pyinstaller,如下所示:Pyinstaller应该会吐出一个正确的构建程序,应该可以工作。问题解决了。
kxxlusnw2#
您可以在scrapy包中找到该文件。转到此路径:Python/Lib/site-packages/scrapy,你就会找到那个文件。下面是你接下来要做的步骤:
1.转到exe文件所在的目录,创建一个名为scrappy的文件夹。
1.从上面的路径中复制VERSION和mime.types。(如果不复制mime.types,则会出现另一个没有此类文件的错误。我只是在节省您的时间)
1.将这两个文件粘贴到您在步骤1中创建的scrapy文件夹中。
1.现在打开你的exe文件。如果出现No Module Error,你只需要导入你想使用Pyinstaller的文件中的相应模块。
祝你好运。