Сканирование Scrapy не выполняется, если используется слишком много пауков (просканировано 0 страниц) - PullRequest
1 голос
/ 22 июня 2019

Я пытаюсь сканировать цены с популярной платформы перепродажи. Для каждого предмета я создаю один и тот же паук с разными поисковыми тегами. С менее чем 300 предметами процесс работает отлично, но не более того. Каждый паук записывает свои результаты в документ до его закрытия, поэтому не существует специальных конвейеров или иерархий.

Я пробовал разные подходы, такие как

    for c in collection:
        for item in c.get_items():
            crawler = Pricecrawler(c.collection_id, item.id, item.name)
            print(crawler)
            process.crawl(crawler, collection_id=c.collection_id, item_id=item.id, search=(item.name))
    process.start()

Или

    runner = CrawlerRunner(settings)
    d = []
    for c in collection:
        for item in c.get_items():
            crawler = Pricecrawler(c.collection_id, item.id, item.name)
            print(crawler)
            runner.crawl(crawler, collection_id=c.collection_id, item_id=item.id, search=(""+item.name))
            d = runner.join()
            d.addBoth(lambda _: reactor.stop())
    reactor.run()

(Эти два прекрасно работают для меньшего числа пауков, еще одна попытка с подпроцессами, выдающими команды командной строки scrapy, не работала).

Я пробовал разные настройки и надстройки в разных комбинациях и с разными значениями в течение последних двух недель без каких-либо заметных изменений в результате. (Хотя я, конечно, не перепробовал все возможные комбинации) настройки и дополнения, такие как

#settings.set('USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)')
#settings.set('TELNETCONSOLE_ENABLED', 'False')
#settings.set('TELNETCONSOLE_PORT', None)
#settings.set('CONCURRENT_REQUESTS', 8)
#settings.set('DEPTH_PRIORITY', 8)
#settings.set('DOWNLOAD_TIMEOUT', 360)
#settings.set('REACTOR_THREADPOOL_MAXSIZE', 20)
#settings.set('COOKIES_ENABLED', False)
#settings.set('DOWNLOAD_DELAY', 2)
#settings.set('DEPTH_LIMIT', 10)
#settings.set('DOWNLOADER_MIDDLEWARES', {'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
#                                        'scrapy_user_agents.middlewares.RandomUserAgentMiddleware': 400})

#settings.set('PROXY_POOL_ENABLED', True)
#settings.set('DOWNLOADER_MIDDLEWARES', {'scrapy_proxy_pool.middlewares.ProxyPoolMiddleware': 610,
#               'scrapy_proxy_pool.middlewares.BanDetectionMiddleware': 620})

#settings.set('CONCURRENT_REQUESTS', 100)
#settings.set('CONCURRENT_REQUESTS_PER_DOMAIN', 100)
#settings.set('DEPTH_PRIORITY', 1)
#settings.set('DOWNLOAD_TIMEOUT', 360)

И так далее ...

Пауки получают экземпляры вот так:

    for c in collection:
        for item in c.get_items():
            crawler = Pricecrawler(c.collection_id, item.id, item.name)
            print(crawler)
            process.crawl(crawler, collection_id=c.collection_id, item_id=item.id, search=(item.name))
    process.start()

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

Результат с более чем 300 пунктами приводит к минутам

YYYY-MM-DD HH:MM:SS [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)

Спасибо, что уделили время.

Не забывайте: я открыт для новых подходов к тому, как запустить несколько экземпляров одного паука с разными параметрами, даже если это требует гораздо больше времени.

1 Ответ

1 голос
/ 24 июня 2019

Обратите внимание, что первый аргумент CrawlerRunner.crawl метода - это не экземпляр Crawler, а класс.

Попробуйте передать это так:

process.crawl(
    Pricecrawler, 
    collection_id=c.collection_id, 
    item_id=item.id, 
    search=item.name
)
...