Scrapy-蜘蛛需要很长时间才能关闭

时间:2018-07-20 00:55:27

标签: python scrapy subprocess

基本上,我有一个名为spiders.py的文件,在其中我配置了所有蜘蛛,然后使用一个搜寻器对所有蜘蛛进行了射击。这是此文件的源代码:

from scrapy import spiderloader
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from navigator import *


def main():
  settings = get_project_settings()
  spider_loader = spiderloader.SpiderLoader.from_settings(settings)
  process = CrawlerProcess(settings=settings)
  for spider_name in spider_loader.list():
      process.crawl(spider_name)

  process.start()


if __name__ == '__main__':
  main()

我要实现的目标是使用subprocess模块从另一个脚本中启动此蜘蛛,并在执行5分钟后关闭所有蜘蛛(仅使用一个SIGTERM)。负责此目标的文件为monitor.py

from time import sleep
import os
import signal
import subprocess

def main():
  spiders_process = subprocess.Popen(["python", "spiders.py"], stdout=subprocess.PIPE,
                                      shell=False, preexec_fn=os.setsid)
  sleep(300)
  os.killpg(spiders_process.pid, signal.SIGTERM)

if __name__ == '__main__':
  main()

当主线程唤醒时,终端显示2018-07-19 21:45:09 [scrapy.crawler] INFO: Received SIGTERM, shutting down gracefully. Send again to force 。但是,即使在收到此消息后,爬虫仍会继续抓取网页。我做错了什么?

OBS :是否可以在spiders.py内发射所有蜘蛛,而不会阻塞主进程?

1 个答案:

答案 0 :(得分:0)

我相信,当scrapy收到SIGTERM时,它会尝试通过首先等待完成所有已发送/预定的请求来正常关闭。最好的选择是限制数量或并发请求,以便更快完成(默认情况下,CONCURRENT_REQUESTS / CONCURRENT_REQUESTS_PER_DOMAIN分别为16和8)或发送两个SIGTERM来指示scrapy做不干净的立即退出。

  

OBS:是否有可能在spiders.py内部发射所有蜘蛛,而不会阻塞主进程?

process.start()启动扭曲的反应堆(扭曲的主事件循环),这是一个阻塞调用,要绕​​开它并在反应堆启动后运行更多代码,可以安排在循环内运行函数。本手册的第一段内容应为您提供一个概念:https://twistedmatrix.com/documents/current/core/howto/time.html

但是,如果您采用这种方式,则必须确保计划的代码也必须是非阻塞的,否则,如果暂停循环执行的时间过长,可能会开始发生不良情况。因此,time.sleep()之类的东西必须用等效的方式重写。