我正在尝试使用Celery周期性任务从脚本运行Scrapy蜘蛛。
Twisted==17.9.0
Scrapy==1.4.0
celery==4.1.0
我有一个班级SpiderSupervisor
,它可以获得运行蜘蛛所需的一些数据,并决定此时运行蜘蛛。
问题在于,如果我使用标准方式:
process = CrawlerProcess({
'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})
process.crawl(MySpider)
process.start()
它首次运行,但随后它会引发ReactorNotRestartable
。
所以我尝试了另一种使用scrapyscript的方式,但它被初始化了两次。
这种方式也不起作用:Run a Scrapy spider in a Celery Task
scrapy中没有crawler.configure(), reactor.run(), crawler.start()
并且扭曲了:
from scrapy.crawler import Crawler
from twisted.internet import reactor
from billiard import Process # this can be from billiard.process import Process
tasks.py:
@periodic_task(run_every=timedelta(minutes=1))
def ping_spider():
SpiderSupervisor().send_signal()
SpiderSupervisor:
class SpiderSupervisor():
""" - Decides whether run spider now
- Sets last_hour_ping and hour in SystemScanningData
"""
def __init__(self): # TODO: exceptions?
self.system_scanning_data = SystemScanningData.objects.first()
...
def _get_new_system_scanning(self):
system_scanning = SystemScanning.objects.create()
return system_scanning
def send_signal(self):
self.system_scanning_data.update()
users = self.get_users_to_scan()
if users.exists():
urls_queryset = Url.objects.filter(product__user__in=users)
self.prepare_and_run_spider(urls_queryset)
def prepare_and_run_spider(self, urls_queryset):
system_scanning = self._get_new_system_scanning()
# spider = StilioMainSpider([1,2,3])
# job = Job(spider)
# Processor().run(job)
process = CrawlerProcess()
process.crawl(StilioMainSpider,[1,2,3])
process.start()
你知道怎么做这个吗?还有另外一种方法吗?我需要将参数传递给蜘蛛。