【问题标题】:How does Scrapy pause/resume work?Scrapy 暂停/恢复是如何工作的?
【发布时间】:2015-03-04 10:03:52
【问题描述】:

有人可以向我解释一下Scrapy 中的暂停/恢复功能是如何工作的吗?

我使用的scrapy的版本是0.24.5

documentation 没有提供太多细节。

我有以下简单的蜘蛛:

class SampleSpider(Spider):
name = 'sample'

def start_requests(self):
        yield Request(url='https://colostate.textbookrack.com/listingDetails?lst_id=1053')
        yield Request(url='https://colostate.textbookrack.com/listingDetails?lst_id=1054')
        yield Request(url='https://colostate.textbookrack.com/listingDetails?lst_id=1055')

def parse(self, response):
    with open('responses.txt', 'a') as f:
        f.write(response.url + '\n')

我正在使用:

from twisted.internet import reactor
from scrapy.crawler import Crawler
from scrapy import log, signals


from scrapyproject.spiders.sample_spider import SampleSpider
spider = SampleSpider()
settings = get_project_settings()
settings.set('JOBDIR', '/some/path/scrapy_cache')
settings.set('DOWNLOAD_DELAY', 10)
crawler = Crawler(settings)
crawler.signals.connect(reactor.stop, signal=signals.spider_closed)
crawler.configure()
crawler.crawl(spider)
crawler.start()
log.start()
reactor.run() 

如您所见,我启用了 JOBDIR 选项,以便保存我的抓取状态。

我将DOWNLOAD_DELAY 设置为10 seconds,以便在处理请求之前停止蜘蛛。我本来希望下次我运行蜘蛛时,不会重新生成请求。事实并非如此。

我在我的 scrapy_cache 文件夹中看到一个名为 requests.queue 的文件夹。然而,那总是空的。

看起来 requests.seen 文件正在保存发出的请求(使用 SHA1 哈希),这很棒。但是,下次我运行蜘蛛时,请求会重新生成,并且(重复的)SHA1 哈希会添加到文件中。我在Scrapy 代码中跟踪了这个问题,看起来RFPDupeFilter 打开了带有“a+”标志的requests.seen 文件。所以它总是会丢弃文件中以前的值(至少这是我的 Mac OS X 上的行为)。

最后,关于蜘蛛状态,我可以从Scrapy 代码中看到,蜘蛛状态在蜘蛛关闭时被保存,并在它打开时被读回。但是,如果发生异常(例如,机器关闭),这不是很有帮助。我必须定期保存吗?

我在这里遇到的主要问题是:使用Scrapy 的常见做法是什么?预期抓取会停止/恢复多次(例如,抓取一个非常大的网站时)?

【问题讨论】:

  • 看起来你在 python 脚本中运行了scrapy。你能定期停止反应器/刮擦吗?根据我过去的经验,reactor.run() 总是阻止脚本,所以我无法调用reactor.stop()。我想过在另一个线程中运行scrapy并向该线程发送终止信号,但我没有尝试过。

标签: scrapy


【解决方案1】:

为了能够暂停和恢复scrapy搜索,你可以运行这个命令来开始搜索:

scrapy crawl somespider --set JOBDIR=crawl1

要停止搜索,您应该运行 control-C,但您必须运行一次并等待 scrapy 停止,如果您运行 control-C 两次,它将无法正常工作。

然后您可以通过再次运行此命令来恢复搜索:

scrapy crawl somespider --set JOBDIR=crawl1

【讨论】:

  • 文档没有提到任何关于信号数量的内容。能否请您链接参考?
【解决方案2】:

我使用的scrapy版本是1.1.0

你需要在settings.py中设置正确的JOBDIR

JOBDIR = 'PROJECT_DIR'

通过control+c 停止蜘蛛后,您可以运行蜘蛛继续抓取其余部分。

它应该在那之后工作

【讨论】:

    【解决方案3】:

    Re:我这里的主要问题是:使用 Scrapy 的常见做法是什么,同时期望抓取会停止/恢复多次(例如,当抓取一个非常大的网站时)?

    如果您不想使用 Scrapy 的暂停/恢复,您可以随时序列化您的请求。下面我举个例子:

    如果你先抓取10000个url,然后在新的爬虫中依次请求抓取这10000个url,你可以简单地将这些url按照一些规则序列化,并在spider中导入csv:

    file = open('your10000_urls.csv', 'r')
    data = csv.reader(file)
    urls = list(data)
    url = ['']
    for i in urls:
        url.append(i[0])
    start_urls = url[1:]
    file.close()
    

    然后,您可以通过删除已请求的请求来跟踪这些请求。此外,您可能希望将数据存储在数据库中,这让生活变得更加轻松。

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2014-06-30
      • 2012-08-27
      • 2017-05-09
      • 1970-01-01
      • 1970-01-01
      • 2013-01-30
      • 2017-03-14
      • 2013-06-01
      • 1970-01-01
      相关资源
      最近更新 更多