使用PyInstaller将Python Scrapy转换为EXE文件

j0pj023g  于 2023-03-30  发布在  Python
关注(0)|答案(1)|浏览(178)

我正在尝试将Scrapy脚本转换为EXE文件。main.py 文件如下所示:

from scrapy.crawler import CrawlerProcess
from amazon.spiders.amazon_scraper import Spider

spider = Spider()
process = CrawlerProcess({
    'FEED_FORMAT': 'csv',
    'FEED_URI': 'data.csv',
    'DOWNLOAD_DELAY': 3,
    'RANDOMIZE_DOWNLOAD_DELAY': True,
    'ROTATING_PROXY_LIST_PATH': 'proxies.txt',
    'USER_AGENT_LIST': 'useragents.txt',
    'DOWNLOADER_MIDDLEWARES' :
    {
        'rotating_proxies.middlewares.RotatingProxyMiddleware': 610,
        'rotating_proxies.middlewares.BanDetectionMiddleware': 620,
        'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
        'random_useragent.RandomUserAgentMiddleware': 400
    }
})

process.crawl(spider)
process.start() # The script will block here until the crawling is finished

Scrapy脚本看起来和其他脚本一样。我使用pyinstaller.exe --onefile main.py将其转换为EXE文件。当我尝试打开dist文件夹中的 main.exe 文件时,它开始输出错误:

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

我可以通过在dist文件夹中创建一个scrapy文件夹并从lib/site-packages/scrapy上传一个VERSION文件来修复它。之后,会出现许多其他错误,但我可以通过上传一些scrapy库来修复它们。
最后,它开始输出一个错误:

ModuleNotFoundError: No module named 'email.mime'

我都不知道那是什么意思。我从没见过。
我正在使用:

  • Python 3.6.5语言
  • Scrapy 1.5
  • PyInstaller 3.3.1
6kkfgxo0

6kkfgxo01#

我也有同样的情况。
我没有尝试让PyInstaller计算这个文件(我所有的尝试都失败了),而是决定检查并更改Scrapy代码的某些部分以避免这个错误。
我注意到只有一个地方使用\scrapy\VERSION文件-\scrapy*init*.py
我决定通过修改 * scrapy_init_.py* 来硬编码 scrapy\version 中的值:

#import pkgutil
__version__ = "1.5.0" #pkgutil.get_data(__package__, 'VERSION').decode('ascii').strip()
version_info = tuple(int(v) if v.isdigit() else v
                     for v in __version__.split('.'))
#del pkgutil

在此更改之后,不需要将版本存储在外部文件中。由于没有任何对\scrapy\version文件的引用,因此不会发生该错误。
在那之后,我有相同的FileNotFoundError: [Errno 2]\scrapy\mime.types文件。
文件 \scrapy\mime.types 也有同样的情况。它只在文件\scrapy\responsetypes.py中使用。

...
#from pkgutil import get_data
...
    def __init__(self):
        self.classes = {}
        self.mimetypes = MimeTypes()
        #mimedata = get_data('scrapy', 'mime.types').decode('utf8')
        mimedata = """
        Copypaste all 750 lines of \scrapy\mime.types here
"""
        self.mimetypes.readfp(StringIO(mimedata))
        for mimetype, cls in six.iteritems(self.CLASSES):
            self.classes[mimetype] = load_object(cls)

我同意将750行文本硬编码到Python代码中不是最好的决定。
之后,我开始接收ModuleNotFoundError: No module named scrapy.spiderloader。我将"scrapy.spiderloader"添加到pyinstaller的隐藏导入参数中。
下一篇:ModuleNotFoundError: No module named scrapy.statscollectors
Scrapy脚本的PyInstaller命令的最终版本包含46个隐藏导入。之后,我收到了一个工作的EXE文件。

相关问题