Python Scrapy преобразование в EXE-файл с помощью Pyinstaller - PullRequest
0 голосов
/ 23 мая 2018

Я пытаюсь преобразовать сценарий scrapy в исполняемый файл.Файл 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

Скриптовый скрипт выглядит как любой другой.Я использую pyinstaller.exe --onefile main.py, чтобы преобразовать его в исполняемый файл.Когда я пытаюсь открыть файл main.exe в папке dist, он начинает выводить ошибки:

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

Я могу это исправить, создав папку scrapy внутри папки dist и загрузив файл VERSION из lib / site-пакеты / SCRAPY.После этого возникает много других ошибок, но я могу исправить их, загрузив некоторые библиотеки scrapy.

В конце концов, он начинает выводить ошибку:

ModuleNotFoundError: No module named 'email.mime'

Я даже не знаю, что это делаетимею в виду.Я никогда не видел это.

Я использую:

Python 3.6.5
Scrapy 1.5.0
pyinstaller 3.3.1

1 Ответ

0 голосов
/ 09 февраля 2019

У меня была такая же ситуация.
Вместо того, чтобы пытаться заставить pyinstaller подсчитать этот файл (я потерпел неудачу во всех моих попытках сделать это), я решил проверить и изменить некоторую часть кода scrapy, чтобы избежать этой ошибки.

Я заметил, что есть только одно место, где используется файл \ scrapy \ VERSION -- \ scrapy \ __ init __. Py
Я решил жестко закодировать это значение изscrapy \ version путем изменения scrapy__init__.py:

#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 file.
С \ 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)

Это изменение разрешено FileNotFoundError: [Errno 2] с помощью \ scrapy \ mimeФайл .types.Я согласен, что жесткое кодирование 750 строк текста в код Python - не лучшее решение.

После этого я начал получать ModuleNotFoundError: No module named scrapy.spiderloader.Я добавил "scrapy.spiderloader" в скрытый параметр импорта pyinstaller.
Следующий выпуск ModuleNotFoundError: No module named scrapy.statscollectors.
Финальная версия команды pyinstaller для моего скриптового сценария состоит из 46 скрытых импортов - после этого я получил рабочий файл .exe.

...