好的,这就是我如何让Scrapy在我的Django项目中工作,该项目使用Celery 来排队要爬行的东西.实际的解决方法主要来自位于此处的Joehillen的代码http://snippets.scrapy.org/snippets/13/
首先是tasks.py
号文件
from celery import task
@task()
def crawl_domain(domain_pk):
from crawl import domain_crawl
return domain_crawl(domain_pk)
那么crawl.py
文件
from multiprocessing import Process
from scrapy.crawler import CrawlerProcess
from scrapy.conf import settings
from spider import DomainSpider
from models import Domain
class DomainCrawlerScript():
def __init__(self):
self.crawler = CrawlerProcess(settings)
self.crawler.install()
self.crawler.configure()
def _crawl(self, domain_pk):
domain = Domain.objects.get(
pk = domain_pk,
)
urls = []
for page in domain.pages.all():
urls.append(page.url())
self.crawler.crawl(DomainSpider(urls))
self.crawler.start()
self.crawler.stop()
def crawl(self, domain_pk):
p = Process(target=self._crawl, args=[domain_pk])
p.start()
p.join()
crawler = DomainCrawlerScript()
def domain_crawl(domain_pk):
crawler.crawl(domain_pk)
这里的诀窍是"来自多处理导入过程",它绕过了Twisted框架中的"ReactorNotRestartable"问题.因此基本上Celery 任务调用"domain_crawl"函数,该函数反复重用"DomainCrawlerScript"对象,以与你的Scrapy spider接口.(我知道我的示例有点多余,但我之所以这么做,是因为我的设置中使用了多个版本的python[我的django Web服务器实际上使用的是python2.4,我的工作服务器使用的是python2.7])
在我的示例中,"DomainSpider"只是一个修改后的Scrapy Spider,它接受一个URL列表,然后将它们设置为"start_urls".
希望这能有所帮助!