python - Scrapy - 蜘蛛需要很长时间才能被关闭
问题描述
基本上,我有一个名为的文件,我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
不阻塞主进程的情况下触发所有蜘蛛吗?
解决方案
我相信当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()
必须用扭曲的等价物重写。
推荐阅读
- javascript - 如何使用 Firebase 获取用户帖子并使用 Facebook 进行身份验证?
- python - /payment/卡处的 AttributeError
- c# - 空闲时更新 Azure.Messaging.EventHubs.EventProcessorClient 上的 EventHub 分区偏移检查点
- python - cmp_to_key 在 python3 中不适用于 .csv 文件
- css - 使用 React Beautiful DND 在放置的项目上添加淡出动画
- docker - 删除不再需要的文件后如何回收 Docker Image 中的空间(用于制作 jre 的 java jdk 11)
- r - 带有等高线图的 Rworldmap
- html - 当类型为文本/密码时,前置输入的高度不同
- c - 如何编写代码以从输入文件的单独行中读取输入并执行此代码在 C 中所做的相同操作
- php - CakePHP 3 - 可包含的行为在模型上不起作用,即使它们是链接的