使用PyInstaller打包Scrapy脚本时出现文件或目录不存在错误
解决Scrapy脚本PyInstaller打包exe后「No such file or directory」问题
我之前也踩过Scrapy打包成exe的这个坑,这个问题大多是PyInstaller没把Scrapy的依赖资源(比如配置文件、内置模板)打包进去,或者运行时路径识别出了问题。给你几个针对性的解决办法:
1. 手动指定Scrapy的资源路径
打包成exe后,程序会在临时目录运行,和原脚本的路径完全不同,导致Scrapy找不到自己的内置文件。你可以在脚本开头加入路径适配代码:
import scrapy import sys import os # 区分打包后和正常脚本环境 if getattr(sys, 'frozen', False): # 打包后的exe环境,获取临时资源目录 scrapy_resource_path = os.path.join(sys._MEIPASS, 'scrapy') # 强制指定Scrapy的配置模块路径 os.environ['SCRAPY_SETTINGS_MODULE'] = '你的项目名称.settings' # 把Scrapy资源目录加入系统路径 sys.path.append(scrapy_resource_path) else: # 正常开发环境,无需额外处理 pass
2. 用--add-data参数手动补全缺失文件
PyInstaller默认会漏掉Scrapy的一些必要资源,打包时需要手动指定要包含的文件:
打开命令行进入你的项目根目录,执行打包命令时加上--add-data:
pyinstaller --onefile --add-data "你的Python环境路径/Lib/site-packages/scrapy;scrapy" 你的启动脚本.py
注意:Windows系统下路径分隔符用;,把你的Python环境路径换成你实际的路径(比如用虚拟环境的话就是venv/Lib/site-packages/scrapy)。
3. 修复脚本中的硬编码路径
如果你的脚本里有用硬编码的本地路径(比如读取自定义配置、本地文件),打包后exe的工作目录和你开发时不一样,就会找不到文件。改成动态路径:
import sys import os # 获取当前程序的根路径 if getattr(sys, 'frozen', False): base_dir = sys._MEIPASS else: base_dir = os.path.dirname(os.path.abspath(__file__)) # 用base_dir拼接你的文件路径 custom_config = os.path.join(base_dir, 'config.json')
4. 改用爬虫类直接启动的方式打包
很多人打包自己写的启动脚本容易出问题,试试直接调用Scrapy的爬虫类来启动:
先写一个简单的启动脚本run_spider.py:
from scrapy.crawler import CrawlerProcess from scrapy.utils.project import get_project_settings # 导入你的爬虫类 from 你的项目名.spiders.你的爬虫文件名 import 你的爬虫类 process = CrawlerProcess(get_project_settings()) process.crawl(你的爬虫类) process.start()
然后用PyInstaller打包这个run_spider.py,同时加上前面说的--add-data参数,这样更贴合Scrapy的运行逻辑。
5. 查看详细错误日志定位问题
如果上面的方法都没用,让exe输出详细日志,看看具体是哪个文件找不到:
在脚本开头加入日志配置:
import logging logging.basicConfig(level=logging.DEBUG)
运行exe后看控制台的错误信息,找到缺失的文件,再用--add-data手动把它打包进去。
内容的提问来源于stack exchange,提问作者Dainius Preimantas
相关产品推荐
相关产品推荐

