scrapy pyinstaller error

Нужно собрать проект с парсером (scrapy) в один exe файл. При запуске main.py, через который идет взаимодействие с пользователем через консоль и запуск паука, в Pycharm все работает. При сборке через pyinstaller main.py создается main.exe. Он запускается, открывается консоль, пользователю предлагается запустить парсинг - тут все ок. Но при запуске паука вылезает ошибка и паук закрывается. Подскажите, пожалуйста, что с этим можно сделать.

системные сообщения:

2020-12-20 16:31:05 [scrapy.core.engine] INFO: Spider opened
2020-12-20 16:31:05 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2020-12-20 16:31:05 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2020-12-20 16:31:05 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://knife.media/wp-sitemap.xml> (referer: None)
2020-12-20 16:31:05 [scrapy.core.scraper] ERROR: Spider error processing <GET https://knife.media/wp-sitemap.xml> (referer: None)
Traceback (most recent call last):
  File "twisted\internet\defer.py", line 1418, in _inlineCallbacks
StopIteration: <200 https://knife.media/wp-sitemap.xml>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "scrapy\utils\defer.py", line 55, in mustbe_deferred
  File "scrapy\core\spidermw.py", line 58, in process_spider_input
  File "scrapy\core\scraper.py", line 149, in call_spider
  File "scrapy\utils\misc.py", line 245, in warn_on_generator_with_return_value
  File "scrapy\utils\misc.py", line 230, in is_generator_with_return_value
  File "inspect.py", line 985, in getsource
  File "inspect.py", line 967, in getsourcelines
  File "inspect.py", line 798, in findsource
OSError: could not get source code
2020-12-20 16:31:06 [scrapy.core.engine] INFO: Closing spider (finished)
2020-12-20 16:31:06 [bigSp] INFO: Spider closed: bigSp

код паука:

from scrapy.spiders import SitemapSpider
import sqlite3
import csv
import json
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.exceptions import CloseSpider
import keyboard
from scrapy import signals
import pydispatch as dispatcher


class MySpider(SitemapSpider):
    name = "bigSp"
    allowed_domains = ["knife.media"]
    sitemap_urls = ["https://knife.media/wp-sitemap.xml"]

    rules = (
        Rule(LinkExtractor(allow=('wp-sitemap-posts-post')), follow=True),
        Rule(LinkExtractor(unique=True))
    )

    COOKIES_ENABLED = False  # выключение куки файлов
    RETRY_ENABLED = False

    custom_settings = {'FEED_URI': "data.csv",
                       'FEED_FORMAT': 'csv',
                       }

    @classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        spider = super(MySpider, cls).from_crawler(crawler, *args, **kwargs)
        crawler.signals.connect(spider.spider_closed, signal=signals.spider_closed)
        return spider

    def spider_closed(self, spider):
        with open("data.csv", encoding="utf-8", newline="") as f, \
                sqlite3.connect("web.db") as conn:
            conn.execute("""CREATE TABLE IF NOT EXISTS web2 (
                                 url text UNIQUE ON CONFLICT IGNORE,
                                 id text UNIQUE ON CONFLICT IGNORE,
                                 tag text,
                                 title text,
                                 author text,
                                 date text,
                                 text text
                               )""")
            conn.executemany("""INSERT INTO web2 VALUES (?,?,?,?,?,?,?)""",
                             csv.reader(f))
        spider.logger.info('Spider closed: %s', spider.name)

    def parse(self, response):
        if keyboard.is_pressed('s'):
            raise CloseSpider('shutdown')
        else:
            f = open('url.txt', 'r')
            urls = f.readlines()
            urls = ([s.strip('\n') for s in urls])

            if urls.count(response.url) == 0 and response.css('article::attr(id)').get() and response.xpath(
                    '//div[@class="entry-footer__tags tags"]/a/text()').get() and response.css(
                'h1::text').get() and response.xpath('//a[@rel="author"]/text()').extract() and response.css(
                'time::attr(datetime)').get() and response.xpath(
                '//div[@class="entry-header__lead"]/p/text()').extract() and response.xpath(
                '//div[@class="entry-content"]/p/text()').extract():
                print('url is unique')
                data = {
                    'url': response.url,
                    'id': response.css('article::attr(id)').get(),
                    'tag': response.xpath('//div[@class="entry-footer__tags tags"]/a/text()').get(),
                    'title': response.css('h1::text').extract(),
                    'author': response.xpath('//a[@rel="author"]/text()').extract(),
                    'date': response.css('time::attr(datetime)').get(),
                    'text': response.xpath('//div[@class="entry-header__lead"]/p/text()').extract() + response.xpath(
                        '//div[@class="entry-content"]/p/text()').extract()
                }
                f = open('url.txt', 'a')
                f.write(response.url)
                f.write('\n')
                yield data
            f.close()
            yield None

код main:

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
import time
import keyboard
import tkinter as tk
import tkinter.ttk as ttk
from scrapy.spiders import SitemapSpider
import sqlite3
import csv
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.exceptions import CloseSpider
from scrapy import signals
import os

f = open('url.txt', 'w')
f.close()
menu=-1
while menu!='s':
 if keyboard.is_pressed('s'):
     break
 print('----------------для выхода из приложения нажмите \'s\'------------------')
 print('установите частоту обновления в минутах (от 10 до 240)')
 process = CrawlerProcess(get_project_settings())
 freq = int(input())
 freq = freq * 60
 print('начать загрузку данных? y/n')
 menu=input()
 if menu=='y':
     while True:
        print('идет загрузка...')
        print('для досрочной остановки нажмите \'s\'')
        time.sleep(2)
        process.crawl('bigSp')
        process.start()
        print('загрузка данных завершена')
        time.sleep(freq)

Ответы (0 шт):