当初的想法是scrapy用来爬去url,用celery去下载内容。(环境配置celery+redis)
往往总是事与愿违。
(前提,celery 已在spider中引入,并执行了delay函数)
celery worker的py文件,与spider放在同一个目录。每次启动spider的时候,通过最原始的启动方式:scrapy crawl spidername 来启动。
启动celery worder的时候,也是放在spider的目录启动,如下: celery -A workerfilename worker --loglevel=info
这个时候问题就出来,每次delay一个任务到celery 都会出现 task not registered。这可把我郁闷的哇。
其实遇到这样的问题并不揪心,更揪心的是,如果单独执行delay是完全可行的,唯独到了scrapy里面,怎么搞都不行。
貌似,没啥解决方案,查了查stackoverflow,基本上都是spider如何在celery中执行的,没有跟我这个问题相关的。
放弃吗?不行。慢慢来,要研究……
通过研究发现,每次delay的一个任务,其实是一个json格式的数据,写入到redis,然后worker从redis中读取这个json格式的参数,执行worker对应的任务。
我仔细分析了每次报错的提示,task not registered 后面紧跟着的是task的名字(scrapypro.spiders.workerfilename.workername)。如果成功执行这个worker的时候,task的名字,都是workerfilename.workername。
这就是问题的所在了。spider相对于整个scrapy project 而言,它的路径是:scrapypro.spiders.spider,所以每次启动的spider的时候,吐到celery中的task参数是有个前缀的(scrapypro.spiders)。
而以上面的方式启动celery worker的时候,注册的task名字是workerfilaname.workername。所以,spider每次吐到redis的数据,celery worker无法解析。也就不能正常执行了。
虽然,知道的问题的所在,但还是没能找到解决办法……至此,问题就搁浅了……
下午陪未来老婆去逛街,回来,做饭,吃饭……开电脑。又想到这个问题了。
不知道是醍醐灌顶,还是脑洞大开。既然,spider吐出来的task格式是scrapypro.spiders.worderfilename.workername,那我何不就按找这样的方式去启动worker呢?
往下就简单了,回退到scrapy.cfg所在的目录启动worker,启动worker:celery -A scrapypro.spiders.workerfilename worker --loglevel=info…………
居然,居然………………成功了……
憋了一天了…………居然就这么解决了。就这么简单。可能是我太傻了。